SolveConPython

Python Reto #23 — Pipeline ETL simple (leer → limpiar → validar → exportar)

Nivel: Intermedio+
Tema: ETL, CSV, validación, normalización, errores por fila, exportación, tests con pytest
Objetivo: Construir un mini pipeline de datos: leer un CSV “sucio”, limpiar y validar filas, separar válidas e inválidas, y exportar resultados.

Enunciado

Crea una función llamada:

etl_simple(ruta_entrada, ruta_salida_ok, ruta_salida_error)

que:

  1. Reciba tres rutas (strings):
    • ruta_entrada: CSV de entrada con cabecera
    • ruta_salida_ok: CSV de salida con filas válidas
    • ruta_salida_error: CSV de salida con filas inválidas + motivo
  2. Validación:
    • Si alguna ruta es NoneTypeError
    • Si alguna ruta no es strTypeError
    • Si ruta_entrada no existe → FileNotFoundError
  3. Debe procesar un CSV con estas columnas (cabecera obligatoria):
    • email
    • edad
    • pais
  4. Reglas de limpieza y validación por fila:
    • email: strip(), minúsculas; válido si contiene un solo @, sin espacios, y con . en el dominio
    • edad: strip(); válido si es entero entre 0 y 120 (incluidos)
    • pais: strip(); válido si no está vacío
  5. Salidas:
    • En ruta_salida_ok escribe las filas válidas con columnas: email,edad,pais (limpias)
    • En ruta_salida_error escribe filas inválidas con columnas: email,edad,pais,error donde error describe el motivo principal
  6. La función debe devolver un resumen:

{"ok": int, "error": int}

Nota: Si una fila tiene varios problemas, registra solo el primer error detectado para simplificar.

CSV de ejemplo (entrada)

usuarios.csv

email,edad,pais
USER@Email.com , 30 , España
bademail.com,25,México
ana@mail,22,Chile
luis@mail.com,200,Perú
maria@mail.com, ,Argentina
,40,Colombia
pedro@mail.com,40,

Salidas esperadas:

  • OK: solo filas válidas (email normalizado, edad limpia, país limpio)
  • ERROR: filas inválidas con explicación

Pistas

  1. Reutiliza el validador de email “simple” del Reto #11.
  2. Convierte edad con int(...) y valida rango.
  3. Para exportar CSV usa csv.DictWriter.
  4. Maneja archivos con newline="" para evitar líneas en blanco en Windows.

Solución explicada (paso a paso)

  1. Validar rutas y existencia del archivo de entrada.
  2. Leer con csv.DictReader.
  3. Por cada fila:
    • normalizar campos (strip, lower)
    • validar email → si falla, mandar a error
    • validar edad → si falla, mandar a error
    • validar país → si falla, mandar a error
    • si todo OK → escribir en salida OK
  4. Contar ok y error.
  5. Devolver resumen.

Ejecuta:

  • pytest -q

Variantes para subir de nivel (opcional)

  1. Acumular múltiples errores por fila (lista de errores)
  2. Normalizar país (por ejemplo, title case)
  3. Soportar separador ; como parámetro
  4. Generar un resumen por país adicional
  5. Registrar estadísticas por tipo de error

Lo que aprendiste

  • Diseño de un pipeline ETL realista
  • Validación por fila sin romper el proceso
  • Exportación de resultados limpios vs. errores
  • Tests con archivos temporales y lecturas CSV

Accede al código completo y a los tests en GitHub para ejecutar y modificar la solución localmente.

El siguiente reto recomendado: Reto #24 — Cache simple (memoization) para acelerar funciones: rendimiento + diseño limpio + tests.