Saltar al contenido
Volver al inicio 100 Días de Código en Python — Día 98: Proyecto de portafolio — Automatiza algo de tu vida

100 Días de Código en Python — Día 98: Proyecto de portafolio — Automatiza algo de tu vida

Nivel: Grado décimo Área: Tecnología e Informática Modalidad: Tutorial práctico Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 98, proyecto de portafolio profesional (categoría Python Automation).

Este tutorial adapta pedagógicamente el Día 98. La sección 📝 Contenido original del curso proviene del único archivo de la carpeta: dia98-tarea17.md (enunciado, ideas de inspiración, la historia de la instructora y la pregunta de reflexión, en inglés; aquí traducido). El curso no ofrece guía ni solución, y la tarea es abierta: cada estudiante automatiza algo distinto. Este tutorial ofrece un método para encontrar qué automatizar, un ejemplo completo verificado (organizar una carpeta) como modelo de buenas prácticas, criterios de seguridad y ética, retos 🟢🟡🟠🔴, un proyecto extra y la etapa 17 de Mi Portafolio Profesional. Todo eso es creación de esta adaptación.

Nota sobre las verificaciones: el 28 de septiembre de 2026, con Python 3.14, se ejecutó el organizador de la sección 4 en una carpeta temporal con 6 archivos de prueba: en modo simulación no movió nada y listó los 6 movimientos; en modo real los movió a Audio/, Comprimidos/, Documentos/, Imagenes/ y Otros/; un archivo con nombre repetido se guardó como foto (1).JPG sin sobrescribir el existente; y una segunda ejecución no hizo ningún movimiento.


Tabla de contenidos

  1. La tarea: ¿cuándo te sientes un robot?
  2. Encontrar qué automatizar
  3. 📖 Principios de una buena automatización
  4. 📖 Ejemplo completo: organizar una carpeta de descargas
  5. 📖 Que se ejecute sola: programar tareas
  6. 🚀 Proyecto del día: construcción por versiones
  7. 🌟 Proyecto extra: el asistente del representante de curso
  8. 🏗️ Mi Portafolio Profesional — Etapa 17
  9. 🧩 Comprueba lo aprendido
  10. 🤖 Programar con apoyo de IA
  11. 🛠️ Observaciones sobre el material original
  12. 📋 Matriz de trazabilidad
  13. 📦 Evidencias de aprendizaje del Día 98

1. La tarea: ¿cuándo te sientes un robot?

(Fuente: dia98-tarea17.md)

📝 Contenido original del curso

Aprendiste sobre automatización con Python y Selenium. Es tu turno de ser creativo y automatizar algún aspecto de tu vida con lo que aprendiste.

Puede ser un aspecto de tu trabajo, tus tareas escolares, tu casa, tus quehaceres. Piensa en tu semana y en todo lo que haces con regularidad: ¿cuándo te sientes como un robot? ¿Qué trabajos te parecen tediosos y aburridos? ¿Se pueden automatizar?

Historias de inspiración:

  • Automatizar un correo a tu jefe para pedir un aumento cada 3 meses (en broma).
  • Automatizar tus luces para que se enciendan cuando tu teléfono esté dentro del radio de tu casa.
  • Organizar automáticamente los archivos de tu carpeta de descargas según su tipo.
  • Automatizar las reservas de tus clases en el gimnasio.
  • Automatizar la renovación de tus libros de la biblioteca.
  • Automatizar tu trabajo y los quehaceres de tu casa (enlaces a conversaciones de Reddit con ejemplos).

La historia de la instructora: tuvo un trabajo en un hospital en el que debía organizar los turnos de todos los médicos del departamento (día normal, día largo, noche), según cuándo querían tomar vacaciones y las necesidades de personal. Empezó en una hoja de Excel; al terminar, estaba totalmente automatizado con Python y los médicos podían ver una versión en vivo del cuadro de turnos para saber cuándo podían tomar días libres. "El código tomó una tarde escribirlo y me ahorra 3 horas por semana". (Más tiempo para ver Netflix y comer helado.)

Cuando termines, cuéntanos qué automatizaste: ¡quizá inspires a otro estudiante!

Pregunta de la tarea — Momento de reflexión: cómo abordaste el proyecto; qué fue difícil y qué fácil; cómo mejorarías; tu mayor aprendizaje; qué harías distinto.

Prerequisitos: archivos, carpetas y pathlib (Día 24); CSV, pandas y Excel (Día 25); correo con smtplib y fechas con datetime (Día 32); APIs (Días 33–38); Selenium (Días 48–53); excepciones (Día 30).


