Skip to content

xnexuzx/ToDoList-ED1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Gestión de Tareas con Lista Enlazada Simple — v2.0.0

Descripción

Aplicación universitaria para la materia Estructuras de Datos I que implementa un gestor de tareas (To-Do List) usando una Lista Enlazada Simple como estructura de datos central.

La v2.0.0 agrega soporte para múltiples listas independientes, búsqueda global con normalización de texto, edición inline, favoritos y persistencia automática en JSON.

Cada tarea se representa como un Nodo que contiene su título, descripción, estado (Pendiente / Completada), bandera de favorito, y un puntero al siguiente nodo en la cadena.


Arquitectura MVC

El proyecto sigue el patrón Modelo–Vista–Controlador (MVC), con responsabilidades separadas y sin dependencias cruzadas entre capas:

Capa Archivo Responsabilidad
Modelo src/models/model.py Nodo, ListaEnlazadaTareas, GestorListas + JSON
Vista src/views/view.py Interfaz gráfica Tkinter; no importa al controlador
Controlador src/controllers/controller.py Intermediario: recibe callbacks de la Vista, opera el Modelo

Flujo del dato: de la Vista al Modelo y de vuelta

Agregar tarea

VISTA   → usuario escribe título y pulsa ✓
CTRL    → llama a gestor.listas[lista_activa].agregar_tarea(titulo, desc)
MODELO  → crea Nodo y lo enlaza al final de la cadena  [O(n)]
CTRL    → llama a gestor.guardar_json() + vista._refrescar_vista()
VISTA   → redibuja las tarjetas con la nueva tarea visible

Completar / Eliminar tarea

VISTA   → usuario hace click en una card (selección por índice)
CTRL    → registra tarea_seleccionada y habilita botones de la toolbar
VISTA   → usuario pulsa ✓ Completar o ✕
CTRL    → lista.toggle_completada(indice) | lista.eliminar_tarea(indice)
MODELO  → recorre la cadena hasta el nodo en posición [indice]  [O(n)]
CTRL    → guardar_json() + _refrescar_vista()
VISTA   → redibuja con el estado actualizado

Búsqueda global

VISTA   → usuario pulsa 🔍 y escribe texto
CTRL    → llama a gestor.buscar_global(texto, solo_favoritas)
MODELO  → recorre TODAS las listas y aplica normalización NFD + lower()
CTRL    → entrega la lista de resultados a vista.renderizar_resultados_busqueda()
VISTA   → muestra tarjetas con "NombreLista › Título"

Estructura del Proyecto

envWin/
├── src/
│   ├── main.py                   # Punto de entrada; instancia ControladorTareas
│   ├── models/
│   │   ├── __init__.py
│   │   └── model.py              # Nodo · ListaEnlazadaTareas · GestorListas
│   ├── views/
│   │   ├── __init__.py
│   │   ├── view.py               # VistaTareas (widgets Tkinter)
│   │   └── styles.py             # Paleta de colores, fuentes y constantes UI
│   ├── controllers/
│   │   ├── __init__.py
│   │   └── controller.py         # ControladorTareas (callbacks MVC)
│   └── data/
│       └── tareas.json           # Persistencia automática (generado en runtime)
├── tests/
│   └── test_model.py             # 15 pruebas unitarias con unittest
├── requirements.txt              # Sin dependencias externas (solo stdlib)
├── run.bat                       # Lanzador rápido para Windows
└── README.md                     # Este archivo

Clases del Modelo

Nodo

Unidad atómica de la lista enlazada.

Atributo Tipo Descripción
titulo str Texto principal de la tarea
descripcion str Detalle opcional (cadena vacía por defecto)
estado str 'Pendiente' o 'Completada'
favorito bool Marca de favorito; False por defecto
siguiente Nodo | None Puntero al próximo nodo; None indica fin de cadena

ListaEnlazadaTareas

Implementa la lista enlazada simple. La cabeza (self.cabeza) es el único punto de acceso.

Método Complejidad Descripción
agregar_tarea O(n) Recorre hasta el último nodo y enlaza el nuevo al final
_obtener_nodo O(n) Busca un nodo por índice (helper interno)
toggle_completada O(n) Alterna estado entre 'Pendiente' y 'Completada'
editar_tarea O(n) Sobrescribe titulo y descripcion del nodo en [indice]
marcar_favorito O(n) Invierte el valor booleano de favorito
eliminar_tarea O(n) Redirige el puntero del nodo anterior para saltar al eliminado
obtener_todas O(n) Recorre la cadena y retorna una lista de dicts (0-indexed)
obtener_favoritas O(n) Filtra obtener_todas() por favorito == True

GestorListas

Repositorio central de múltiples ListaEnlazadaTareas con persistencia JSON.

Método Descripción
agregar_lista Crea una nueva lista; retorna False si el nombre ya existe
eliminar_lista Elimina la lista completa con todas sus tareas
buscar_global Busca subcadena en títulos y descripciones de todas las listas
guardar_json Serializa todas las listas y las escribe en data/tareas.json
cargar_json Lee el JSON y reconstruye las listas enlazadas en memoria

Modo :memory:: si se instancia con GestorListas(':memory:'), los métodos guardar_json y cargar_json son no-operativos. Se usa en los tests unitarios para evitar E/S de disco.


Complejidad Algorítmica

Todas las operaciones son O(n) en tiempo porque la Lista Enlazada Simple no tiene acceso aleatorio — es necesario recorrer la cadena nodo a nodo hasta alcanzar el índice deseado.

