7.2.2 Procesamiento de datos
En el mundo real, los ficheros suelen venir "sucios": líneas vacías inesperadas, espacios extra, codificaciones extrañas o formatos inconsistentes. El procesamiento de datos es el arte de transformar ese caos en estructuras utilizables.
1️⃣ El Pipeline de Procesamiento
Un buen procesador de archivos sigue siempre un esquema mental claro.
- Iteración → recorrer el fichero.
- Limpieza (Sanitización) → eliminar ruido.
- Filtrado → descartar lo irrelevante.
- Transformación → convertir tipos.
- Almacenamiento o cálculo → usar el dato.
Este flujo es clave. Saltarse pasos genera errores silenciosos.
🟩 Iteración eficiente
Siempre que sea posible, recorre línea a línea:
with open("datos.txt", "r", encoding="utf-8") as f:
for linea in f:
print(linea)
Ventaja:
- No cargas todo en memoria.
- Puedes procesar archivos grandes.
🟦 Limpieza básica: strip()
Al leer de un fichero, las líneas incluyen \n.
linea = " Ana , 25 \n"
print(linea.strip())
Resultado:
Ana , 25
strip() elimina espacios y saltos al inicio y al final.
También existen:
lstrip()→ izquierdarstrip()→ derecha
🟨 Filtrado inteligente
No todo lo que se lee es útil.
Ejemplo típico:
if not linea or linea.startswith("#"):
continue
- Ignorando líneas vacías.
- Ignorando comentarios.
Este patrón es muy común en logs y configuraciones.
🟧 Transformación de tipos
El fichero solo contiene texto. Si necesitas números, debes convertirlos.
partes = linea.split("|")
id_item = int(partes[0])
valor = float(partes[1])
Si no conviertes, todo será string y los cálculos fallarán.
🟥 Pipeline completo ejemplo
def procesar_log(ruta):
datos_limpios = []
with open(ruta, "r", encoding="utf-8") as f:
for linea in f:
linea = linea.strip()
if not linea or linea.startswith("#"):
continue
partes = linea.split("|")
id_item = int(partes[0].strip())
valor = float(partes[1].strip())
datos_limpios.append({
"id": id_item,
"valor": valor
})
return datos_limpios
Aquí vemos claramente las 5 fases del procesamiento.
2️⃣ Problemas comunes en datos reales
🟩 Separadores inconsistentes
A veces el fichero mezcla espacios:
Ana , 25 , Madrid
Solución profesional:
datos = [d.strip() for d in linea.split(",")]
Esto limpia cada elemento individualmente.
🟦 Valores faltantes
Ejemplo:
Ana|25
Luis|
Si haces:
int(partes[1])
Fallará.
Solución defensiva:
if partes[1]:
edad = int(partes[1])
else:
edad = None
🟨 Tipos incorrectos
Si esperas un número y aparece texto:
Juan|veinte
Sin control, el programa se detiene.
🟧 Procesamiento defensivo
def extraer_puntos(linea):
try:
nombre, puntos = linea.split(":")
return int(puntos)
except ValueError:
print(f"Línea corrupta ignorada: {linea}")
return None
Esto permite que el programa continúe.
3️⃣ Procesamiento eficiente y memoria
No siempre necesitamos guardar todo.
Ejemplo incorrecto:
datos = []
for linea in f:
datos.append(linea)
Si el archivo es enorme, puede consumir demasiada RAM.
🟩 Cálculo incremental
Si solo quieres sumar valores:
total = 0
with open("ventas.txt", "r", encoding="utf-8") as f:
for linea in f:
total += float(linea.strip())
print(total)
Aquí nunca almacenamos todas las líneas.
🟦 Generadores (nivel intermedio)
En lugar de listas intermedias:
valores = (float(l.strip()) for l in f)
Esto genera valores “sobre la marcha”.
4️⃣ Validación básica antes de procesar
Antes de procesar un fichero grande conviene:
- Verificar que no esté vacío.
- Verificar número mínimo de columnas.
- Manejar excepciones.
- Confirmar formato esperado.
Ejemplo simple:
if "|" not in linea:
continue
✅ Buenas prácticas en procesamiento
- Limpiar siempre antes de transformar.
- Convertir tipos lo antes posible.
- Manejar errores de conversión.
- No asumir que el dato es perfecto.
- Evitar cargar todo si no es necesario.
- Separar lectura de lógica de negocio.
🧪 Ejercicios prácticos – Aditoría del sistema
Después de restaurar el sistema (7.1.1), el equipo necesita una auditoría. El sistema ya arranca, pero los datos siguen “brutos” y hay que convertirlos en información útil.
Dispones de estos ficheros: 👉 Descárgalos aquí
eventos_brutos.txt→ eventos sin limpiar del sistemaconfiguracion_sistema.txt→ configuración activa con parámetros legacyaccesos_usuarios.txt→ registros de acceso con duplicados e inconsistencias
Tu misión es limpiar, validar, transformar y generar informes.
🟢 Fase 1 – Limpieza del registro de eventos
🟩 Ejercicio 1 – Normalización del registro (eventos_brutos.txt)
El registro está lleno de ruido (comentarios, líneas vacías y espacios irregulares).
Crea un archivo eventos_limpios.txt que:
- Ignore líneas que empiecen por
# - Ignore líneas vacías
- Elimine espacios sobrantes en cada campo
- Guarde las líneas con el formato exacto:
fecha|nivel|usuario|mensaje
Ejemplo de salida:
2026-02-16|INFO|admin|inicio del sistema
🟦 Ejercicio 2 – Resumen rápido de severidad
El equipo necesita una visión global del estado del sistema.
Recorre eventos_brutos.txt y calcula (sin cargar todo en memoria):
- Total de eventos válidos
- Total de eventos
INFO - Total de eventos
DEBUG - Total de eventos
ERROR
Muestra el resultado por pantalla.
🟡 Fase 2 – Validación de integridad del log
🟨 Ejercicio 3 – Detección de eventos incompletos
No se puede auditar un sistema con eventos corruptos.
En eventos_brutos.txt, cuenta cuántos registros tienen problemas como:
- Menos de 4 campos separados por
| - El campo
usuariovacío
Muestra por pantalla:
- Total de eventos incompletos
- Ejemplos de líneas descartadas (solo 2 o 3, no todas)
🟧 Ejercicio 4 – Archivo de incidentes críticos
El equipo de seguridad solo quiere el listado de incidentes (errores).
Crea un archivo incidentes.txt que contenga solo los mensajes de los eventos ERROR (sin fecha, sin nivel, sin usuario), por ejemplo:
fallo autenticacion
error en base de datos
timeout conexion
🔵 Fase 3 – Reconstrucción de la configuración real
🟥 Ejercicio 5 – Cargar configuración activa (configuracion_sistema.txt)
La configuración está mezclada con comentarios y parámetros legacy. Construye un diccionario en memoria con los valores reales:
- Ignora comentarios
#y líneas vacías - Extrae pares
clave = valor - Aplica
strip()a ambos lados
Resultado esperado (ejemplo):
{
"modo": "produccion",
"max_usuarios": "100",
"timeout": "30",
"debug": "true",
...
}
🟪 Ejercicio 6 – Conversión de tipos (configuración lista para usar)
Ahora el equipo quiere usar esa configuración en el programa, por tanto necesita tipos correctos:
- Convertir valores numéricos a
int - Convertir
true/false(ignorando mayúsculas/minúsculas) a booleanos realesTrue/False
Muestra el diccionario final ya tipado.
🔴 Fase 4 – Auditoría de accesos y cuentas
🟫 Ejercicio 7 – Duplicados en el sistema (accesos_usuarios.txt)
El equipo sospecha que hay usuarios repetidos.
En accesos_usuarios.txt:
- Ignora comentarios y líneas vacías
- Detecta usuarios que aparecen más de una vez
- Muestra por pantalla el listado de usuarios duplicados
🟪 Ejercicio 8 – Lista de usuarios activos válidos
Necesitamos generar una lista real de usuarios activos.
Filtra accesos_usuarios.txt y quédate solo con:
- Usuarios cuyo campo
activoseaTrue - Registros completos (sin campos vacíos)
Muestra por pantalla la lista final.
🟣 Fase Final – Informe consolidado para auditoría
🟥 Ejercicio 9 – Generar informe del sistema
Crea un archivo informe_sistema.txt con:
- Total de eventos válidos
- Total de errores (
ERROR) - Total de eventos incompletos descartados
- Total de usuarios activos válidos
- Usuarios duplicados detectados
Cada dato en una línea con un formato claro, por ejemplo:
Eventos validos: 7
Errores: 3
Eventos incompletos: 1
Usuarios activos validos: 2
Usuarios duplicados: admin