2. Encontrar qué automatizar

(Sección creada para esta adaptación.)

🔍 Antes de programar: el diario del robot

Durante 3 días, anota cada tarea repetitiva que haces en el computador o el celular:

Tarea ¿Cada cuánto? Minutos cada vez ¿Siempre los mismos pasos? ¿Datos de entrada claros?
Ordenar la carpeta de descargas Semanal 15 Sí Sí (los archivos)
Revisar si subieron notas a la plataforma Diario 5 Sí ¿Hay API o se necesita Selenium?
…

¿Vale la pena?

Un criterio simple: tiempo ahorrado al año frente a tiempo para programarlo.

Texto
Ahorro anual = minutos cada vez × veces por semana × 40 semanas (año escolar)
Ordenar descargas: 15 × 1 × 40 = 600 minutos = 10 horas al año

Si programarlo te toma 4 horas, vale la pena… y además aprendes. En el proyecto escolar, el aprendizaje también cuenta.

Buenos candidatos para grado décimo

Idea Herramientas Dificultad
Organizar descargas por tipo pathlib, shutil 🟢
Renombrar fotos por fecha (2026-09-28_001.jpg) pathlib, Pillow (fecha EXIF) 🟢
Recordatorio de tareas por correo cada domingo CSV + smtplib + programador de tareas 🟡
Resumen semanal de gastos o ahorros desde un Excel pandas, gráficos 🟡
Avisar si baja el precio de algo (con permiso del sitio) requests, Beautiful Soup (Día 47) 🟠
Cuadro de turnos del aseo del salón (como los turnos de la instructora) listas, reglas, CSV 🟠

¿Puedo? ¿Debo?

  • No automatices tareas escolares que deben ser tu trabajo (escribir un ensayo, responder un quiz): eso es deshonestidad académica.
  • No automatices plataformas cuyos términos lo prohíben (muchas reservas, redes sociales y plataformas educativas). Revisa los términos (Día 93).
  • No uses credenciales de otras personas ni guardes contraseñas en el código.
  • Nunca automatices mensajes masivos no solicitados (spam).

3. 📖 Principios de una buena automatización

(Sección creada para esta adaptación.)

Un script que actúa solo puede causar daño solo: mover archivos equivocados, enviar 200 correos, borrar datos. Estos principios se aplican a cualquier automatización:

Principio Qué significa Cómo en Python
Modo simulación (dry run) Primero muestra lo que haría, sin hacerlo Parámetro simular=True por defecto
No destruir Mover o copiar antes que borrar; no sobrescribir Comprobar exists(); nombres libres
Idempotencia Ejecutarlo dos veces no causa daño ni duplicados Verificado: la 2.ª ejecución no mueve nada
Registro (log) Guardar qué hizo y cuándo Módulo logging o un archivo de texto
Configuración fuera del código Rutas, horarios y correos en un archivo config.json o .env
Fallar con elegancia Un error en un archivo no detiene todo try/except por elemento, y registrar el error

4. 📖 Ejemplo completo: organizar una carpeta de descargas

(Sección creada para esta adaptación, desarrollando una de las ideas del enunciado. Verificado en una carpeta temporal.)

Este ejemplo se muestra completo porque es el modelo de buenas prácticas; tu proyecto debe ser otro (o este mismo muy ampliado, con los retos).

Python
import shutil
from pathlib import Path

CATEGORIAS = {
    "Imagenes": {".jpg", ".jpeg", ".png", ".gif"},
    "Documentos": {".pdf", ".docx", ".txt", ".xlsx", ".pptx"},
    "Audio": {".mp3", ".wav"},
    "Comprimidos": {".zip", ".rar"},
}

def categoria_de(archivo):
    extension = archivo.suffix.lower()
    for nombre, extensiones in CATEGORIAS.items():
        if extension in extensiones:
            return nombre
    return "Otros"

def destino_libre(destino):
    if not destino.exists():
        return destino
    n = 1
    while True:
        candidato = destino.with_name(f"{destino.stem} ({n}){destino.suffix}")
        if not candidato.exists():
            return candidato
        n += 1

def organizar(carpeta, simular=True):
    movimientos = []
    for archivo in Path(carpeta).iterdir():
        if not archivo.is_file():
            continue
        subcarpeta = Path(carpeta) / categoria_de(archivo)
        destino = destino_libre(subcarpeta / archivo.name)
        movimientos.append((archivo.name, destino.relative_to(carpeta)))
        if not simular:
            subcarpeta.mkdir(exist_ok=True)
            shutil.move(archivo, destino)
    return movimientos

