pd_run_report.py in Python
A pandas report end to end: parse, clean, derive, group and rank.
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 load(text):
"""Read the export and give every column its real type."""
return pd.read_csv(
StringIO(text),
parse_dates=["day"],
dtype={"lang": "category", "chars": "int32", "errors": "int16"},
)
def derive(frame):
return frame.assign(
wpm=lambda f: (f["chars"] / 5) / (f["seconds"] / 60),
accuracy=lambda f: (1 - f["errors"] / f["chars"]) * 100,
week=lambda f: f["day"].dt.isocalendar().week,
)
def by_language(frame):
return (frame
.groupby("lang", observed=True)
.agg(runs=("wpm", "size"),
best_wpm=("wpm", "max"),
mean_wpm=("wpm", "mean"),
accuracy=("accuracy", "mean"))
.sort_values("mean_wpm", ascending=False)
.round(1))
def main():
runs = load(RAW).pipe(derive)
print("runs per language")
print(by_language(runs).to_string())
print("\nweekly mean wpm")
weekly = (runs.set_index("day")["wpm"]
.resample("W")
.mean()
.round(1)
.dropna())
print(weekly.to_string())
print("\nrolling three-run average, python only")
python_only = runs[runs["lang"] == "python"].sort_values("day")
rolling = python_only["wpm"].rolling(3, min_periods=1).mean().round(1)
for day, value in zip(python_only["day"].dt.date, rolling):
print(f" {day} {value}")
best = runs.loc[runs["wpm"].idxmax()]
print(f"\nbest run: {best['lang']} at {best['wpm']:.1f} wpm "
f"on {best['day'].date()}")
if __name__ == "__main__":
main()
How it works
- The whole transform is one chain, so no half-built frame escapes.
- Dates are parsed once, then the index does the time slicing.
- The output is a small table, not a dump of the frame.
Keywords and builtins used here
asby_languagedefderiveforiflambdaloadmainprintreturnzip
The run, in numbers
- Lines
- 71
- Characters to type
- 1638
- Tokens
- 491
- Three-star pace
- 115 tpm
At the three-star pace of 115 tokens a minute, this run takes about 256 seconds.
Step 1 of 1 in Encore, step 26 of 26 in pandas.