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