Qué hace cada parte:

  • CATEGORIAS es configuración: agregar un tipo no requiere cambiar la lógica. Los conjuntos ({...}) hacen rápida la pregunta in.
  • .suffix.lower(): "foto.JPG" → ".jpg". Sin lower(), las fotos en mayúsculas terminarían en "Otros".
  • if not archivo.is_file(): continue: no mueve carpetas (incluidas las que el propio script crea).
  • destino_libre: si ya existe foto.JPG, usa foto (1).JPG, foto (2).JPG… (verificado). Nunca sobrescribe.
  • simular=True por defecto: para mover de verdad hay que pedirlo explícitamente.
  • mkdir(exist_ok=True): crea la subcarpeta si no existe, sin error si ya existe.
  • Devuelve la lista de movimientos: sirve para mostrarla, registrarla y probarla.

Uso recomendado:

Python
for origen, destino in organizar(r"C:\Users\TuUsuario\Downloads"):   # primero, simular
    print(f"{origen}  →  {destino}")
# Revisa la lista. Solo si está bien:
# organizar(r"C:\Users\TuUsuario\Downloads", simular=False)

⚠️ Errores frecuentes (y sustos reales)

Error Qué ocurre Solución
Ejecutar el script en su propia carpeta El script se mueve a sí mismo a "Otros" Probar en una carpeta de prueba; excluir el propio archivo (Path(__file__))
Probar directamente en la carpeta real Se desordenan archivos importantes Primero, carpeta de prueba con copias; luego simulación; luego real
Sobrescribir archivos Se pierde un archivo con el mismo nombre destino_libre
PermissionError Un archivo está abierto en otro programa try/except por archivo y registrar el error
Rutas con \ en cadenas normales "C:\Users\nuevo" interpreta \n como salto de línea Cadenas crudas r"..." o Path con /
Mover archivos que se están descargando Archivos a medio descargar (.crdownload, .part) Ignorar esas extensiones

5. 📖 Que se ejecute sola: programar tareas

(Sección creada para esta adaptación.)

Una automatización completa no necesita que tú la ejecutes. Opciones:

Opción Dónde Cómo
Programador de tareas de Windows Tu computador Crear una tarea básica que ejecute python ruta\script.py cada semana
cron Linux y macOS Una línea en crontab -e, por ejemplo cada domingo a las 18:00
Servicio en la nube (como en el Día 32) Internet Un servicio que ejecute scripts programados (revisa condiciones de edad y cuenta)
Un ciclo con time.sleep Tu computador Simple, pero el programa debe estar siempre abierto; no recomendado

Si el script se ejecuta solo, el registro es imprescindible: es la única forma de saber qué hizo mientras no mirabas.


6. 🚀 Proyecto del día: construcción por versiones

(Desarrolla la tarea dia98-tarea17.md. Las versiones son una propuesta de esta adaptación.)

Problema

Automatizar una tarea repetitiva real de tu vida.

Contexto

Tu propio diario del robot (sección 2).

Objetivo

Un script (o conjunto de scripts) que ahorre tiempo de verdad, sea seguro de ejecutar y esté documentado para que otra persona pueda usarlo.

Requisitos funcionales

  1. Resuelve una tarea identificada en tu diario del robot, con el cálculo de ahorro.
  2. Tiene modo simulación (o, si no aplica, un modo de prueba con datos ficticios).
  3. Registra lo que hace.
  4. Se ejecuta de forma programada o con un solo comando.

Restricciones técnicas

  • Cumple los principios de la sección 3.
  • Configuración en un archivo aparte; credenciales en variables de entorno.
  • Respeta la sección "¿Puedo? ¿Debo?".

Planificación

  1. Diario del robot (3 días). 2. Elegir y calcular el ahorro. 3. Describir los pasos manuales exactos. 4. Entradas y salidas. 5. Qué puede salir mal. 6. Diseñar funciones. 7. Implementar con simulación. 8. Probar con datos de prueba. 9. Ejecutar de verdad. 10. Programarlo y medir el ahorro real.

