|
| 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 | + |
| 41 | +import os |
| 42 | + |
| 43 | +MONTHS = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"] |
| 44 | + |
| 45 | +def show_menu(): |
| 46 | + |
| 47 | + print("\nPlanificador de objetivos") |
| 48 | + print("1. Añadir objetivo.") |
| 49 | + print("2. Calcular el plan detallado") |
| 50 | + print("3. Guardar la planificación") |
| 51 | + print("4. Salir") |
| 52 | + |
| 53 | +class Goal: |
| 54 | + |
| 55 | + def __init__(self, goal_name: str, amount: int, units: str, limit: int): |
| 56 | + self.goal_name = goal_name |
| 57 | + self.amount = amount |
| 58 | + self.units = units |
| 59 | + self.limit = limit |
| 60 | + |
| 61 | +def request_goal() -> Goal: |
| 62 | + |
| 63 | + goal_name = input("Meta: ") |
| 64 | + |
| 65 | + while True: |
| 66 | + try: |
| 67 | + amount = int(input("Cantidad: ")) |
| 68 | + if amount <= 0: |
| 69 | + print("La cantidad debe ser un número positivo.") |
| 70 | + continue |
| 71 | + break |
| 72 | + except: |
| 73 | + print("Introduce un número entero válido.") |
| 74 | + |
| 75 | + units = input("Unidades: ") |
| 76 | + |
| 77 | + while True: |
| 78 | + try: |
| 79 | + limit = int(input("Plazo en meses (máx. 12): ")) |
| 80 | + if limit <= 0 or limit > len(MONTHS): |
| 81 | + print("El plazo debe ser de 1 a 12 meses.") |
| 82 | + continue |
| 83 | + break |
| 84 | + except: |
| 85 | + print("Introduce un número entre 1 y 12.") |
| 86 | + |
| 87 | + return Goal(goal_name, amount, units, limit) |
| 88 | + |
| 89 | +def calculate_detailed_plan(goals: list[Goal]) -> dict: |
| 90 | + |
| 91 | + plan = {month: [] for month in range(1, len(MONTHS) + 1)} |
| 92 | + |
| 93 | + for goal in goals: |
| 94 | + |
| 95 | + month_amount = goal.amount / goal.limit |
| 96 | + |
| 97 | + for month in range(1, goal.limit + 1): |
| 98 | + |
| 99 | + plan[month].append(Goal(goal.goal_name, round(month_amount, 1), goal.units, goal.amount)) |
| 100 | + |
| 101 | + return plan |
| 102 | + |
| 103 | +def show_detailed_plan(plan: dict): |
| 104 | + |
| 105 | + for month in range(1, len(MONTHS) + 1): |
| 106 | + |
| 107 | + if not plan[month]: |
| 108 | + break |
| 109 | + |
| 110 | + print(f"\n{MONTHS[month - 1]}: ") |
| 111 | + |
| 112 | + for index, goal in enumerate(plan[month], start=1): |
| 113 | + print(f"[ ] {index}. {goal.goal_name} ({goal.amount} {goal.units}/mes). Total: {goal.limit}.") |
| 114 | + |
| 115 | +def save_detailed_plan(plan: dict): |
| 116 | + |
| 117 | + file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "plan.txt") |
| 118 | + |
| 119 | + with open(file_path, "w", encoding="utf-8") as file: |
| 120 | + file.write("Plan detallado") |
| 121 | + |
| 122 | + for month in range(1, len(MONTHS) + 1): |
| 123 | + |
| 124 | + if not plan[month]: |
| 125 | + break |
| 126 | + |
| 127 | + file.write(f"\n{MONTHS[month - 1]}:\n") |
| 128 | + |
| 129 | + for index, goal in enumerate(plan[month], start=1): |
| 130 | + file.write(f"[ ] {index}. {goal.goal_name} ({goal.amount} {goal.units}/mes). Total: {goal.limit}.\n") |
| 131 | + |
| 132 | + print(f"Plan guardado con éxito en {file_path}") |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +goals = [] |
| 138 | + |
| 139 | +while True: |
| 140 | + |
| 141 | + show_menu() |
| 142 | + |
| 143 | + option = input("\nElige una opción: ") |
| 144 | + |
| 145 | + if option == "1": |
| 146 | + if len(goals) >= 10: |
| 147 | + print("Has alcanzado el número máximo de objetivos (10).") |
| 148 | + continue |
| 149 | + else: |
| 150 | + goal = request_goal() |
| 151 | + goals.append(goal) |
| 152 | + print("Objetivo añadido correctamente.") |
| 153 | + continue |
| 154 | + |
| 155 | + if option == "2": |
| 156 | + if len(goals) == 0: |
| 157 | + print("No hay objetivos añadidos.") |
| 158 | + continue |
| 159 | + else: |
| 160 | + plan = calculate_detailed_plan(goals) |
| 161 | + show_detailed_plan(plan) |
| 162 | + continue |
| 163 | + |
| 164 | + if option == "3": |
| 165 | + if len(goals) == 0: |
| 166 | + print("No hay objetivos para guardar.") |
| 167 | + continue |
| 168 | + else: |
| 169 | + plan = calculate_detailed_plan(goals) |
| 170 | + save_detailed_plan(plan) |
| 171 | + |
| 172 | + if option == "4": |
| 173 | + print("Saliendo del planificador.") |
| 174 | + break |
| 175 | + else: |
| 176 | + print("Opción no válida. Elige una opción entre el 1 y 4.") |
| 177 | + |
0 commit comments