Lección 29 de 29Módulo 6: Automatización y Mejores Prácticas

29. Mejores Prácticas y Siguientes Pasos

Testing, logging, versionado, deployment y carrera profesional

25 minutos

Has recorrido un camino increíble desde variables básicas hasta sistemas completos de automatización. En esta lección final consolidarás todo con testing, logging profesional, Git, deployment y el roadmap para continuar creciendo como analista de datos.

Testing: Asegura calidad desde el inicio

¿Por qué testing es crucial?

Sin tests, cada cambio en tu código puede romper funcionalidad existente sin que lo notes. Tests automáticos son tu red de seguridad.

Escenario real: Modificas tu función de cálculo de métricas. Sin tests, envías un reporte con números incorrectos a 50 stakeholders. Con tests, detectas el error antes de enviar nada.

pytest: Framework de testing moderno

# test_analytics.py
"""
Tests para funciones de analytics
"""

import pytest
import pandas as pd
import numpy as np
from analytics import calcular_metricas, limpiar_datos

def test_calcular_metricas_basico():
    """Test de cálculo de métricas con datos válidos"""
    # Arrange (preparar)
    df = pd.DataFrame({
        'fecha': ['2025-01-01', '2025-01-02'],
        'ventas': [1000, 1500],
        'cantidad': [10, 15]
    })

    # Act (ejecutar)
    resultado = calcular_metricas(df)

    # Assert (verificar)
    assert resultado['total_ventas'] == 2500
    assert resultado['promedio_ventas'] == 1250
    assert resultado['total_cantidad'] == 25

def test_calcular_metricas_con_datos_vacios():
    """Test manejo de DataFrame vacío"""
    df = pd.DataFrame()

    with pytest.raises(ValueError):
        calcular_metricas(df)

def test_limpiar_datos_elimina_nulos():
    """Test que limpieza elimina nulos correctamente"""
    df = pd.DataFrame({
        'producto': ['A', 'B', None, 'D'],
        'precio': [100, None, 300, 400]
    })

    resultado = limpiar_datos(df)

    assert len(resultado) == 2  # Solo filas completas
    assert resultado['producto'].isna().sum() == 0
    assert resultado['precio'].isna().sum() == 0

def test_limpiar_datos_elimina_duplicados():
    """Test eliminación de duplicados"""
    df = pd.DataFrame({
        'id': [1, 2, 2, 3],
        'valor': [100, 200, 200, 300]
    })

    resultado = limpiar_datos(df, columna_id='id')

    assert len(resultado) == 3  # Sin duplicados

# Ejecutar tests: pytest test_analytics.py
# Ver cobertura: pytest --cov=analytics test_analytics.py

Tests de integración

# test_integration.py
"""
Tests de integración end-to-end
"""

import pytest
from report_generator import ReportGenerator
from email_sender import EmailSender
import os

def test_generacion_reporte_completo(tmp_path):
    """Test que verifica generación completa de reportes"""
    # Usar directorio temporal para tests
    generator = ReportGenerator()

    # Generar PDF
    pdf_path = generator.generar_reporte_pdf()
    assert os.path.exists(pdf_path)
    assert os.path.getsize(pdf_path) > 0  # No está vacío

    # Generar Excel
    excel_path = generator.generar_reporte_excel()
    assert os.path.exists(excel_path)

    # Limpiar archivos de test
    os.remove(pdf_path)
    os.remove(excel_path)

@pytest.mark.skipif(
    not os.getenv('EMAIL_PASSWORD'),
    reason="Email credentials not configured"
)
def test_envio_email_funcional():
    """Test envío de email (solo si credenciales configuradas)"""
    sender = EmailSender()

    resultado = sender.enviar_email(
        destinatarios=['test@empresa.com'],
        asunto='Test Email',
        cuerpo_html='<p>Test</p>'
    )

    assert resultado == True

Logging profesional

Niveles de logging

import logging

# Configuración completa de logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('analytics.log'),
        logging.StreamHandler()  # También imprime en consola
    ]
)

