The capstone preserves the existing sales-v1 report: first valid customer/sale wins, later identical normalized rows are duplicates, conflicting payloads are conflicts, and valid sales with unknown customers remain accepted but unmatched.
The Pandas implementation shares scalar parsing/validation rules with the records version, then independently performs DataFrame deduplication, enrichment and totals. It never calls the records clean_sales function. Compare the entire report, not just a total or screenshot.
The source loader keeps identifiers and literal NA text intact. Scalar validators normalize accepted fields. DataFrame duplicated/drop_duplicates chooses the first valid normalized row, while error records are sorted back into source order so invalid rows and duplicate findings remain comparable.
The joined cents column deliberately stores Python ints as object dtype. Its totals stay exact even beyond signed64-bit range. Public output converts missing customer names to None and scalar counts/cents to ordinary Python ints before JSON serialization.
import pandas as pd
rows=pd.DataFrame({"id":["a","a","b"],"cents":[29,30,-125]})
print(rows.duplicated("id",keep="first").tolist())
print(rows.drop_duplicates("id",keep="first")["cents"].tolist())The independent records baseline and DataFrame path must agree on accepted rows, both error lists, unmatched source positions and every summary field. The fixture includes zero, refunds, leading-zero IDs, literal NA text, duplicate/conflicting rows, invalid dates/amounts and unknown customers.
A separate large-integer case demonstrates exact policy preservation. It is reported to browser media as a decimal string rather than an unsafe JavaScript number. A parity result concerns these defined inputs and policy; it is not a claim that arbitrary inferred dtypes are interchangeable.
import pandas as pd
huge=99999999999999999999999999999999
values=pd.Series([huge,1],dtype=object)
print(values.sum()==huge+1)
print(type(values.iloc[0]).__name__)Run the downloadable report comparison and public checks. Inspect the actual dtypes, mask, group and join views, then add an independent edge case without changing the baseline policy. The CLI uses only supplied local fixtures after dependency installation.
Cleanup removes only the extracted lab’s own virtual environment and output files you created. No account, production database or remote data source is used. Continue into broader analysis after complete report parity is established.
Download the complete lab. The archive includes runnable code, tests, fixtures and a README.
Follow the same observations through each operation.
These tables were computed from the supplied fixture. Choose a step to inspect actual values and row counts. Full report parity includes accepted rows, rejection reasons, unmatched source positions and every summary field.
Eleven raw records retain text IDs, literal NA and empty amounts before business validation.
| sale_id | customer_id | date | amount |
|---|---|---|---|
| s001 | 001 | 2025-01-01 | $0.29 |
| s002 | 002 | 2025-01-02 | $0 |
| s003 | missing | 2025-01-03 | -$1.25 |
| s001 | 001 | 2025-01-01 | $0.29 |
| s001 | 001 | 2025-01-01 | $0.30 |
| s004 | "" · empty text | 2025-01-04 | $4 |
| s005 | NA | 2025-01-05 | $2 |
| s006 | 001 | 2025-02-30 | $1 |
| s007 | 001 | 2025-01-07 | $1,234.50 |
| s008 | 001 | 2025-01-08 | bad |
| s009 | 001 | 2025-01-09 | "" · empty text |
sale_id · stringcustomer_id · stringdate · stringcents · Int64