NCEA Level 2 Digital Technologies study materials
NCEA Level 2 Digital Technologies study resources

Canteen Pre-order Total Crashes Before Launch

NCEA Level 2 Digital Technologies · Put your knowledge to work in context.

All case studies

Canteen Pre-order Total Crashes Before Launch

A Year 12 team at a Wellington secondary school has built a Python 3 pre-order program for the school canteen, which serves about 620 students a day. Each order line is a dictionary such as {"item": "pie", "price": "4.50", "qty": 2}, and a whole day's orders are held in one list. The day's takings are calculated by a function that loops over the list and adds each line's price multiplied by its quantity. During testing, two pies and one juice ($3.00) crash the program with TypeError: can't multiply sequence by non-int of type 'float'. The canteen manager has also noticed that when a student orders the same item twice it prints as two separate lines, which slows packing at interval. The team has three days before launch. One member wants to rewrite the whole program using classes for Menu, Order and OrderLine; another wants to patch the crash and leave the structure alone. The teacher requires evidence of testing and a short written justification of the design decisions.

1. Identify the cause of the TypeError and explain what the team should change, including where in the program the change belongs.

Read the worked answer

The crash is a data-type bug, not a maths bug. The price is stored as text - "4.50" - because it was typed into the dictionary literal or read straight from a CSV without conversion. In Python the * operator between a string and an integer repeats the string, so "4.50" * 2 gives "4.504.50". The multiplication succeeds when qty is an int; it is the += into a numeric total that raises the TypeError.

The fix belongs where data enters the program, not inside the total function. Convert price to Decimal(price) (or to whole cents as an int) and qty to int once, at load or input, and reject or flag anything that will not convert. Money should not be held in float, because binary floats cannot represent values like 0.10 exactly and cent-sized errors accumulate across 620 orders.

Patching only the total function leaves the same bad data to break the kitchen printout, the daily report and any later feature. Converting at the boundary means every function downstream can trust its inputs, and a validation failure can be reported with the offending row so the manager can fix the source data.

2. The team must choose between a three-day rewrite using classes and a patch to the existing code. Recommend one option and justify it using the evidence available.

Read the worked answer

Recommendation: patch now, refactor after launch, and write tests first.

Evidence for patching: the failure is one unvalidated type at the input boundary plus a missing grouping step. Both fit the existing list-of-dictionaries design - parse to Decimal at load, and before printing, group lines by item using a dictionary keyed on the item name and sum the quantities. That is hours of work, not days.

Evidence against the rewrite: a Menu/Order/OrderLine model is better design, but three days leaves no time for regression testing, and the canteen has a hard start date. An untested rewrite is a bigger risk to 620 students' lunch orders than a well-tested patch.

Conditions attached to the decision: (1) write characterisation tests that capture the currently correct behaviour before changing anything; (2) keep the total calculation in one function so it can be swapped later; (3) after launch, refactor with those tests as a safety net. Record the decision and the reasons in the design log - the reasoning is what is being assessed, not just the choice. If the manager could delay a week with a manual fallback, a staged rewrite becomes defensible.

3. Describe the testing you would carry out before launch and the evidence you would keep.

Read the worked answer

Tests should target boundaries and the reported failure, not repeat one happy path.

Case Input Expected What it checks
empty day [] 0.00 no crash on no data
reported bug 2 pies, 1 juice 12.00 regression of the crash
zero quantity price 4.50, qty 0 0.00 no phantom charge
duplicate items 2 pie lines one line, qty 3 grouping
bad data price "free" clear error naming the row validation
rounding 3 × $0.10 0.30 exactly Decimal, not float
volume 200 lines correct total performance

Each result goes into a table of input / expected / actual / pass-fail and is kept as evidence.

Then user acceptance testing: the canteen manager runs 20 real orders from the previous week and compares the program's total and packing list against the paper record. This catches requirements the team did not think to specify.

One successful test proves nothing - the crash only appeared with a multi-line order, so a single-line test would have hidden it.