logger = logging.getLogger(__name__)

# Niveles en orden de severidad
logger.debug("Información de debugging detallada")
logger.info("Información general del proceso")
logger.warning("Advertencia: algo inusual pero no crítico")
logger.error("Error: algo falló pero el programa continúa")
logger.critical("Error crítico: el programa debe detenerse")

# Ejemplo en función
def procesar_ventas(df):
    """Procesa dataframe de ventas"""
    logger.info(f"Procesando {len(df)} filas de ventas")

    try:
        resultado = calcular_total(df)
        logger.info(f"Total calculado: ${resultado:,.2f}")
        return resultado

    except Exception as e:
        logger.error(f"Error calculando total: {e}", exc_info=True)
        raise

Logging estructurado para producción

# logger_config.py
"""
Configuración avanzada de logging
"""

import logging
import logging.handlers
from datetime import datetime

def setup_logger(name='analytics', log_dir='/var/log/analytics'):
    """Configura logger con rotación de archivos"""
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)

    # Handler con rotación (max 10 MB, keep 5 backups)
    file_handler = logging.handlers.RotatingFileHandler(
        filename=f'{log_dir}/{name}.log',
        maxBytes=10*1024*1024,  # 10 MB
        backupCount=5
    )

    # Handler para errores críticos (email)
    smtp_handler = logging.handlers.SMTPHandler(
        mailhost=('smtp.gmail.com', 587),
        fromaddr='analytics@empresa.com',
        toaddrs=['admin@empresa.com'],
        subject='ERROR CRÍTICO en Analytics',
        credentials=('user', 'password'),
        secure=()
    )
    smtp_handler.setLevel(logging.ERROR)

    # Formato detallado
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - [%(levelname)s] - %(funcName)s:%(lineno)d - %(message)s'
    )
    file_handler.setFormatter(formatter)
    smtp_handler.setFormatter(formatter)

    logger.addHandler(file_handler)
    logger.addHandler(smtp_handler)

    return logger

Git: Control de versiones

Inicializar repositorio

# Estructura de proyecto para Git
analytics_project/
├── .gitignore           # Archivos a NO versionar
├── README.md            # Documentación del proyecto
├── requirements.txt     # Dependencias Python
├── .env.example         # Ejemplo de variables de entorno
├── src/
│   ├── __init__.py
│   ├── analytics.py
│   ├── report_generator.py
│   └── email_sender.py
├── tests/
│   └── test_analytics.py
├── data/                # NO versionar (agregar a .gitignore)
│   └── .gitkeep
└── reports/             # NO versionar
    └── .gitkeep

.gitignore esencial

# .gitignore
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
*.egg-info/

