Programming and Software Development: Question 4

Syllabus 11.2

Structured AS 8 marks

A self-service checkout scans the items a customer buys, one at a time. The price of each item is entered as a REAL number, and the customer finishes scanning by entering 0 instead of a price. The pseudocode below reads in each price, adds it to a running total, and counts how many items were scanned, ignoring the terminating value 0 itself.

DECLARE Price : REAL
DECLARE Total : REAL
DECLARE ItemCount : INTEGER

Total ← 0
ItemCount ← 0

REPEAT
    INPUT Price
    IF Price > 0
        THEN
            Total ← Total + Price
            ItemCount ← ItemCount + 1
    ENDIF
UNTIL Price = 0

OUTPUT "Number of items: ", ItemCount
OUTPUT "Total cost: ", Total

(a) The pseudocode above uses a REPEAT ... UNTIL loop rather than a WHILE ... DO loop. State whether REPEAT ... UNTIL is a pre-condition or a post-condition loop, referring to when its condition is tested, and explain why this makes it a sensible choice for reading in the first price scanned by a customer who always scans at least one item. [2]

(b) A customer scans three items, entering the prices 12.50, 8.00 and 5.50 in that order, then finishes scanning by entering 0. Trace the execution of the REPEAT ... UNTIL loop for this customer by copying and completing a trace table showing, for each pass through the loop, the value read into Price, whether the condition Price > 0 is true, the resulting values of Total and ItemCount, and whether the condition Price = 0 is true. State the two values output once the loop has finished. [4]

(c) Rewrite the loop above as an equivalent WHILE ... DO ... ENDWHILE loop that produces exactly the same output for the same four values entered, and explain why the IF Price > 0 check used inside the REPEAT ... UNTIL loop is no longer needed once the loop is rewritten using WHILE. [2]

Show worked solution Hide worked solution

Worked solution

Part (a): Post-condition loops and why REPEAT suits this task

A REPEAT ... UNTIL loop is a post-condition loop: its condition (UNTIL Price = 0) is tested after the loop body has already run, not before. This means the loop body. Here, INPUT Price followed by the IF check. Always executes at least once, however many prices are eventually entered. [1 mark] for correctly identifying REPEAT ... UNTIL as a post-condition loop and stating that its condition is tested after the body runs.

This suits the self-checkout scenario well: a customer who is scanning items always has at least one real price to enter before scanning can possibly finish, so there is no need to test any condition before the very first price has even been read. A WHILE ... DO loop, by contrast, tests its condition before the body runs, so it would need some value already available in Price before the loop even starts. [1 mark] for explaining that the loop body must run at least once regardless of the first value, matching how a WHILE loop would need a value to test before it could even begin.

Part (b): Tracing the REPEAT… UNTIL loop

Before the loop starts, Total ← 0 and ItemCount ← 0. The loop then runs once for every value entered, including the terminating 0:

PassPrice readPrice > 0 ?TotalItemCountPrice = 0 ? (loop test)
112.50Yes12.501No. Loop repeats
28.00Yes20.502No. Loop repeats
35.50Yes26.003No. Loop repeats
40.00No26.003Yes. Loop stops

[2 marks]: [1] for correctly building up Total (12.50, 20.50, 26.00) and ItemCount (1, 2, 3) across the first three passes, [1] for correctly tracing the fourth pass, showing that Price = 0.00 fails Price > 0 (so Total and ItemCount are unchanged) and that this same value then makes the UNTIL Price = 0 condition true, stopping the loop.

Once the loop has finished, the two OUTPUT statements display:

Number of items: 3
Total cost: 26.00

[2 marks]: [1] for the correct item count (3), [1] for the correct total cost (26.00).

Part (c): Rewriting as an equivalent WHILE… DO loop

DECLARE Price : REAL
DECLARE Total : REAL
DECLARE ItemCount : INTEGER

Total ← 0
ItemCount ← 0

INPUT Price
WHILE Price <> 0 DO
    Total ← Total + Price
    ItemCount ← ItemCount + 1
    INPUT Price
ENDWHILE

OUTPUT "Number of items: ", ItemCount
OUTPUT "Total cost: ", Total

Two changes are needed compared with the REPEAT ... UNTIL version: a priming INPUT Price statement is added before the loop starts, so that WHILE Price <> 0 has a value to test on its first pass, and a second INPUT Price is placed at the end of the loop body, so the next value is ready to be tested the next time WHILE Price <> 0 is checked. [1 mark] for a correctly structured WHILE ... DO ... ENDWHILE loop with both the priming read before the loop and the repeated read at the end of the loop body.

Tracing the same four values (12.50, 8.00, 5.50, 0) confirms the loops are equivalent: the priming read sets Price ← 12.50, and the loop body runs for Price = 12.50, then 8.00, then 5.50 (building Total to 26.00 and ItemCount to 3, exactly as in part (b)), reading 0 at the end of the third pass through the body. On the next test, WHILE Price <> 0 is now false, since Price is 0, so the loop body does not run a fourth time. The value 0 is never added to Total and never increments ItemCount.

This is exactly why the IF Price > 0 check inside the REPEAT ... UNTIL version is no longer needed: in that version, the loop body always ran once for every value read, including 0, so the IF was needed to stop the terminator being treated as a real price. In the WHILE version, the condition is tested before the body runs, so Price = 0 is caught by WHILE Price <> 0 itself, and the loop body, the code that adds to Total and increments ItemCount, simply never executes for it. [1 mark] for explaining that WHILE’s pre-condition test intercepts the value 0 before the loop body can run, making the internal IF check unnecessary.

Final answers

  • (a) REPEAT ... UNTIL is a post-condition loop (tested after the body runs), which suits this task because a customer always has at least one real price to enter before scanning can finish.
  • (b) Price passes through 12.50, 8.00, 5.50, then 0.00; Total reaches 26.00 and ItemCount reaches 3 after the third pass and are unchanged on the fourth; output is Number of items: 3 and Total cost: 26.00.
  • (c) Add a priming INPUT Price before the loop and a further INPUT Price at the end of the loop body; the internal IF Price > 0 check is no longer needed because WHILE Price <> 0 already tests for the terminator before the loop body runs.