08 Pandas
Compare these references after your own attempt. You can read them at any time; they do not record a live model or vendor run.
# Reference answer. Attempt the exercise first.
from io import StringIO
import pandas as pd
def clean_session_table(csv_text):
raw = pd.read_csv(StringIO(csv_text), dtype="string", keep_default_na=False)
clean = raw.copy()
clean["topic"] = clean["topic"].str.strip().str.lower()
clean["minutes"] = pd.to_numeric(clean["minutes"], errors="coerce")
valid = (clean["topic"].ne("") & clean["minutes"].notna()
& clean["minutes"].ge(0) & clean["minutes"].mod(1).eq(0))
return clean.loc[valid].copy(), raw.loc[~valid].copy()
def topic_totals(accepted):
return accepted.groupby("topic", as_index=False)["minutes"].sum().sort_values("topic")
text = "topic,minutes\n Python ,20\ndata,30\npython,25\ncharts,unknown\n,10\ndata,-3\ncharts,1.5\n"
accepted, rejected = clean_session_table(text)
summary = topic_totals(accepted)
assert len(accepted) == 3 and len(rejected) == 4
assert summary["topic"].tolist() == ["data", "python"]
assert summary["minutes"].tolist() == [30, 45]
print(summary.to_string(index=False))
# Limitation: rejected durations prevent a complete practice-time total.
# Question: can the source owner recover missing or invalid duration values?
# The separate inspection fixture: record observations before cleaning it.
inspection_text = "topic,minutes\n arrays ,15\ntables,not yet\ntables,0\n charts ,-4\n,20\n"
inspection_raw = pd.read_csv(StringIO(inspection_text), dtype="string", keep_default_na=False)
print("Inspection shape:", inspection_raw.shape)
print(inspection_raw.head().to_string())
print("Source missing markers:", inspection_raw.isna().sum().to_dict())
# Observations: topic spacing needs normalization; 'not yet' needs review;
# one empty topic is not a category, and -4 violates the duration rule.
inspection_accepted, inspection_rejected = clean_session_table(inspection_text)
assert inspection_accepted.index.tolist() == [0, 2]
assert inspection_accepted["minutes"].tolist() == [15, 0]
print("Inspection transfer checks passed")