# Datos y reportes (NO versionar)
data/*.csv
data/*.xlsx
reports/*.pdf
reports/*.xlsx

# Credenciales (CRÍTICO - NO versionar)
.env
config/credentials.py
*.pem
*.key

# IDEs
.vscode/
.idea/
*.swp

# Logs
logs/
*.log

# Sistema operativo
.DS_Store
Thumbs.db

Workflow básico de Git

# Inicializar repositorio
git init

# Configurar usuario
git config user.name "Tu Nombre"
git config user.email "tu@email.com"

# Agregar archivos
git add src/
git add tests/
git add requirements.txt
git add README.md

# Primer commit
git commit -m "Initial commit: Analytics project structure"

# Crear repositorio remoto (GitHub/GitLab)
git remote add origin https://github.com/usuario/analytics-project.git
git push -u origin main

# Workflow diario
git add src/analytics.py              # Agregar cambios
git commit -m "Add: Función calcular ROI"  # Commit descriptivo
git push                               # Subir a remoto

# Ver cambios
git status                             # Estado actual
git log --oneline                      # Historial
git diff                               # Ver cambios sin commit

Virtual Environments: Aislamiento de dependencias

# Crear virtual environment
python3 -m venv venv

# Activar (Linux/Mac)
source venv/bin/activate

# Activar (Windows)
venv\Scripts\activate

# Instalar dependencias
pip install pandas numpy matplotlib seaborn

# Exportar dependencias
pip freeze > requirements.txt

# Instalar desde requirements.txt (nuevo environment)
pip install -r requirements.txt

# Desactivar
deactivate

requirements.txt ejemplo

# requirements.txt
pandas==2.1.4
numpy==1.26.2
matplotlib==3.8.2
seaborn==0.13.0
requests==2.31.0
beautifulsoup4==4.12.2
openpyxl==3.1.2
reportlab==4.0.7
python-dotenv==1.0.0
pytest==7.4.3
pytest-cov==4.1.0

Deployment: Llevar a producción

Opción 1: Servidor Linux (AWS EC2, DigitalOcean)

# 1. Conectar al servidor
ssh user@tu-servidor.com

# 2. Instalar Python y dependencias
sudo apt update
sudo apt install python3 python3-pip python3-venv

# 3. Clonar repositorio
git clone https://github.com/usuario/analytics-project.git
cd analytics-project

# 4. Crear virtual environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# 5. Configurar variables de entorno
cp .env.example .env
nano .env  # Editar con credenciales reales

# 6. Configurar cron
crontab -e
# Agregar: 0 8 * * * /home/user/analytics-project/venv/bin/python /home/user/analytics-project/src/daily_report.py

# 7. Verificar ejecución
python src/daily_report.py

Opción 2: Docker (recomendado para producción)

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

# Instalar dependencias
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copiar código
COPY src/ ./src/
COPY data/ ./data/

# Variables de entorno
ENV PYTHONUNBUFFERED=1

# Ejecutar script
CMD ["python", "src/daily_report.py"]
# docker-compose.yml
version: '3.8'

services:
  analytics:
    build: .
    volumes:
      - ./data:/app/data
      - ./reports:/app/reports
    env_file:
      - .env
    restart: unless-stopped

Roadmap: Siguientes pasos en tu carrera

Nivel 1: Junior Data Analyst (Donde estás ahora)

Has completado:

  • Python fundamentos
  • Pandas para manipulación de datos
  • Visualización con Matplotlib/Seaborn
  • Estadística aplicada
  • Web scraping y APIs
  • Automatización completa

Habilidades adquiridas:

  • Análisis exploratorio de datos (EDA)
  • Limpieza y transformación de datos
  • Creación de reportes automáticos
  • Visualizaciones profesionales
  • Scraping ético de datos

Salario estimado: $35,000 - $55,000 USD/año

Nivel 2: Data Analyst (6-12 meses)

Próximos pasos:

  1. SQL avanzado

    • Joins complejos
    • Window functions
    • CTEs y subqueries
    • Optimización de queries
    • Curso: "PostgreSQL for Data Analytics"
  2. Dashboards interactivos

    • Power BI o Tableau
    • Streamlit (Python)
    • Plotly Dash
    • Proyecto: Dashboard de KPIs en tiempo real
  3. Más estadística

    • Testing de hipótesis avanzado
    • Regresión múltiple
    • Series de tiempo
    • Causalidad vs correlación

Salario estimado: $55,000 - $75,000 USD/año

Nivel 3: Senior Data Analyst (1-2 años)

Especialización:

  1. Machine Learning aplicado

    • Scikit-learn
    • Predicción de churn
    • Scoring de propensión
    • Segmentación con clustering
    • Curso: "ML para Business Analytics"
  2. Big Data

    • Spark con PySpark
    • Análisis de millones de filas
    • Data pipelines con Airflow
  3. Cloud

    • AWS (S3, Redshift, Lambda)
    • Google Cloud (BigQuery)
    • Azure

Salario estimado: $75,000 - $110,000 USD/año

Nivel 4: Paths de especialización (2-3 años)

Opción A: Data Scientist

  • Deep learning
  • NLP avanzado
  • Modelos de forecasting
  • Salario: $110,000 - $150,000+

Opción B: Analytics Engineer

  • dbt (data build tool)
  • Data modeling
  • Data warehousing
  • Salario: $100,000 - $140,000+

Opción C: Business Intelligence Lead

  • Estrategia de datos
  • Arquitectura de BI
  • Liderazgo de equipo
  • Salario: $120,000 - $160,000+

Recursos para continuar aprendiendo

Plataformas de práctica

  1. Kaggle (kaggle.com)

    • Competencias de datos
    • Datasets reales
    • Notebooks compartidos
    • Aprende de expertos
  2. DataCamp (datacamp.com)

    • Cursos interactivos
    • Projects guiados
    • Certificaciones
  3. LeetCode SQL (leetcode.com/problemset/database/)

    • Práctica de SQL
    • Problemas de entrevista
    • Ranking global

Libros recomendados

  1. "Python for Data Analysis" - Wes McKinney

    • Por el creador de Pandas
    • Profundiza en Pandas
  2. "Storytelling with Data" - Cole Nussbaumer Knaflic

    • Visualización efectiva
    • Comunicación de insights
  3. "The Data Warehouse Toolkit" - Ralph Kimball

    • Modelado dimensional
    • Architecture patterns

Comunidades

  • Stack Overflow - Resuelve dudas técnicas
  • Reddit r/datascience - Discusiones y recursos
  • LinkedIn - Networking profesional
  • Meetups locales - Conecta presencialmente

Construye tu portfolio

Proyectos esenciales para mostrar

  1. Dashboard interactivo

    • Streamlit app pública
    • Deploy en Streamlit Cloud
    • GitHub repo bien documentado
  2. Análisis exploratorio completo

    • Jupyter Notebook en Kaggle
    • Dataset interesante (deportes, finanzas, etc.)
    • Insights accionables
  3. Sistema de automatización

    • Repositorio en GitHub
    • README detallado
    • Muestra tu código de este curso

GitHub profile profesional

# README.md del profile
# Tu Nombre - Data Analyst

Apasionado por convertir datos en insights accionables.

## Skills
- Python (Pandas, NumPy, Matplotlib, Seaborn)
- SQL (PostgreSQL, MySQL)
- Data Visualization (Tableau, Power BI, Plotly)
- Statistics & A/B Testing
- Web Scraping & APIs
- Automation & Reporting

## Proyectos destacados
1. [Sales Dashboard](link) - Dashboard interactivo de ventas
2. [Customer Churn Prediction](link) - ML model para predecir churn
3. [Automated Reporting System](link) - Sistema completo de reportes

## Contacto
- LinkedIn: [tu-perfil]
- Email: tu@email.com
- Portfolio: [tu-sitio]

Mensaje final

Has recorrido un camino increíble:

  • De cero programación a sistemas automatizados completos
  • De Excel manual a análisis con millones de filas
  • De reportes manuales a pipelines automáticas

Lo que tienes ahora:

  • Habilidades técnicas demandadas en el mercado
  • Portfolio con proyectos reales
  • Mentalidad de automatización y eficiencia
  • Fundamentos para crecer a roles senior

Recuerda:

  • El aprendizaje nunca termina - la tecnología evoluciona
  • Practica diariamente - la constancia vence al talento
  • Comparte tu conocimiento - enseñar solidifica lo aprendido
  • Construye en público - tu trabajo debe ser visible

Tu primer paso después del curso

  1. Esta semana: Aplica lo aprendido en tu trabajo actual
  2. Este mes: Construye un proyecto para tu portfolio
  3. Este trimestre: Postula a roles de Data Analyst
  4. Este año: Alcanza el siguiente nivel salarial

¡Felicidades por completar Python para Data Analytics!

Has invertido en la habilidad más valiosa del siglo XXI: convertir datos en decisiones. El camino apenas comienza, pero ahora tienes las herramientas para recorrerlo.

Nos vemos en la cumbre.

¿Completaste esta lección?

Marca esta lección como completada. Tu progreso se guardará en tu navegador.