Operación Tiempo Espacio auxiliar Justificación
agregar_tarea O(n) O(1) Recorre hasta el último nodo para enlazar el nuevo
toggle_completada O(n) O(1) Recorre hasta el índice deseado y cambia el campo estado
editar_tarea O(n) O(1) Recorre hasta el índice y sobreescribe titulo y descripcion
marcar_favorito O(n) O(1) Recorre hasta el índice y niega el booleano favorito
eliminar_tarea O(n) O(1) Necesita el nodo anterior al eliminado para redirigir el puntero
obtener_todas O(n) O(n) Construye una lista Python con un dict por cada nodo
buscar_global O(n·m) O(k) n = tareas totales en todas las listas, m = len(texto), k = coincidencias

Nota: mantener un puntero cola bajaría agregar_tarea a O(1), pero se omitió para hacer el recorrido explícito y pedagógico.


Instalación y Configuración

Prerrequisitos

  • Python 3.8 o superior.

  • tkinter viene incluido en Python para Windows y macOS. En Linux puede requerir instalación adicional:

    sudo apt-get install python3-tk

Pasos

# 1. Clonar el repositorio
git clone <URL-del-repositorio>
cd <carpeta-del-proyecto>

# 2. No se requiere instalar dependencias externas.
#    El proyecto usa exclusivamente la biblioteca estándar de Python.

Cómo Ejecutar la Aplicación

Windows (lanzador rápido)

run.bat

Multiplataforma

Desde la raíz del proyecto:

python src/main.py

La ventana se abre con:

  • Barra de tabs: una pestaña por lista, con botón ✕ para eliminar y + Agregar lista.
  • Panel de tarjetas: cada tarea muestra su estado (barra lateral verde/naranja), favorito (★/○), título, descripción y etiqueta [Pendiente] / [Completada].
  • Toolbar inferior: botones ✓ Completar, ☆ Favorito, ✏ Editar, ✕ Eliminar (habilitados al seleccionar una tarea).
  • Modo búsqueda: botón 🔍 activa un campo de texto con búsqueda en tiempo real y filtro de favoritas.
  • Modo edición: el panel de tarjetas se reemplaza por un formulario de edición con campos Título y Descripción.

Cómo Ejecutar los Tests

Desde la raíz del proyecto:

python -m unittest discover tests -v

Resultado esperado:

test_busqueda_global_multilist (test_model.TestGestorListas) ... ok
test_busqueda_ignora_acentos (test_model.TestGestorListas) ... ok
test_busqueda_ignora_mayusculas (test_model.TestGestorListas) ... ok
test_busqueda_solo_favoritas (test_model.TestGestorListas) ... ok
test_gestor_agregar_lista (test_model.TestGestorListas) ... ok
test_gestor_eliminar_lista (test_model.TestGestorListas) ... ok
test_gestor_nombre_duplicado (test_model.TestGestorListas) ... ok
test_persistencia_guardar_cargar (test_model.TestGestorListas) ... ok
test_agregar_enlaza_correctamente (test_model.TestListaEnlazadaTareas) ... ok
test_editar_tarea_cambia_campos (test_model.TestListaEnlazadaTareas) ... ok
test_eliminar_cabeza (test_model.TestListaEnlazadaTareas) ... ok
test_eliminar_reasigna_punteros (test_model.TestListaEnlazadaTareas) ... ok
test_lista_vacia_obtener_todas (test_model.TestListaEnlazadaTareas) ... ok
test_marcar_favorito_toggle (test_model.TestListaEnlazadaTareas) ... ok
test_toggle_completada (test_model.TestListaEnlazadaTareas) ... ok
----------------------------------------------------------------------
Ran 15 tests in 0.016s

OK

Cobertura de la suite (15 tests)

TestListaEnlazadaTareas (7 tests)

Test Qué verifica
test_agregar_enlaza_correctamente Cadena A→B→C correcta; último nodo apunta a None
test_eliminar_reasigna_punteros Eliminar B de A→B→C produce A→C; punteros redirigidos correctamente
test_eliminar_cabeza Eliminar índice 0 promueve al segundo nodo como nueva cabeza
test_toggle_completada Doble toggle: Pendiente→Completada→Pendiente; retorna True
test_editar_tarea_cambia_campos Sobrescribe título y descripción sin crear un nodo nuevo
test_marcar_favorito_toggle Doble toggle: FalseTrueFalse
test_lista_vacia_obtener_todas Lista sin nodos retorna [], no None

TestGestorListas (8 tests)

Test Qué verifica
test_gestor_agregar_lista Lista nueva registrada como ListaEnlazadaTareas en el dict interno
test_gestor_nombre_duplicado Nombre repetido retorna False y no duplica la entrada
test_gestor_eliminar_lista Eliminar "A" no afecta "B"; "A" desaparece del gestor
test_busqueda_global_multilist Búsqueda "comprar" encuentra resultados en L1 y L2 (2 resultados)
test_busqueda_ignora_mayusculas "TAREA IMPORTANTE" encontrada con búsqueda "tarea"
test_busqueda_ignora_acentos "Música relajante" encontrada con búsqueda "musica" (sin acento)
test_busqueda_solo_favoritas Filtro solo_favoritas=True excluye tareas no marcadas
test_persistencia_guardar_cargar Datos guardados en JSON (título, favorito) se recuperan en otro gestor

About

PROYECTO 1 ED1 - ING. CAMPOS

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors