Skip to content

Commit a1db093

Browse files
committed
mouredev#50 - python
1 parent 7df86ce commit a1db093

File tree

1 file changed

+218
-0
lines changed
  • Roadmap/50 - PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO/python

1 file changed

+218
-0
lines changed
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
# /*
2+
# * EJERCICIO:
3+
# * El nuevo año está a punto de comenzar...
4+
# * ¡Voy a ayudarte a planificar tus propósitos de nuevo año!
5+
# *
6+
# * Programa un gestor de objetivos con las siguientes características:
7+
# * - Permite añadir objetivos (máximo 10)
8+
# * - Calcular el plan detallado
9+
# * - Guardar la planificación
10+
# *
11+
# * Cada entrada de un objetivo está formado por (con un ejemplo):
12+
# * - Meta: Leer libros
13+
# * - Cantidad: 12
14+
# * - Unidades: libros
15+
# * - Plazo (en meses): 12 (máximo 12)
16+
# *
17+
# * El cálculo del plan detallado generará la siguiente salida:
18+
# * - Un apartado para cada mes
19+
# * - Un listado de objetivos calculados a cumplir en cada mes
20+
# * (ejemplo: si quiero leer 12 libros, dará como resultado
21+
# * uno al mes)
22+
# * - Cada objetivo debe poseer su nombre, la cantidad de
23+
# * unidades a completar en cada mes y su total. Por ejemplo:
24+
# *
25+
# * Enero:
26+
# * [ ] 1. Leer libros (1 libro/mes). Total: 12.
27+
# * [ ] 2. Estudiar Git (1 curso/mes). Total: 1.
28+
# * Febrero:
29+
# * [ ] 1. Leer libros (1 libro/mes). Total: 12.
30+
# * ...
31+
# * Diciembre:
32+
# * [ ] 1. Leer libros (1 libro/mes). Total: 12.
33+
# *
34+
# * - Si la duración es menor a un año, finalizará en el mes
35+
# * correspondiente.
36+
# *
37+
# * Por último, el cálculo detallado debe poder exportarse a .txt
38+
# * (No subir el fichero)
39+
# */
40+
import math
41+
import os
42+
43+
class Gestor:
44+
__LIMIT = 10 # Máximo de objetivos permitidos por usuario, restaremos cada vez que se añada un objetivo.
45+
__LIMIT_MONTHS = 12 # Máximo de meses permitidos para el plazo de un objetivo.
46+
__MONTHS = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']
47+
__PROCECED_DATA = [] # Datos procesados para poder guardarlos en un archivo además de mostrarlos en consola.
48+
49+
def __init__(self):
50+
self.objetivos = [] # Lista de objetivos
51+
self.__LIMIT_MONTHS = 12
52+
53+
def calcular(self):
54+
"""
55+
Calcula los objetivos mensuales y los estructura para cada mes.
56+
en los objetivos que tengan plazo impar, se redondeará hacia arriba para no tener decimales.
57+
"""
58+
self.__PROCECED_DATA = [] # Limpieza de datos procesados
59+
60+
# Recorremos los objetivos para calcular su distribución mensual
61+
for objetivo in self.objetivos:
62+
# Obtenemos los datos del objetivo
63+
cantidad = objetivo['cantidad'] # Total de unidades
64+
plazo = objetivo['plazo'] # Meses disponibles
65+
meta = objetivo['meta'] # Descripción del objetivo
66+
unidad = objetivo['unidad'] # Unidad del objetivo
67+
68+
restante = cantidad # Inicializamos el restante
69+
cuota_mensual = cantidad / plazo # Cálculo de cuota base por mes
70+
71+
for mes in range(plazo):
72+
cantidad_mes = max(math.ceil(cuota_mensual),1) # Cuota redondeada minimizando a 1
73+
if restante < cantidad_mes:
74+
cantidad_mes = restante # Ajustamos la cuota al restante
75+
76+
restante -= cantidad_mes # Reducimos el restante
77+
nuevo_objetivo = {
78+
'mes': self.__MONTHS[mes], # Mes correspondiente
79+
'meta': meta, # Meta del objetivo
80+
'cantidad': cantidad_mes, # Cantidad para el mes
81+
'unidad': unidad, # Unidad asociada
82+
'total': cantidad, # Total del objetivo
83+
}
84+
if cantidad_mes > 0:
85+
self.__PROCECED_DATA.append(nuevo_objetivo) # Añadimos al resultado
86+
87+
self.mostrar_objetivos() # Muestra los objetivos procesados
88+
89+
90+
def limpiar_fichero(self):
91+
"""
92+
Limpia el archivo de texto donde se guardan los objetivos
93+
"""
94+
file_ruta = self.obtener_fichero()
95+
with open(file_ruta, 'w', encoding="utf-8") as file:
96+
file.write('')
97+
98+
def obtener_fichero(self):
99+
"""
100+
Obtiene el archivo de texto donde se guardan los objetivos
101+
"""
102+
return os.path.join(os.getcwd(), 'objetivos.txt')
103+
104+
def guardar(self):
105+
"""
106+
Guarda los objetivos procesados en un archivo de texto
107+
"""
108+
#limpiamos el archivo de texto
109+
self.limpiar_fichero()
110+
#obtenemos la ruta del archivo de texto
111+
file_ruta = self.obtener_fichero()
112+
113+
objetivos_por_mes = {}
114+
115+
# Agrupamos los objetivos por mes
116+
117+
for objetivo in self.__PROCECED_DATA:
118+
# Obtenemos el mes del objetivo
119+
mes = objetivo['mes']
120+
# Si el mes no está en el diccionario, lo añadimos
121+
if mes not in objetivos_por_mes:
122+
# Inicializamos la lista de objetivos
123+
objetivos_por_mes[mes] = []
124+
# Añadimos el objetivo a la lista correspondiente
125+
objetivos_por_mes[mes].append(objetivo)
126+
127+
# Abrimos el archivo de texto y sobre escribimos mes a mes
128+
with open(file_ruta, 'r+', encoding="utf-8") as file:
129+
for mes, objetivos in objetivos_por_mes.items():
130+
# Mostramos el mes
131+
file.write(f'{mes}:\n')
132+
# Mostramos los objetivos del mes
133+
for i, objetivo in enumerate(objetivos):
134+
#escribimos en el archivo de texto con el objetivo
135+
file.write(f'[{i+1}] {objetivo["meta"]} ({objetivo["cantidad"]} {objetivo["unidad"]}/mes). Total: {objetivo["total"]}.\n')
136+
#saltamos una linea
137+
file.write('\n')
138+
#cerramos el archivo de texto
139+
file.close()
140+
141+
def add_objetivo(self,meta: str, cantidad:int, unidad:str, plazo:int)->None:
142+
"""
143+
Añade un objetivo a la lista de objetivos.
144+
- Meta: Leer libros
145+
- Cantidad: 12
146+
- Unidades: libros
147+
- Plazo (en meses): 12 (máximo 12)
148+
"""
149+
# Validaciones
150+
if(self.__LIMIT == 0):
151+
print('Has alcanzado el máximo de objetivos permitidos.')
152+
return
153+
154+
if(plazo > self.__LIMIT_MONTHS):
155+
print(f'El plazo no puede ser mayor a {self.__LIMIT_MONTHS} meses.')
156+
return
157+
158+
if cantidad <= 0:
159+
print('La cantidad no puede ser menor o igual a 0.')
160+
return
161+
162+
# añadir objetivo cuando se cumplan las validaciones.
163+
self.objetivos.append({
164+
'meta': meta,
165+
'cantidad': cantidad,
166+
'unidad': unidad,
167+
'plazo': plazo
168+
})
169+
self.__LIMIT -= 1
170+
print(f'Objetivo añadido: {meta}')
171+
172+
173+
174+
def mostrar_objetivos(self):
175+
"""
176+
Muestra los objetivos procesados por mes en el formato requerido.
177+
"""
178+
if not self.__PROCECED_DATA:
179+
print("No hay objetivos procesados.")
180+
return
181+
182+
objetivos_por_mes = {}
183+
# Agrupamos los objetivos por mes
184+
for objetivo in self.__PROCECED_DATA:
185+
# Obtenemos el mes del objetivo
186+
mes = objetivo['mes']
187+
# Si el mes no está en el diccionario, lo añadimos
188+
if mes not in objetivos_por_mes:
189+
# Inicializamos la lista de objetivos
190+
objetivos_por_mes[mes] = []
191+
# Añadimos el objetivo a la lista correspondiente
192+
objetivos_por_mes[mes].append(objetivo)
193+
for mes, objetivos in objetivos_por_mes.items():
194+
# Mostramos el mes
195+
print(f'{mes}:')
196+
# Mostramos los objetivos del mes
197+
for i, objetivo in enumerate(objetivos):
198+
print(f'[{i+1}] {objetivo["meta"]} ({objetivo["cantidad"]} {objetivo["unidad"]}/mes). Total: {objetivo["total"]}.')
199+
print()
200+
201+
202+
if __name__ == '__main__':
203+
gestor = Gestor()
204+
# Añadimos los objetivos al gestor.
205+
206+
gestor.add_objetivo('Leer libros', 12, 'libros', 12)
207+
gestor.add_objetivo('Estudiar Git', 1, 'curso', 1)
208+
gestor.add_objetivo('Hacer ejercicio', 12, 'rutina', 12)
209+
gestor.add_objetivo('Aprender Python', 12, 'curso', 7)
210+
gestor.add_objetivo('Aprender Javascript', 7, 'curso', 12)
211+
gestor.add_objetivo('Aprender Vue', 8, 'curso', 9)
212+
gestor.add_objetivo('Aprender Svelte', 12, 'curso', 4)
213+
gestor.add_objetivo('Aprender React', 10, 'curso', 4)
214+
gestor.add_objetivo('Aprender Angular', 2, 'curso', 4)
215+
gestor.add_objetivo('Aprender Node', 8, 'curso', 4)
216+
217+
gestor.calcular()
218+
gestor.guardar()

0 commit comments

Comments
 (0)