This is the whole thing: the prose spec turned into a twelve-row battery — boundaries, rounding mode, and both nasty interactions pinned — plus the engine that satisfies every row. The exercise hands you the prose and a stub; you write both halves.
The craft on display is the translation — turning each sentence of prose into a check that runs. Each sentence of the spec became at least one row (one assertion: a stated outcome the code must produce, or it fails); the boundary words ("strictly", "or more", "at the very end", "never below") each became their own row; and the two places where sentences collide became the rows most likely to catch a wrong implementation. The battery, all together, is simply the spec made precise enough to run.
The two nasty interactions
- Rule 2 reads rule 1's output. A basket of 10 × 52.00 is 520.00 gross — over 500 — but rule 1 takes it to 468.00 first, and rule 2 reads 468.00: no basket discount. An engine that tests the gross (520) wrongly grants the 5% too, gives 444.60, and fails the pin.
- The coupon floors at zero — after everything else. 15.00 with
SAVE20is 0.00, not −5.00; an empty basket with a coupon is 0.00, not −20.00. And because the coupon is last, 600.00 becomes 570.00 → 550.00, never 580.00 × 0.95.
One more sentence that bites: rounded to the cent, half up. 15 × 0.83 = 12.45; 10% off is 11.205 — half up gives 11.21. Banker's rounding (the .NET default!) gives 11.20 and fails the pin: the battery even pins the rounding mode.
The battery and the engine, live
Press Run — twelve rows, all green.
Write the promo engine so every row of the twelve-case battery goes green: 10% off any line of 10 or more units, then 5% off a line-discounted subtotal strictly over 500, then the SAVE20 coupon last, floored at zero — rounding to the cent half-up after each rule. Run the battery and show expected versus actual per spec sentence.
The engine is eleven lines. The battery is the deliverable that outlives it: hand those twelve rows to any agent — or any colleague — and the prose is no longer open to interpretation.
← Back to the exercise · Module 1 — Introduction · All solutions