Por Jose R. Zapata
Ultima actualización: 15/Ago/2026
Objetivo
Escribir funciones de Python relacionadas con su proyecto, aplicando buenas prácticas (nombres descriptivos, type hints, docstrings), verificando la calidad de código con pre-commit (ruff + mypy), y cubriéndolas con pruebas unitarias (pytest) antes de integrarlas mediante un Pull Request.
Criterio de éxito: un módulo src/.../funciones_<su_tema>.py con al menos 3 funciones propias (tipadas y documentadas) relacionadas con su dataset, un módulo tests/.../test_funciones_<su_tema>.py con pruebas unitarias que pasen, pre-commit corriendo sin errores sobre los archivos nuevos, y un Pull Request abierto con el trabajo.
Prerequisitos
- Ambiente configurado (Práctica — Configuración del entorno de desarrollo).
- Flujo de Git/GitHub ya practicado: crear rama desde un issue, commits con Conventional Commits, y Pull Request (Práctica — Primer repositorio, commit y push, Pull Request).
- Repositorio de su proyecto creado a partir de data-science-project-template, con el dataset de E1 ya descargado (ver práctica de la sesión de esta mañana en GitHub Projects/Issues).
- Haber leído: Calidad de Código y Pre-commit, Funciones en Python, Pruebas Unitarias en Python.
Paso 1 — Crear una rama de trabajo
Como en la práctica de esta mañana, cree una rama:
git checkout main
git pull origin main
git checkout -b feature/funciones-datos
Paso 2 — Preparar el ambiente y pre-commit
Active el ambiente virtual del proyecto e instale/actualice dependencias:
source .venv/bin/activate
uv sync
El proyecto (generado desde el template) ya trae .pre-commit-config.yaml, instale los hooks localmente:
uv run pre-commit install
Verifique que existen los archivos de configuración de calidad de código (los trae el template):
.pre-commit-config.yaml.code_quality/ruff.toml.code_quality/mypy.ini
Si no existen en su repositorio, revise Calidad de Código y Pre-commit para crearlos antes de continuar.
Paso 3 — Escribir las funciones
Cree un archivo de funciones dentro de src/ (por ejemplo src/limpieza/funciones_datos.py) con al menos 3 funciones propias relacionadas con su dataset de E1 (por ejemplo: limpiar una columna, calcular una métrica descriptiva, detectar outliers, normalizar una variable, validar un rango de valores, etc.).
Cada función debe tener:
- Nombre descriptivo (verbo + qué hace).
- Type hints en parámetros y valor de retorno.
- Docstring (
Args,Returns, y opcionalmenteExamples) siguiendo el estilo visto en Funciones en Python.
Ejemplo de referencia (no copiar literal — adapte la idea a su propio dataset):
import pandas as pd
def calcular_valores_nulos_por_columna(datos: pd.DataFrame) -> pd.Series:
"""Calcula el número de valores nulos por columna de un DataFrame.
Args:
datos (pd.DataFrame): DataFrame de entrada.
Returns:
pd.Series: Conteo de valores nulos por columna.
Examples:
>>> import pandas as pd
>>> df = pd.DataFrame({"a": [1, None, 3], "b": [None, None, 3]})
>>> calcular_valores_nulos_por_columna(df)["a"]
1
"""
return datos.isna().sum()
pandas — depende de su dataset y de lo que sus funciones necesiten (puede ser sobre listas, diccionarios, arreglos de numpy, etc.). Lo importante es que las funciones sean relevantes para su proyecto.Paso 4 — Verificar calidad de código con pre-commit
Ejecute pre-commit sobre los archivos que creó (o sobre todo el repositorio) y corrija lo que reporte ruff (lint + format) y mypy (static typing) hasta que pase sin errores:
uv run pre-commit run --files src/limpieza/funciones_datos.py
uv run pre-commit run --all-files
Si ruff reporta errores de formato o lint, en general puede corregirlos automáticamente agregando --fix a la configuración ya definida en .pre-commit-config.yaml (ver Calidad de Código y Pre-commit); los errores de mypy (tipado) debe corregirlos usted mismo ajustando las anotaciones de tipo.
Paso 5 — Escribir pruebas unitarias
Cree el archivo de pruebas correspondiente en tests/ (ver la convención de Pruebas Unitarias en Python: un directorio tests espejo de src, con __init__.py, y archivos/funciones que empiecen con test_).
Para cada una de sus 3+ funciones, escriba al menos:
- Una prueba con un caso “normal” (entrada típica, salida esperada conocida).
- Una prueba de caso límite o de error (ej. entrada vacía, valores inválidos, división por cero, etc. — lo que aplique a su función).
import pandas as pd
from src.limpieza.funciones_datos import calcular_valores_nulos_por_columna
def test_calcular_valores_nulos_por_columna() -> None:
"""Caso normal: DataFrame con nulos conocidos."""
df = pd.DataFrame({"a": [1, None, 3], "b": [None, None, 3]})
resultado = calcular_valores_nulos_por_columna(df)
assert resultado["a"] == 1
assert resultado["b"] == 2
def test_calcular_valores_nulos_por_columna_sin_nulos() -> None:
"""Caso límite: DataFrame sin valores nulos."""
df = pd.DataFrame({"a": [1, 2, 3]})
resultado = calcular_valores_nulos_por_columna(df)
assert resultado["a"] == 0
Ejecute las pruebas y confirme que todas pasan:
uv run pytest -v --cov=src
Paso 6 — Commit, push y Pull Request
Haga commits siguiendo Conventional Commits (uno para las funciones, otro para las pruebas, o combinados si el cambio es pequeño):
git add src/limpieza/funciones_datos.py
git commit -m "feat: agregar funciones de procesamiento de datos"
git add tests/limpieza/test_funciones_datos.py
git commit -m "test: agregar pruebas unitarias para funciones de procesamiento de datos"
pre-commit está instalado (Paso 2), se ejecutará automáticamente en cada git commit y puede bloquear el commit si encuentra errores de calidad de código — corríjalos y vuelva a intentar el commit.Suba la rama y abra el Pull Request:
git push origin feature/funciones-datos
Abra el Pull Request en GitHub enlazando el issue del Paso 1 en la descripción (ver Pull Request — Qué es y buenas prácticas).
Checklist de pasos
- rama creada
-
pre-commitinstalado (pre-commit install) en el repositorio del proyecto - Al menos 3 funciones propias en
src/, relacionadas con el dataset, con type hints + docstrings -
pre-commit runpasa sin errores sobre los archivos nuevos (ruff lint, ruff format, mypy) - Archivo de pruebas en
tests/con al menos 1 caso normal + 1 caso límite por función -
pytestcorre y todas las pruebas pasan - Commits siguiendo Conventional Commits
- Pull Request abierto, enlazado al issue
Referencias
- Calidad de Código y Pre-commit
- Funciones en Python
- Pruebas Unitarias en Python
- Conventional Commits
- Pull Request — Qué es y buenas prácticas
- data-science-project-template (GitHub)
- Documentación oficial de pytest
- Documentación oficial de Ruff