Construcción paso a paso

  • Versión 1 — Pasos manuales en papel: escribe, como receta, lo que haces a mano.
  • Versión 2 — Simulación: el script muestra lo que haría.
  • Versión 3 — Acción real sobre datos de prueba.
  • Versión 4 — Robustez: errores por elemento, idempotencia, registro.
  • Versión 5 — Configuración y programación.
  • Versión final: README.md (qué hace, cómo configurarlo, cómo deshacer), diario y "cuéntanos qué automatizaste" (como pide el curso): comparte con tu clase.

Pruebas (para el ejemplo de la sección 4; adapta a tu proyecto)

# Caso Resultado esperado
1 Simulación en una carpeta con 6 archivos Lista de 6 movimientos; la carpeta no cambia
2 Ejecución real Cada archivo en su subcarpeta
3 foto.JPG ya existe en Imagenes/ El nuevo queda como foto (1).JPG
4 Segunda ejecución Ningún movimiento
5 Extensión en mayúsculas Categoría correcta
6 Archivo sin extensión "Otros"
7 Archivo abierto en otro programa Error registrado; los demás se mueven
Python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as carpeta:
    carpeta = Path(carpeta)
    (carpeta / "tarea.pdf").write_text("x")
    assert organizar(carpeta) == [("tarea.pdf", Path("Documentos/tarea.pdf"))]
    assert (carpeta / "tarea.pdf").exists()          # la simulación no movió nada

tempfile.TemporaryDirectory() crea una carpeta que se borra sola al terminar: perfecta para probar sin riesgo.

🧪 Prueba y depuración

Python
import os
for nombre in os.listdir("C:/Users/Ana/Downloads"):
    if nombre.endswith(".jpg"):
        os.rename(nombre, "Imagenes/" + nombre)

Encuentra cinco problemas: os.rename(nombre, ...) usa rutas relativas a la carpeta actual, no a Descargas; la carpeta Imagenes puede no existir; .JPG en mayúsculas se ignora; si ya existe un archivo con ese nombre, falla (o en otros sistemas, lo sobrescribe); y no hay simulación ni registro. (Además, la ruta con el nombre de una persona está escrita en el código.)

⭐ Extensión del proyecto

  • 🟢 Reto 1 — Aplicación: agrega un archivo de registro con fecha y hora de cada movimiento (logging).
  • 🟡 Reto 2 — Ampliación: función deshacer(registro) que devuelva cada archivo a su lugar original usando el registro.
  • 🟠 Reto 3 — Desafío: mover a "Antiguos" los archivos que no se han abierto en 90 días (archivo.stat().st_mtime y datetime).
  • 🔴 Reto 4 — Pensamiento computacional: inspirado en la historia de la instructora, genera el cuadro de turnos del aseo del salón para un periodo: cada estudiante (alias) debe tener un número parecido de turnos, nadie dos días seguidos, y se respetan ausencias conocidas. Diseña las reglas, cómo comprobar que se cumplen y qué hacer si es imposible cumplirlas todas.

7. 🌟 Proyecto extra: el asistente del representante de curso

(Proyecto creado para esta adaptación; no existe en el curso original.)

Situación

El representante del curso pasa cada domingo 30 minutos armando el mensaje de la semana: fechas de entregas, evaluaciones y actividades, a partir de lo que los docentes anuncian.

Requisitos

  1. Una hoja de cálculo o CSV compartido con: materia, actividad, fecha, tipo (tarea, evaluación, evento).
  2. Un script que genere, cada domingo, un mensaje ordenado por fecha con las actividades de los próximos 7 días, resaltando evaluaciones.
  3. El mensaje se guarda como texto listo para copiar (o se envía por correo institucional, con autorización).

Decisiones que debes tomar (y justificar)

  • ¿Qué pasa con actividades sin fecha o con fechas mal escritas?
  • ¿Cómo evitas que el mensaje se vuelva demasiado largo?

Casos de prueba

  • Una actividad del próximo lunes aparece; una de dentro de 10 días, no.
  • Una fecha inválida se reporta sin detener el programa.

8. 🏗️ Mi Portafolio Profesional — Etapa 17

(Proyecto integrador creado para esta adaptación; etapas anteriores en los Días 82 a 97.)

Etapa 17 (hoy):

  1. Repositorio de tu automatización con config.example.json, pruebas con carpetas o datos temporales y README.md con: el problema, el cálculo de ahorro, cómo ejecutarlo en modo simulación y cómo deshacerlo.
  2. Medición real: después de una semana de uso, anota el tiempo ahorrado.
  3. DIARIO.md del Día 98 y ficha en proyectos.json.

