pd_run_report.py en Python
Un reporte de pandas de punta a punta: parsear, limpiar, derivar, agrupar y clasificar.
from io import StringIO
import pandas as pd
RAW = """day,lang,chars,seconds,errors
2026-07-20,python,1820,60.0,4
2026-07-20,rust,1510,60.0,9
2026-07-21,python,1980,60.0,2
2026-07-21,sql,1240,60.0,1
2026-07-22,python,2050,60.0,3
2026-07-22,rust,1660,60.0,5
2026-07-28,css,980,45.0,7
2026-07-29,python,2110,60.0,1
"""
def cargar(texto):
"""Lee el export y le da a cada columna su tipo real."""
return pd.read_csv(
StringIO(texto),
parse_dates=["day"],
dtype={"lang": "category", "chars": "int32", "errors": "int16"},
)
def derivar(tabla):
return tabla.assign(
wpm=lambda f: (f["chars"] / 5) / (f["seconds"] / 60),
exactitud=lambda f: (1 - f["errors"] / f["chars"]) * 100,
semana=lambda f: f["day"].dt.isocalendar().week,
)
def por_lenguaje(tabla):
return (tabla
.groupby("lang", observed=True)
.agg(intentos=("wpm", "size"),
mejor_wpm=("wpm", "max"),
media_wpm=("wpm", "mean"),
exactitud=("exactitud", "mean"))
.sort_values("media_wpm", ascending=False)
.round(1))
def principal():
intentos = cargar(RAW).pipe(derivar)
print("intentos por lenguaje")
print(por_lenguaje(intentos).to_string())
print("\nwpm medio semanal")
semanal = (intentos.set_index("day")["wpm"]
.resample("W")
.mean()
.round(1)
.dropna())
print(semanal.to_string())
print("\npromedio movil de tres intentos, solo python")
solo_python = intentos[intentos["lang"] == "python"].sort_values("day")
movil = solo_python["wpm"].rolling(3, min_periods=1).mean().round(1)
for dia, valor in zip(solo_python["day"].dt.date, movil):
print(f" {dia} {valor}")
mejor = intentos.loc[intentos["wpm"].idxmax()]
print(f"\nmejor intento: {mejor['lang']} a {mejor['wpm']:.1f} wpm "
f"el {mejor['day'].date()}")
if __name__ == "__main__":
principal()
Cómo funciona
- Toda la transformación es una sola cadena: ningún dataframe a medio construir se escapa.
- Las fechas se parsean una vez; luego el índice hace los cortes por tiempo.
- La salida es una tabla pequeña, no un volcado del dataframe.
Palabras clave y builtins usados aquí
asdefforiflambdaprintreturnzip
El intento, en números
- Líneas
- 71
- Caracteres a escribir
- 1714
- Tokens
- 491
- Ritmo de tres estrellas
- 115 tpm
Al ritmo de tres estrellas de 115 tokens por minuto, este intento toma unos 256 segundos.
Paso 1 de 1 en Bis; paso 26 de 26 en pandas.