Milk Validation Funnel, Rule Ordering & Collision Simulator
Run clean_milk() from the practice question with your own batch, check the row-conservation invariant, and see how rule ordering decides whether ' mbarara ' is a valid delivery.
Predict first
Commit to a guess before you touch anything. Being wrong here is how it sticks.
500 raw rows, 14 exact duplicates, 6 colliding record_ids, 24 domain errors. How many rows in clean_df?
Experiment
Move the controls and watch the outputs. Goals tick off automatically when you reach them.
Row conservation
rows_in (500) = kept (450) + rejected (36) + exact duplicates (14)
Tidy first, then validate
Validating before tidying rejects farmers whose only 'error' was whitespace or capitals.
Explain it
Put what you saw into words. This is what the exam will ask you to do.
Why are both rows of a record_id collision rejected, while an exact duplicate keeps one copy?
Code it
Write real code against real data. Python and SQL run right here in your browser and hidden tests check your work; the AI reviews it like an examiner.
clean_milk() — the sample_qtn exercise
Implement clean_milk(raw, centres) returning (clean_df, rejected_df, exact_removed):
- Work on a copy. Tidy first:
centre→strip().title(); parsedate(pd.to_datetime(..., format="%Y-%m-%d", errors="coerce"));litres→ numeric. - Remove exact duplicate rows (keep the first) and count them in
exact_removed. - Reject both rows of any
record_idcollision with reasonrecord_id_collision. - Then reject, with the first reason that applies, in this order:
invalid_date(unparseable),invalid_litres(missing or ≤ 0),unknown_centre(not incentres.csv). rejected_dfkeeps the original columns plus areasoncolumn.
Finally assert rows_in == len(clean_df) + len(rejected_df) + exact_removed.
Challenge
Fixed variations, a new problem every day, and unlimited AI challenges built from your current settings.
Row Conservation with Exact Duplicates & Collisions
A raw milk batch has 500 rows. During clean_milk(), you remove 14 exact duplicate copies (keep='first'), find 6 record_id keys that each have 2 conflicting rows (collisions), and reject 24 additional rows for invalid dates or non-positive litres. How many rows are in clean_df?