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:
- Reciba tres rutas (strings):
ruta_entrada: CSV de entrada con cabeceraruta_salida_ok: CSV de salida con filas válidasruta_salida_error: CSV de salida con filas inválidas + motivo
- Validación:
- Si alguna ruta es
None→TypeError - Si alguna ruta no es
str→TypeError - Si
ruta_entradano existe →FileNotFoundError
- Si alguna ruta es
- Debe procesar un CSV con estas columnas (cabecera obligatoria):
emailedadpais
- Reglas de limpieza y validación por fila:
email:strip(), minúsculas; válido si contiene un solo@, sin espacios, y con.en el dominioedad:strip(); válido si es entero entre 0 y 120 (incluidos)pais:strip(); válido si no está vacío
- Salidas:
- En
ruta_salida_okescribe las filas válidas con columnas:email,edad,pais(limpias) - En
ruta_salida_errorescribe filas inválidas con columnas:email,edad,pais,errordondeerrordescribe el motivo principal
- En
- 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
- Reutiliza el validador de email “simple” del Reto #11.
- Convierte
edadconint(...)y valida rango. - Para exportar CSV usa
csv.DictWriter. - Maneja archivos con
newline=""para evitar líneas en blanco en Windows.
Solución explicada (paso a paso)
- Validar rutas y existencia del archivo de entrada.
- Leer con
csv.DictReader. - 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
- normalizar campos (
- Contar
okyerror. - Devolver resumen.
Ejecuta:
pytest -q
Variantes para subir de nivel (opcional)
- Acumular múltiples errores por fila (lista de errores)
- Normalizar país (por ejemplo, title case)
- Soportar separador
;como parámetro - Generar un resumen por país adicional
- 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.