9. 🧩 Comprueba lo aprendido

Conceptuales

  1. ¿Qué es el modo simulación y por qué debe ser el comportamiento por defecto?
  2. ¿Qué significa que un script sea idempotente? Da un ejemplo de uno que no lo es.
  3. ¿Por qué el registro es imprescindible en una tarea programada?
  4. Menciona dos tareas que no deberías automatizar y por qué.

Análisis de código

Python
Path("informe.final.PDF").suffix.lower()
Path("informe.final.PDF").stem

¿Qué devuelven?

Predicción

Si en Imagenes/ ya existen foto.jpg y foto (1).jpg, ¿con qué nombre guarda destino_libre una nueva foto.jpg?

Depuración

"Ejecuté mi organizador y mi script organizar.py desapareció." ¿Dónde está y cómo lo evitas?

Modificación

Agrega la categoría "Codigo" para .py, .html, .css y .js. ¿Cuántas líneas de la lógica cambiaste?

Creación

Escribe ahorro_anual(minutos, veces_por_semana, semanas=40) que devuelva las horas ahorradas al año, y úsala para priorizar tu diario del robot.


10. 🤖 Programar con apoyo de IA

Ciclo de trabajo: formula el problema → inténtalo tú primero → consulta a la IA sobre un punto concreto → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.

Actividad 1 — Ideas, no código. Describe tu semana (sin datos personales) y pide a una IA 10 ideas de automatización. Evalúa cada una con la tabla de la sección 2 y con "¿Puedo? ¿Debo?".

Actividad 2 — Revisión de riesgos. Antes de ejecutar un script que una IA te sugiera y que mueva, borre o envíe algo, pídele que explique qué hace cada línea y ejecútalo primero en una carpeta temporal. Nunca ejecutes a ciegas código que modifica tus archivos.

Actividad 3 — Documentación. Pregunta la diferencia entre shutil.move, os.rename y Path.rename. Compruébalo en la documentación de Python y anota cuál usas y por qué.

Declara el uso: sección "Uso de IA" en el README.md.


11. 🛠️ Observaciones sobre el material original

Archivo Observación Tratamiento
dia98-tarea17.md Tarea totalmente abierta Sección 2: método para encontrar y priorizar qué automatizar
dia98-tarea17.md Algunas ideas (reservas de gimnasio, correos automáticos al jefe) pueden violar términos de uso o ser inapropiadas "¿Puedo? ¿Debo?" en la sección 2
dia98-tarea17.md Menciona "schoolwork" como algo automatizable Se aclara: automatizar la gestión de tareas sí; hacer las tareas por ti, no
dia98-tarea17.md Enlaza conversaciones de Reddit como inspiración Se conservan como referencia; contenido de terceros no verificado
dia98-tarea17.md La historia de los turnos del hospital Inspira el reto 4 (turnos del aseo)

12. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
Automatizar un aspecto de tu vida con Python/Selenium dia98-tarea17.md Secciones 2 y 3 Automatización personal Retos 1 a 3 Secciones 6 y 8
¿Cuándo te sientes un robot? Tareas tediosas dia98-tarea17.md Sección 2 (diario del robot) Automatización personal — Sección 6
Idea: organizar descargas por tipo de archivo dia98-tarea17.md Sección 4 — Retos 1 a 3 Sección 6 (pruebas)
Otras ideas: luces, gimnasio, biblioteca, correos dia98-tarea17.md Sección 2 (ética y viabilidad) — — —
Historia de los turnos del hospital dia98-tarea17.md Sección 2 (ahorro de tiempo) — Reto 4 —
Compartir qué automatizaste dia98-tarea17.md Sección 6 (versión final) — — Sección 8
Momento de reflexión dia98-tarea17.md Sección 6 (versión final) Pregunta de reflexión — Sección 8
(No existe en el curso original) — Simulación, idempotencia, registro, tareas programadas — Asistente del representante Sección 7

13. 📦 Evidencias de aprendizaje del Día 98

  • El diario del robot (3 días) y el cálculo de ahorro.
  • El script funcionando: salida de la simulación y registro de una ejecución real.
  • Pruebas con carpetas o datos temporales.
  • La medición del tiempo ahorrado tras una semana.
  • DIARIO.md del Día 98 y ficha en el portafolio.
  • Cuaderno de errores: script que se mueve a sí mismo, rutas relativas, extensiones en mayúsculas, sobrescritura, PermissionError, \n en rutas de Windows, archivos a medio descargar.