Cerrábamos el módulo 7 con un diagnóstico incómodo: TareaFácil v0.17 funciona, está bien repartido en módulos y no tiene un solo ciclo de importación, pero no está documentado más allá de unas docstrings sueltas. Si mañana Marta contrata a alguien y le pasa la carpeta tareafacil/, esa persona tendrá que leerse los cinco ficheros enteros para averiguar qué hace el programa, cómo se arranca y qué significa que una tarea tenga dias. Y no hace falta imaginarse a un desconocido: tú dentro de seis meses eres exactamente ese desconocido, con la desventaja añadida de creer que te acuerdas. Esta lección convierte el paquete en algo que se entiende en cinco minutos: comentarios que explican el porqué y no el qué, docstrings de verdad siguiendo la convención oficial, anotaciones de tipo que documentan y además ayudan al editor, y un README.md que es la puerta de entrada del proyecto. Documentar no es escribir mucho: es escribir lo que el código no puede decir por sí solo.
Contenido
- Para quién se documenta
- Comentarios: la regla de oro
- Comentarios que mienten y marcadores
TODO/FIXME - Docstrings: la convención PEP 257
- Los tres estilos: Google, NumPy y reStructuredText
- Anotaciones de tipo: documentación ejecutable
- El
README.mddel proyecto CHANGELOG.md, versionado semántico y herramientas- TareaFácil v0.18: el paquete documentado
- Errores comunes y consejos
- Ejercicios
- Conclusión
- Para quién se documenta
Antes de escribir una sola línea conviene tener claro a quién se la escribes, porque cada lector necesita cosas distintas:
| Lector | Qué necesita saber | Dónde lo busca |
|---|---|---|
| Quien usa el programa | Qué hace, cómo se instala, cómo se arranca | README.md |
| Quien usa una función tuya | Qué recibe, qué devuelve, qué puede fallar | Docstring y anotaciones |
| Quien modifica el código | Por qué está hecho así y no de otra manera | Comentarios en el punto exacto |
| Tú dentro de seis meses | Todo lo anterior, y lo has olvidado | Los tres sitios a la vez |
De ahí salen las tres herramientas de la lección, y cada una tiene su sitio: el README explica el proyecto desde fuera, las docstrings explican cada pieza a quien la va a usar, y los comentarios explican decisiones concretas a quien va a tocar esa línea. Confundirlas es el primer error: un README de doscientas líneas no sustituye a una docstring, y un comentario dentro de una función no lo leerá jamás quien solo quiere llamarla. Y una advertencia que atraviesa toda la lección: la mejor documentación es el código que no la necesita; antes de escribir un comentario que explique un tramo confuso, pregúntate si no sería mejor renombrar una variable o extraer una función con un nombre claro, algo que retomaremos en Estilo, legibilidad y refactorización.
- Comentarios: la regla de oro
La sintaxis ya la conoces desde el módulo 2: # convierte en comentario todo lo que va desde ese punto hasta el final de la línea, y Python lo ignora por completo. Puede ocupar una línea entera o ir al final de una línea de código. Lo que no es evidente es qué escribir dentro, y ahí la regla de oro es esta: el código dice el qué; el comentario dice el porqué. El intérprete ya cuenta con total precisión lo que ocurre; lo que no puede contar es la decisión, la restricción o la sorpresa que hay detrás.
# COMENTARIOS INUTILES: repiten lo que el codigo ya dice
contador = contador + 1 # incrementamos el contador en uno
if tarea.completada: # si la tarea esta completada
hechas.append(tarea) # la anadimos a la lista de hechas
# COMENTARIO VALIOSO: explica el porque
# El equipo trabaja de lunes a viernes: 5 dias reales por semana natural.
# Sin este ajuste, una tarea de 10 dias caia en sabado en el informe de Marta.
semanas = dias / 5Los tres primeros comentarios no aportan nada: cualquiera que sepa Python los deduce leyendo la línea, y además envejecen mal. El último contiene información que no está en ninguna parte del código: una regla de negocio del Estudio Alba que costó una tarde descubrir. Si lo borras, esa información desaparece del universo. Casos en los que un comentario casi siempre merece la pena:
- Reglas de negocio que un lector no puede adivinar (los 5 días laborables, el descuento del cliente Vidal) y decisiones descartadas: «se usó búsqueda lineal a propósito: la lista nunca pasa de 200 tareas».
- Trucos obligados por una limitación externa: un formato de fichero raro, una peculiaridad de una librería.
- Advertencias, fórmulas y unidades: «no cambies el orden de estas dos líneas», o de dónde sale un número y en qué unidad está.
- Comentarios que mienten y marcadores
TODO/FIXME
TODO/FIXMEHay algo peor que la falta de un comentario: un comentario que miente. El código se cambia y el comentario se queda como estaba, y a partir de ahí engaña activamente a quien lo lea.
# Devuelve las tareas de prioridad alta <-- MENTIRA: ya no filtra por prioridad
def pendientes(agenda):
return [t for t in agenda if not t.completada]Quien lea ese comentario confiará en él y buscará el error en otro sitio. La disciplina es simple y no negociable: cuando cambias una línea, revisas su comentario; y entre un comentario dudoso y ninguno, ninguno es mejor. Este riesgo es otro argumento a favor de las anotaciones de tipo y de los buenos nombres: no se desincronizan tan fácilmente porque forman parte del código. Para las tareas pendientes, además, existe una convención universal que todos los editores reconocen y resaltan:
| Marcador | Significado | Ejemplo |
|---|---|---|
TODO |
Falta hacer algo, pero no está roto | # TODO: permitir editar el responsable |
FIXME |
Hay algo mal que habrá que arreglar | # FIXME: si dias es 0 la media revienta |
HACK |
Solución provisional y fea, a sabiendas | # HACK: reordenamos dos veces por un fallo del export |
NOTE |
Aviso importante para quien lea | # NOTE: este fichero lo lee el script de Marta |
En VS Code aparecen resaltados y se pueden listar todos con una búsqueda de TODO en el proyecto. Escríbelos con una frase concreta —# TODO: validar el correo sirve; # TODO: mejorar esto no— y revísalos de vez en cuando: un proyecto con cuarenta TODO de hace dos años es un proyecto donde nadie los lee.
- Docstrings: la convención PEP 257
Una docstring es una cadena de texto colocada como primera instrucción de un módulo, una clase o una función. A diferencia de un comentario, Python la guarda en el atributo __doc__ del objeto, así que puede consultarse en tiempo de ejecución. Las usamos de pasada desde 04-01; ahora las hacemos bien. La convención oficial es la PEP 257, y sus reglas prácticas son estas:
- Se escriben siempre con comillas triples (
"""), incluso si ocupan una sola línea, y la primera es un resumen corto en modo imperativo terminado en punto: «Devuelve...», «Calcula...», «Guarda...», nunca «Esta función devuelve...». - Si hay más texto, se deja una línea en blanco después del resumen, y las comillas de cierre van en su propia línea.
def dias_restantes(tarea):
"""Devuelve los dias que faltan para terminar la tarea.
Nunca devuelve un numero negativo: si el equipo ha dedicado mas dias
de los previstos, el resultado es 0.
"""
return max(0, tarea.dias - tarea.hechos)Las docstrings van en cuatro sitios, y cada una responde a una pregunta distinta:
| Dónde | Qué debe contar |
|---|---|
Módulo (primera línea del .py) |
Qué contiene el fichero y para qué sirve |
Paquete (en el __init__.py) |
Qué es el proyecto y qué módulos lo forman |
Clase (bajo la línea class) |
Qué representa, sus atributos y su uso típico |
Función o método (bajo el def) |
Qué hace, qué recibe, qué devuelve y qué puede fallar |
Y así se leen, sin salir del intérprete: help(Tarea.completar) muestra la firma y la docstring ya formateadas, Tarea.completar.__doc__ devuelve la cadena en crudo y help(tareafacil.modelo) presenta la documentación del módulo entero. Ese es el motivo real de escribirlas: help() funciona con tu código igual que con help(str.upper). Si la docstring está bien escrita, quien use tu módulo no necesita abrir el fichero.
- Los tres estilos: Google, NumPy y reStructuredText
Para funciones con varios parámetros hace falta una estructura. Existen tres convenciones extendidas; todas dicen lo mismo y cambian solo en la forma. Aquí está la misma función en las tres:
# --- Estilo Google: el mas legible en texto plano ---
def filtrar_por(tareas, campo, valor):
"""Devuelve las tareas cuyo campo coincide con el valor dado.
Args:
tareas (list[Tarea]): Coleccion de tareas a filtrar.
campo (str): Nombre del atributo, por ejemplo "responsable".
valor (str): Valor buscado, sin distinguir mayusculas.
Returns:
list[Tarea]: Las tareas que cumplen la condicion.
Raises:
AttributeError: Si el campo no existe en Tarea.
"""
# --- Estilo NumPy: apartados subrayados con guiones ---
"""
Parameters
----------
tareas : list[Tarea]
Coleccion de tareas a filtrar.
campo : str
Nombre del atributo, por ejemplo "responsable".
Returns
-------
list[Tarea]
Las tareas que cumplen la condicion.
"""
# --- Estilo reStructuredText (Sphinx clasico): campos con dos puntos ---
"""
:param tareas: Coleccion de tareas a filtrar.
:returns: Las tareas que cumplen la condicion.
"""| Estilo | Aspecto en texto plano | Verbosidad | Dónde se ve más |
|---|---|---|---|
| Muy legible tal cual | Baja | Proyectos generales, Python moderno | |
| NumPy | Legible, ocupa más | Media | Ciencia de datos: numpy, scipy, pandas |
| reStructuredText | Ruidoso sin renderizar | Alta | Proyectos antiguos con Sphinx |
Recomendación para este curso: el estilo Google. Es el que mejor se lee sin herramientas, el más corto y el que menos estorba mientras programas. Pero lo importante no es cuál elijas, sino ser consistente: un proyecto con tres estilos mezclados confunde más que uno sin documentar. Elige uno, anótalo en el README y respétalo. Un detalle práctico: con anotaciones de tipo puedes ahorrarte los tipos entre paréntesis, porque ya están en la firma; campo (str): pasa a ser campo:.
- Anotaciones de tipo: documentación ejecutable
Las anotaciones de tipo (type hints) declaran qué tipo se espera en cada parámetro y qué tipo se devuelve. Se escriben con dos puntos tras el parámetro y una flecha -> antes del cuerpo:
def resumen(titulo: str, dias: int, urgente: bool = False) -> str:
"""Devuelve una linea de resumen para el listado."""
return f"{'!' if urgente else ' '} {titulo} ({dias} dias)"Se lee así: titulo es un str, dias un int, urgente un bool con valor por defecto False, y la función devuelve un str. Para las estructuras del módulo 5 se indica también qué contienen:
| Anotación | Significa |
|---|---|
list[str] |
Lista de cadenas |
dict[str, int] |
Diccionario con claves de texto y valores enteros |
tuple[str, int] |
Tupla de exactamente dos elementos: un texto y un entero |
str | None |
Un texto o None (típico de una búsqueda que puede fallar) |
list[Tarea] |
Lista de objetos de tu propia clase; -> None: no devuelve nada útil |
def buscar(tareas: list[Tarea], titulo: str) -> Tarea | None:
"""Devuelve la primera tarea con ese titulo, o None si no existe."""El Tarea | None de buscar es especialmente valioso: avisa al lector de que debe comprobar el None antes de usar el resultado, un aviso que sin anotación solo estaría en la cabeza de quien escribió la función. Y ahora lo imprescindible: Python no comprueba las anotaciones en ejecución. La llamada resumen(titulo=42, dias="tres") no lanza ningún error por las anotaciones; el programa sigue adelante hasta romperse más adentro, con un mensaje que ya no señala al culpable. Las anotaciones son documentación que el editor entiende: VS Code autocompleta los métodos y subraya el error antes de ejecutar. Si quieres comprobación real existe mypy, una herramienta externa que analiza el código y avisa de las incoherencias (pip install mypy, después mypy tareafacil/). La retomaremos en 08-05 con el resto de herramientas de calidad.
- El
README.md del proyecto
README.md del proyectoEl README.md se coloca en la raíz del proyecto y es lo primero que cualquiera abre (GitHub y GitLab lo muestran automáticamente, como veremos en 08-03). Debe responder, en este orden, a: qué es esto, qué necesito, cómo lo instalo, cómo lo uso, cómo está organizado y qué puedo hacer con él. Lo esencial de Markdown cabe en una tabla:
| Sintaxis | Resultado |
|---|---|
# Titulo / ## Apartado |
Encabezados de nivel 1 y 2 |
**negrita** / *cursiva* y - elemento / 1. elemento |
Énfasis y listas |
`codigo` y bloques con ``` |
Código en línea y en bloque |
[texto](url) y filas con | |
Enlace y tabla |
Y este es el README de TareaFácil:
# TareaFacil Gestor de tareas de linea de comandos para el equipo del Estudio Alba. Permite crear tareas, asignarlas a un responsable, marcarlas como completadas, filtrarlas, ordenarlas por prioridad y guardarlas en un fichero JSON. ## Requisitos - Python 3.10 o superior (se usa `match`/`case` y la sintaxis `str | None`). - Ninguna libreria externa: todo es biblioteca estandar. ## Instalacion y uso
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate python -m tareafacil # desde la carpeta del paquete
Las tareas se guardan solas en `tareas.json`. La opcion 9 exporta un `tareas.csv`. ## Estructura - `modelo.py`: clases `Tarea` y `TareaRecurrente`. - `agenda.py`: clase `Agenda`, la coleccion y sus operaciones. - `almacen.py`: guardar y cargar en JSON, exportar a CSV. - `interfaz.py`: menu y entrada/salida. `__main__.py`: el `main()`. ## Convenciones y licencia - Docstrings en estilo Google. Prioridades validas: `alta`, `media`, `baja`. - Equipo: Marta, Luis y Nuria (`EQUIPO`). Uso interno del Estudio Alba.
Fíjate en lo que no tiene: no explica cómo funciona Agenda.ordenadas() por dentro —eso es trabajo de la docstring— ni cuenta la historia del proyecto. Un README se mide por lo rápido que alguien pasa de abrirlo a tener el programa funcionando.
CHANGELOG.md, versionado semántico y herramientas
CHANGELOG.md, versionado semántico y herramientasJunto al README suele vivir un CHANGELOG.md: la lista de cambios de cada versión, la más reciente arriba. Responde a «¿qué ha cambiado desde la versión que yo tenía?» sin leer el historial entero. Y los números de versión que este curso lleva usando desde el módulo 3 no son arbitrarios: siguen el versionado semántico, MAYOR.MENOR.PARCHE.
| Parte | Cuándo sube | Ejemplo en TareaFácil |
|---|---|---|
| MAYOR | Cambio que rompe el uso anterior | 0.x → 1.0: el proyecto se considera estable |
| MENOR | Funcionalidad nueva compatible | 0.17 → 0.18: se añade la documentación |
| PARCHE | Corrección de un fallo, sin cambios de uso | 1.0 → 1.0.1: se arregla un cálculo |
Por convención, cualquier versión que empiece por 0 significa «esto aún puede cambiar de cualquier manera», que es exactamente la situación de TareaFácil durante todo el curso; al final del módulo llegará la v1.0. Una entrada de CHANGELOG es tan simple como esta:
## [0.18] - 2026-08-05
### Anadido
- Docstrings de modulo, clase y funcion en todo el paquete.
- Anotaciones de tipo en las funciones publicas, README.md y CHANGELOG.md.Todo esto son ficheros de texto, pero se pueden explotar automáticamente. Python trae pydoc, que lee tus docstrings y las presenta ya formateadas: python -m pydoc tareafacil.modelo las muestra en la terminal, python -m pydoc -w tareafacil.modelo genera un HTML y python -m pydoc -b abre un navegador con todo el proyecto. Es la recompensa inmediata de haber escrito docstrings correctas: sin instalar nada, tienes tu paquete documentado y navegable. Para proyectos grandes existen Sphinx (el generador con el que está hecha la documentación oficial de Python) y MkDocs (más sencillo, parte de ficheros Markdown), que producen sitios web completos con búsqueda e índice; quedan lejos de lo que TareaFácil necesita, pero se alimentan de las mismas docstrings que acabas de aprender a escribir.
- TareaFácil v0.18: el paquete documentado
Aplicamos todo al proyecto: docstring de módulo en cada fichero, docstrings completas en las clases, anotaciones en las funciones públicas y el README que ya has visto.
"""Modelo de datos de TareaFacil.
Define la clase Tarea y su especializacion TareaRecurrente, junto con las
constantes del dominio. No depende de ningun otro modulo del paquete y no
imprime nada: puede reutilizarse desde una web o desde un script.
"""
class Tarea:
"""Una tarea del Estudio Alba con su responsable y su estimacion.
Attributes:
titulo: Descripcion breve, por ejemplo "Cartel feria del libro".
responsable: Nombre en minusculas, uno de EQUIPO.
prioridad: Una de PRIORIDADES ("alta", "media" o "baja").
dias: Dias estimados de trabajo; siempre mayor que 0.
hechos: Dias ya dedicados.
completada: True si la tarea esta terminada.
"""
def __init__(self, titulo: str, responsable: str, prioridad: str = "media",
dias: int = 1) -> None:
"""Crea una tarea normalizando el responsable y la prioridad."""
def progreso(self) -> float:
"""Devuelve el porcentaje de avance, entre 0.0 y 100.0."""
# dias siempre es > 0 por validacion, asi que no hay division por cero
return min(100.0, self.hechos / self.dias * 100)En agenda.py la docstring de clase incluye además un ejemplo de uso, que es lo que más agradece quien llega nuevo; y el __init__.py documenta el paquete entero y lleva el número de versión:
class Agenda:
"""Conjunto de tareas del equipo, con busqueda, filtrado y orden.
La lista interna es privada: se accede recorriendo la agenda
(`for tarea in agenda`) o mediante los metodos publicos.
Example:
>>> agenda = Agenda()
>>> agenda.agregar(Tarea("Logotipo Sole", "nuria", "alta", 5))
>>> len(agenda)
1
"""
# --- tareafacil/__init__.py: la docstring de paquete ---
"""TareaFacil: gestor de tareas del Estudio Alba.
Modulos: modelo (Tarea y TareaRecurrente), agenda, almacen e interfaz.
Uso: python -m tareafacil
"""
__version__ = "0.18"Ahora python -m pydoc -b abre una página con todo el paquete explicado, y quien reciba la carpeta sabe en cinco minutos qué es, cómo se arranca y qué hace cada fichero. TareaFácil v0.18: mismo comportamiento, proyecto comprensible.
Errores Comunes y Consejos
- Comentar el qué en lugar del porqué, o dejar comentarios que mienten.
contador += 1 # sumamos unoes ruido; y al cambiar una línea hay que revisar su comentario, porque uno desactualizado hace más daño que ninguno. - Usar
#donde toca una docstring. Un comentario encima deldefno lo recogenhelp()nipydoc; una docstring dentro deldef, sí. - Docstrings en tercera persona, con comillas simples o en tres estilos mezclados. Comillas triples siempre, primera línea imperativa («Devuelve...», no «Esta función devuelve...») y un solo estilo (Google) anotado en el README.
- Creer que las anotaciones de tipo validan algo. No lo hacen: son documentación; para validar de verdad hacen falta comprobaciones en el código, o
mypyfuera de él. - Escribir un README que empieza por la instalación. Empieza por una frase que diga qué es el programa: hay quien solo va a leer esa línea.
- Consejo: documenta al escribir, no al final. Escribir la docstring antes del cuerpo obliga a aclarar qué hace la función, y a veces revela que hace dos cosas y debería partirse.
Ejercicios
Ejercicio 1: Comentarios que aportan
Este fragmento del informe mensual de Estudio Alba está lleno de comentarios inútiles y le falta el único que importa. Reescríbelo dejando solo comentarios valiosos y añade docstring y anotaciones de tipo.
def coste(dias, tarifa):
total = dias * tarifa # multiplicamos dias por tarifa
total = total * 1.21 # multiplicamos por 1.21
if dias > 20: # si los dias son mas de 20
total = total * 0.9 # multiplicamos por 0.9
return total # devolvemos el totalEjercicio 2: Docstring y anotaciones
Escribe la docstring en estilo Google y las anotaciones de tipo completas de esta función, incluyendo el apartado Raises:
def cargar_equipo(ruta):
with open(ruta, encoding="utf-8") as f:
return [linea.strip().lower() for linea in f if linea.strip()]Ejercicio 3: Versionado y CHANGELOG
Marta quiere un programa aparte, informes, que lea el tareas.json de TareaFácil. Escribe las dos primeras secciones de su README.md (qué es y requisitos) y decide qué número de versión le corresponde a TareaFácil en cada uno de estos tres cambios, justificándolo: (a) se corrige un cálculo del progreso que daba 101 %; (b) se añade la exportación a CSV; (c) Tarea deja de aceptar el parámetro dias y pasa a exigir una fecha de entrega.
Soluciones
Solución 1.
IVA, DESCUENTO_LARGO, DIAS_PROYECTO_LARGO = 1.21, 0.9, 20
def coste(dias: int, tarifa: float) -> float:
"""Devuelve el coste de un encargo con IVA y descuento por volumen.
Args:
dias: Dias de trabajo estimados.
tarifa: Precio por dia en euros, sin impuestos.
Returns:
Importe final en euros, IVA incluido.
"""
total = dias * tarifa * IVA
# El Estudio Alba aplica un 10% de descuento a partir de 20 dias:
# acordado con Marta en la revision de tarifas de 2026.
if dias > DIAS_PROYECTO_LARGO:
total *= DESCUENTO_LARGO
return round(total, 2)Han desaparecido los cinco comentarios que repetían el código y ha aparecido el único con información real: de dónde sale el descuento. Fíjate además en que los números 1.21, 0.9 y 20 se han convertido en constantes con nombre, que documentan por sí mismas y evitan tener que explicarlas (volveremos a esta técnica en 08-05). La docstring cuenta lo que la firma no dice: que la tarifa va sin impuestos y que el resultado los lleva.
Solución 2.
def cargar_equipo(ruta: str) -> list[str]:
"""Lee los nombres del equipo de un fichero de texto.
Cada linea no vacia es un nombre, devuelto sin espacios y en minusculas.
Args:
ruta: Ruta al fichero de texto, codificado en UTF-8.
Returns:
Lista de nombres normalizados, en el orden del fichero.
Raises:
FileNotFoundError: Si el fichero no existe.
UnicodeDecodeError: Si el fichero no esta en UTF-8.
"""
with open(ruta, encoding="utf-8") as f:
return [linea.strip().lower() for linea in f if linea.strip()]El apartado Raises es el que más se olvida y a menudo el más útil: avisa a quien llama de que esta función puede fallar y de qué tendrá que protegerse. Cómo se capturan esas excepciones es justo el tema de la lección siguiente.
Solución 3.
# Informes Alba Genera un resumen mensual de tareas por responsable a partir del `tareas.json` que produce TareaFacil, para la revision de equipo del primer lunes de cada mes. ## Requisitos - Python 3.10 o superior y un `tareas.json` de TareaFacil 0.18 o posterior.
La primera frase es la más importante de todo el fichero: dice qué es el programa y para quién, y hay lectores que no van a leer nada más. En cuanto a las versiones: (a) es un parche (0.18 → 0.18.1), porque corrige un fallo sin cambiar la forma de usar el programa; (b) es una versión menor (0.18 → 0.19), funcionalidad nueva que no rompe nada de lo anterior; y (c) es un cambio mayor, porque todo el código que creaba tareas con dias deja de funcionar: si el proyecto ya estuviera en la 1.0, pasaría a la 2.0.
Conclusión
Documentar es escribir lo que el código no puede decir por sí solo, y tiene tres herramientas con tres destinatarios distintos. Los comentarios (#) explican el porqué y no el qué: reglas de negocio, decisiones descartadas, advertencias y trampas encontradas a base de horas; todo lo que repita la línea de al lado sobra, y todo comentario que no se actualiza acaba mintiendo, que es peor que faltar. Los marcadores TODO, FIXME, HACK y NOTE dejan constancia de lo pendiente en el punto exacto donde está. Las docstrings, con comillas triples y primera línea imperativa según la PEP 257, viven en módulos, paquetes, clases y funciones, se consultan con help() y __doc__, y se escriben en uno de los tres estilos habituales —Google, NumPy o reStructuredText—; aquí elegimos Google, y lo decisivo es no mezclarlos. Las anotaciones de tipo (str, list[str], dict[str, int], Tarea | None, -> None) son documentación que además entiende el editor, con la advertencia clara de que Python no las comprueba en ejecución: para eso está mypy. El README.md es la puerta de entrada del proyecto y responde en orden a qué es, qué necesita, cómo se instala, cómo se usa, cómo está organizado y bajo qué licencia; el CHANGELOG.md cuenta qué cambió en cada versión, y el versionado semántico MAYOR.MENOR.PARCHE explica de dónde salen los números que este curso lleva usando desde el principio. Con python -m pydoc -b todo eso se convierte en documentación navegable sin instalar nada, y Sphinx o MkDocs harían lo mismo a lo grande.
TareaFácil es ahora la v0.18: mismo comportamiento, pero con docstring de módulo en cada fichero, Tarea y Agenda completamente documentadas, anotaciones de tipo en las funciones públicas y un README.md que permite a cualquiera arrancar el programa en cinco minutos. El proyecto se entiende. Lo que todavía no hace es aguantar: si el tareas.json está corrupto o alguien escribe «tres» donde el programa espera un número de días, el resultado sigue siendo un traceback en la cara del usuario y la sesión perdida. Es la promesa que el curso arrastra desde 02-04 y desde 05-05, y le toca el turno en Depuración y manejo de errores: leer un traceback sin miedo, capturar con try/except solo lo que se debe capturar, lanzar excepciones propias como TareaInvalida, registrar lo que pasa con logging en vez de con print y depurar con puntos de interrupción en lugar de adivinar.
Fundamentos de la Programación
Módulo 1: Introducción a la Programación
- ¿Qué es la programación?
- Historia de la programación
- Lenguajes de programación
- Entornos de desarrollo
- Del problema al algoritmo
Módulo 2: Conceptos Básicos
- Variables y tipos de datos
- Operadores y expresiones
- Entrada y salida de datos
- Conversión de tipos y validación de datos
Módulo 3: Estructuras de Control
Módulo 4: Funciones y Procedimientos
- Definición y uso de funciones
- Parámetros y retorno de valores
- Ámbito de variables
- Descomponer un programa en funciones
- Funciones como valores: lambda y orden superior
Módulo 5: Estructuras de Datos
- Listas y arreglos
- Cadenas de caracteres
- Diccionarios y conjuntos
- Tuplas y estructuras anidadas
- Guardar datos en archivos: texto, CSV y JSON
Módulo 6: Algoritmos Básicos
Módulo 7: Objetos y Organización del Código
- De los datos a los objetos: clases e instancias
- Atributos, métodos y constructor
- Colecciones de objetos
- Módulos, paquetes e importaciones
Módulo 8: Buenas Prácticas y Herramientas
- Documentación y comentarios
- Depuración y manejo de errores
- Control de versiones
- Pruebas automatizadas
- Estilo, legibilidad y refactorización
