Reconcile with Business Rules
A record can be perfectly well-shaped and still be wrong. The line items add up to $118 but the stated total says $128. The date is 2026-13-40. The total is negative. Schema validation will not catch any of these -> they are business-rule violations, and catching them is what separates a toy from a service an accounting team would actually trust.
Write reconcile(record) -> a list of discrepancy strings. An empty list means the record reconciles cleanly. Each rule that fails adds one human-readable string. Three rules:
- Items must sum to the total (within a cent). Sum the
amountof every entry inline_itemsand compare tototal. If they differ by more than0.01, append"total mismatch: items sum to X but total is Y"(round both to 2 places in the message). Floats are imprecise, so always compare with a tolerance, never==. - The date must parse as a real calendar date in
YYYY-MM-DDform. Usedatetime.strptime(record["date"], "%Y-%m-%d")inside atry/except ValueError; on failure append"bad date: <value>". (strptimerejects impossible dates like month 13 for you.) - The total must be positive. If
total <= 0, append"non-positive total: <value>".
Order matters for the tests: check the sum first, then the date, then the sign of the total, appending in that order so a record that breaks several rules lists them predictably.
from datetime import datetime
def reconcile(record):
issues = []
items_sum = sum(it["amount"] for it in record["line_items"])
if abs(items_sum - record["total"]) > 0.01:
issues.append(...)
# then the date, then the sign
return issuesThis is the reconciliation step every invoicing, expensing, and ledger system runs before it dares write a row. Press Run to reconcile a clean record and a broken one and see the discrepancies line up.
Write reconcile(record) that returns a list of discrepancy strings for a record with line_items (each {"desc", "amount"}), total, and date. Append, in this order: a "total mismatch: items sum to X but total is Y" string when the line items do not sum to total within a cent (values rounded to 2 dp); a "bad date: <value>" string when the date is not a real YYYY-MM-DD date; and a "non-positive total: <value>" string when total <= 0. A clean record returns [].
This lesson is locked
Lessons open one at a time. Finish the previous lesson to unlock this one.