Clase de Lenguaje de Programación

PROYECTO FINAL
PYTHON

"Desarrollo de una Aplicación de Lista de Tareas (ToDoList) en Python: Gestión de Categorías y Tareas con Persistencia de Datos"
INFORME EN WORD
PRESENTACIÓN
CÓDIGO EN PYTHON
import os
import pickle
class Categoria:
def __init__(self, nombre):
self.nombre = nombre
self.tareas = []
def __str__(self):
return f"{self.nombre}"
class Tarea:
def __init__(self, nombre, descripcion, completada=False):
self.nombre = nombre
self.descripcion = descripcion
self.completada = completada
def __str__(self):
estado = "Completada" if self.completada else "Pendiente"
return f"{self.nombre} - {self.descripcion} ({estado})"
class ToDoList:
def __init__(self):
self.categorias = []
def agregar_categoria(self, categoria):
self.categorias.append(categoria)
print(f"Categoría '{categoria.nombre}' creada.")
def mostrar_categorias(self):
if not self.categorias:
print("No hay categorías en la lista.")
else:
print("Lista de Categorías:")
for idx, categoria in enumerate(self.categorias, start=1):
print(f"{idx}. {categoria}")
def agregar_tarea(self, nombre_categoria, tarea):
categoria = next((c for c in self.categorias if c.nombre == nombre_categoria), None)
if categoria:
categoria.tareas.append(tarea)
print(f"Tarea '{tarea.nombre}' agregada a la categoría '{nombre_categoria}'.")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def mostrar_tareas(self, nombre_categoria):
categoria = next((c for c in self.categorias if c.nombre == nombre_categoria), None)
if categoria:
if not categoria.tareas:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
else:
print(f"Lista de Tareas en la Categoría '{nombre_categoria}':")
for idx, tarea in enumerate(categoria.tareas, start=1):
print(f"{idx}. {tarea}")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def marcar_completada(self, nombre_categoria, indice):
categoria = next((c for c in self.categorias if c.nombre == nombre_categoria), None)
if categoria:
if 1 <= indice <= len(categoria.tareas):
tarea = categoria.tareas[indice - 1]
tarea.completada = not tarea.completada
estado = "Completada" if tarea.completada else "Pendiente"
print(f"Tarea '{tarea.nombre}' marcada como {estado}.")
else:
print("Índice de tarea no válido.")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def eliminar_tarea(self, nombre_categoria, indice):
categoria = next((c for c in self.categorias if c.nombre == nombre_categoria), None)
if categoria:
if 1 <= indice <= len(categoria.tareas):
tarea_eliminada = categoria.tareas.pop(indice - 1)
print(f"Tarea '{tarea_eliminada.nombre}' eliminada de la categoría '{nombre_categoria}'.")
else:
print("Índice de tarea no válido.")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def guardar_en_archivo(self, archivo):
with open(archivo, 'wb') as f:
pickle.dump(self.categorias, f)
def cargar_desde_archivo(self, archivo):
if os.path.exists(archivo):
with open(archivo, 'rb') as f:
self.categorias = pickle.load(f)
def menu_principal():
print("\n--- Menú Principal ---")
print("1. Gestionar Categorías")
print("2. Gestionar Tareas")
print("3. Guardar y Salir")
def menu_categorias():
print("\n--- Menú Categorías ---")
print("1. Agregar Categoría")
print("2. Mostrar Categorías")
print("3. Volver al Menú Principal")
def menu_tareas():
print("\n--- Menú Tareas ---")
print("1. Agregar Tarea a Categoría")
print("2. Mostrar Tareas de Categoría")
print("3. Marcar Tarea como Completada")
print("4. Eliminar Tarea de Categoría")
print("5. Volver al Menú Principal")
def main():
lista_tareas = ToDoList()
archivo_guardado = "todolist_data.pkl"
# Cargar tareas desde un archivo (si existe)
lista_tareas.cargar_desde_archivo(archivo_guardado)
while True:
menu_principal()
opcion_principal = input("Selecciona una opción: ")
if opcion_principal == '1':
while True:
menu_categorias()
opcion_categorias = input("Selecciona una opción: ")
if opcion_categorias == '1':
nombre_categoria = input("Ingrese el nombre de la categoría: ")
nueva_categoria = Categoria(nombre_categoria)
lista_tareas.agregar_categoria(nueva_categoria)
elif opcion_categorias == '2':
lista_tareas.mostrar_categorias()
elif opcion_categorias == '3':
break
else:
print("Opción no válida. Inténtalo de nuevo.")
elif opcion_principal == '2':
while True:
menu_tareas()
opcion_tareas = input("Selecciona una opción: ")
if opcion_tareas == '1':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
nombre_tarea = input("Ingrese el nombre de la tarea: ")
descripcion_tarea = input("Ingrese la descripción de la tarea: ")
nueva_tarea = Tarea(nombre_tarea, descripcion_tarea)
lista_tareas.agregar_tarea(nombre_categoria, nueva_tarea)
elif opcion_tareas == '2':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
lista_tareas.mostrar_tareas(nombre_categoria)
elif opcion_tareas == '3':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
lista_tareas.mostrar_tareas(nombre_categoria)
indice_completar = int(input("Ingrese el número de la tarea a marcar como completada/pendiente: "))
lista_tareas.marcar_completada(nombre_categoria, indice_completar)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas == '4':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
lista_tareas.mostrar_tareas(nombre_categoria)
indice_eliminar = int(input("Ingrese el número de la tarea a eliminar: "))
lista_tareas.eliminar_tarea(nombre_categoria, indice_eliminar)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas == '5':
break
else:
print("Opción no válida. Inténtalo de nuevo.")
elif opcion_principal == '3':
# Guardar tareas en un archivo antes de salir
lista_tareas.guardar_en_archivo(archivo_guardado)
print("Saliendo...")
break
else:
print("Opción no válida. Inténtalo de nuevo.")
if __name__ == "__main__":
main()
from datetime import datetime, timedelta
# ... (Clases existentes y funciones hasta ahora)
class TareaConFecha(Tarea):
def __init__(self, nombre, descripcion, fecha_vencimiento=None, completada=False):
super().__init__(nombre, descripcion, completada)
self.fecha_vencimiento = fecha_vencimiento
def __str__(self):
estado = "Completada" if self.completada else "Pendiente"
fecha_vencimiento_str = f" (Vence el {self.fecha_vencimiento.strftime('%Y-%m-%d')})" if self.fecha_vencimiento else ""
return f"{self.nombre} - {self.descripcion} ({estado}){fecha_vencimiento_str}"
def menu_tareas_avanzado():
print("\n--- Menú Tareas Avanzado ---")
print("1. Agregar Tarea a Categoría con Fecha de Vencimiento")
print("2. Mostrar Tareas de Categoría Ordenadas por Fecha de Vencimiento")
print("3. Marcar Tarea como Completada con Fecha de Vencimiento")
print("4. Eliminar Tarea de Categoría con Fecha de Vencimiento")
print("5. Mostrar Tareas Vencidas")
print("6. Volver al Menú Principal")
def agregar_tarea_con_fecha(nombre_categoria, lista_tareas):
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
categoria = next((c for c in lista_tareas.categorias if c.nombre == nombre_categoria), None)
if categoria:
nombre_tarea = input("Ingrese el nombre de la tarea: ")
descripcion_tarea = input("Ingrese la descripción de la tarea: ")
fecha_vencimiento_str = input("Ingrese la fecha de vencimiento (YYYY-MM-DD) o presione Enter para omitir: ")
fecha_vencimiento = None
if fecha_vencimiento_str:
fecha_vencimiento = datetime.strptime(fecha_vencimiento_str, '%Y-%m-%d')
nueva_tarea = TareaConFecha(nombre_tarea, descripcion_tarea, fecha_vencimiento)
lista_tareas.agregar_tarea(nombre_categoria, nueva_tarea)
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def mostrar_tareas_ordenadas(nombre_categoria, lista_tareas):
categoria = next((c for c in lista_tareas.categorias if c.nombre == nombre_categoria), None)
if categoria:
if not categoria.tareas:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
else:
tareas_ordenadas = sorted(categoria.tareas, key=lambda x: x.fecha_vencimiento)
print(f"Lista de Tareas en la Categoría '{nombre_categoria}' Ordenadas por Fecha de Vencimiento:")
for idx, tarea in enumerate(tareas_ordenadas, start=1):
print(f"{idx}. {tarea}")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def marcar_completada_con_fecha(nombre_categoria, indice, lista_tareas):
categoria = next((c for c in lista_tareas.categorias if c.nombre == nombre_categoria), None)
if categoria:
if 1 <= indice <= len(categoria.tareas):
tarea = categoria.tareas[indice - 1]
tarea.completada = not tarea.completada
estado = "Completada" if tarea.completada else "Pendiente"
print(f"Tarea '{tarea.nombre}' marcada como {estado}.")
else:
print("Índice de tarea no válido.")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def eliminar_tarea_con_fecha(nombre_categoria, indice, lista_tareas):
categoria = next((c for c in lista_tareas.categorias if c.nombre == nombre_categoria), None)
if categoria:
if 1 <= indice <= len(categoria.tareas):
tarea_eliminada = categoria.tareas.pop(indice - 1)
print(f"Tarea '{tarea_eliminada.nombre}' eliminada de la categoría '{nombre_categoria}'.")
else:
print("Índice de tarea no válido.")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def mostrar_tareas_vencidas(lista_tareas):
tareas_vencidas = []
for categoria in lista_tareas.categorias:
for tarea in categoria.tareas:
if isinstance(tarea, TareaConFecha) and tarea.fecha_vencimiento and tarea.fecha_vencimiento < datetime.now():
tareas_vencidas.append(tarea)
if tareas_vencidas:
print("Tareas Vencidas:")
for tarea in tareas_vencidas:
print(f"- {tarea}")
else:
print("No hay tareas vencidas.")
def main_avanzado():
lista_tareas = ToDoList()
archivo_guardado = "todolist_data.pkl"
# Cargar tareas desde un archivo (si existe)
lista_tareas.cargar_desde_archivo(archivo_guardado)
while True:
menu_principal()
opcion_principal = input("Selecciona una opción: ")
if opcion_principal == '1':
while True:
menu_categorias()
opcion_categorias = input("Selecciona una opción: ")
if opcion_categorias == '1':
nombre_categoria = input("Ingrese el nombre de la categoría: ")
nueva_categoria = Categoria(nombre_categoria)
lista_tareas.agregar_categoria(nueva_categoria)
elif opcion_categorias == '2':
lista_tareas.mostrar_categorias()
elif opcion_categorias == '3':
break
else:
print("Opción no válida. Inténtalo de nuevo.")
elif opcion_principal == '2':
while True:
menu_tareas_avanzado()
opcion_tareas_avanzado = input("Selecciona una opción: ")
if opcion_tareas_avanzado == '1':
agregar_tarea_con_fecha(nombre_categoria, lista_tareas)
elif opcion_tareas_avanzado == '2':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
elif opcion_tareas_avanzado == '3':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
indice_completar = int(input("Ingrese el número de la tarea a marcar como completada/pendiente: "))
marcar_completada_con_fecha(nombre_categoria, indice_completar, lista_tareas)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas_avanzado == '4':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
indice_eliminar = int(input("Ingrese el número de la tarea a eliminar: "))
eliminar_tarea_con_fecha(nombre_categoria, indice_eliminar, lista_tareas)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas_avanzado == '5':
mostrar_tareas_vencidas(lista_tareas)
elif opcion_tareas_avanzado == '6':
break
else:
print("Opción no válida. Inténtalo de nuevo.")
elif opcion_principal == '3':
# Guardar tareas en un archivo antes de salir
lista_tareas.guardar_en_archivo(archivo_guardado)
print("Saliendo...")
break
else:
print("Opción no válida. Inténtalo de nuevo.")
if __name__ == "__main__":
main_avanzado()
from enum import Enum
class Prioridad(Enum):
BAJA = 1
MEDIA = 2
ALTA = 3
class TareaConPrioridad(TareaConFecha):
def __init__(self, nombre, descripcion, fecha_vencimiento=None, completada=False, prioridad=Prioridad.MEDIA):
super().__init__(nombre, descripcion, fecha_vencimiento, completada)
self.prioridad = prioridad
def __str__(self):
estado = "Completada" if self.completada else "Pendiente"
fecha_vencimiento_str = f" (Vence el {self.fecha_vencimiento.strftime('%Y-%m-%d')})" if self.fecha_vencimiento else ""
return f"{self.nombre} - {self.descripcion} ({estado}{fecha_vencimiento_str}, Prioridad: {self.prioridad.name})"
def editar_tarea(nombre_categoria, indice, lista_tareas):
categoria = next((c for c in lista_tareas.categorias if c.nombre == nombre_categoria), None)
if categoria:
if 1 <= indice <= len(categoria.tareas):
tarea = categoria.tareas[indice - 1]
print(f"Tarea actual: {tarea}")
nuevo_nombre = input("Nuevo nombre (presiona Enter para mantener el actual): ")
tarea.nombre = nuevo_nombre if nuevo_nombre else tarea.nombre
nueva_descripcion = input("Nueva descripción (presiona Enter para mantener la actual): ")
tarea.descripcion = nueva_descripcion if nueva_descripcion else tarea.descripcion
nueva_fecha_vencimiento_str = input("Nueva fecha de vencimiento (YYYY-MM-DD) o presiona Enter para mantener la actual: ")
if nueva_fecha_vencimiento_str:
tarea.fecha_vencimiento = datetime.strptime(nueva_fecha_vencimiento_str, '%Y-%m-%d')
nueva_prioridad_str = input("Nueva prioridad (BAJA, MEDIA, ALTA) o presiona Enter para mantener la actual: ")
if nueva_prioridad_str:
tarea.prioridad = Prioridad[nueva_prioridad_str.upper()]
print(f"Tarea editada: {tarea}")
else:
print("Índice de tarea no válido.")
else:
print(f"Categoría '{nombre_categoria}' no encontrada.")
def buscar_tarea(lista_tareas):
palabra_clave = input("Ingresa una palabra clave para buscar tareas: ")
tareas_encontradas = []
for categoria in lista_tareas.categorias:
for tarea in categoria.tareas:
if palabra_clave.lower() in tarea.nombre.lower() or palabra_clave.lower() in tarea.descripcion.lower():
tareas_encontradas.append(tarea)
if tareas_encontradas:
print(f"Tareas encontradas con '{palabra_clave}':")
for tarea in tareas_encontradas:
print(f"- {tarea}")
else:
print(f"No se encontraron tareas con '{palabra_clave}'.")
def resumen_estadistico(lista_tareas):
total_tareas = sum(len(categoria.tareas) for categoria in lista_tareas.categorias)
tareas_completadas = sum(1 for categoria in lista_tareas.categorias for tarea in categoria.tareas if tarea.completada)
tareas_vencidas = sum(1 for categoria in lista_tareas.categorias for tarea in categoria.tareas if isinstance(tarea, TareaConFecha) and tarea.fecha_vencimiento and tarea.fecha_vencimiento < datetime.now())
print("\nResumen Estadístico:")
print(f"Total de Tareas: {total_tareas}")
print(f"Tareas Completadas: {tareas_completadas}")
print(f"Tareas Vencidas: {tareas_vencidas}")
def menu_tareas_avanzado_con_prioridad():
print("\n--- Menú Tareas Avanzado con Prioridad ---")
print("1. Agregar Tarea a Categoría con Fecha de Vencimiento y Prioridad")
print("2. Mostrar Tareas de Categoría Ordenadas por Fecha de Vencimiento y Prioridad")
print("3. Marcar Tarea como Completada con Fecha de Vencimiento y Prioridad")
print("4. Eliminar Tarea de Categoría con Fecha de Vencimiento y Prioridad")
print("5. Editar Tarea")
print("6. Buscar Tarea")
print("7. Mostrar Resumen Estadístico")
print("8. Volver al Menú Principal")
def main_final():
lista_tareas = ToDoList()
archivo_guardado = "todolist_data.pkl"
# Cargar tareas desde un archivo (si existe)
lista_tareas.cargar_desde_archivo(archivo_guardado)
while True:
menu_principal()
opcion_principal = input("Selecciona una opción: ")
if opcion_principal == '1':
while True:
menu_categorias()
opcion_categorias = input("Selecciona una opción: ")
if opcion_categorias == '1':
nombre_categoria = input("Ingrese el nombre de la categoría: ")
nueva_categoria = Categoria(nombre_categoria)
lista_tareas.agregar_categoria(nueva_categoria)
elif opcion_categorias == '2':
lista_tareas.mostrar_categorias()
elif opcion_categorias == '3':
break
else:
print("Opción no válida. Inténtalo de nuevo.")
elif opcion_principal == '2':
while True:
menu_tareas_avanzado_con_prioridad()
opcion_tareas_avanzado = input("Selecciona una opción: ")
if opcion_tareas_avanzado == '1':
agregar_tarea_con_fecha(nombre_categoria, lista_tareas)
elif opcion_tareas_avanzado == '2':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
elif opcion_tareas_avanzado == '3':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
indice_completar = int(input("Ingrese el número de la tarea a marcar como completada/pendiente: "))
marcar_completada_con_fecha(nombre_categoria, indice_completar, lista_tareas)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas_avanzado == '4':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
indice_eliminar = int(input("Ingrese el número de la tarea a eliminar: "))
eliminar_tarea_con_fecha(nombre_categoria, indice_eliminar, lista_tareas)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas_avanzado == '5':
lista_tareas.mostrar_categorias()
nombre_categoria = input("Ingrese el nombre de la categoría: ")
if lista_tareas.categorias:
mostrar_tareas_ordenadas(nombre_categoria, lista_tareas)
indice_editar = int(input("Ingrese el número de la tarea a editar: "))
editar_tarea(nombre_categoria, indice_editar, lista_tareas)
else:
print(f"No hay tareas en la categoría '{nombre_categoria}'.")
elif opcion_tareas_avanzado == '6':
buscar_tarea(lista_tareas)
elif opcion_tareas_avanzado == '7':
resumen_estadistico(lista_tareas)
elif opcion_tareas_avanzado == '8':
break
else:
print("Opción no válida. Inténtalo de nuevo.")
elif opcion_principal == '3':
# Guardar tareas en un archivo antes de salir
lista_tareas.guardar_en_archivo(archivo_guardado)
print("Saliendo...")
break
else:
print("Opción no válida. Inténtalo de nuevo.")
if __name__ == "__main__":
main_final()
