typestar

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

  1. Toda la transformación es una sola cadena: ningún dataframe a medio construir se escapa.
  2. Las fechas se parsean una vez; luego el índice hace los cortes por tiempo.
  3. La salida es una tabla pequeña, no un volcado del dataframe.

Palabras clave y builtins usados aquí

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.

Escribe este fragmento

Paso 1 de 1 en Bis; paso 26 de 26 en pandas.

← Anterior