PCEP study materials
PCEP study resources

Crate-Code Loop That Never Reports Completion

PCEP · Put your knowledge to work in context.

All case studies

Crate-Code Loop That Never Reports Completion

Marcus maintains the batch-code printer for a packing line. Crates are numbered 1 to 12. Codes divisible by 4 are reserved for fragile goods and must be skipped, and the whole run must stop before crate 10 for a shift change. He wrote:

n = 1 while n <= 12: if n % 4 == 0: n += 1 continue if n == 10: break print(n, end=" ") n += 1 else: print("ALL DONE")

The printed line is 1 2 3 5 6 7 9 and no completion text appears, although Marcus expected the completion text after a normal finish. His supervisor also wants the exact message STOPPED AT 10 when the break path is taken, and nothing extra on any other run. A colleague warns that deleting the n += 1 inside the fragile-goods branch would hang the program.

1. Explain why `ALL DONE` is never printed, and state precisely when a `while ... else` block runs.

Read the worked answer

The else clause of a loop runs only when the loop ends because its condition became false. It is skipped when the loop is left through break.

In this run the counter reaches 10, the condition n <= 12 is still true, and the if n == 10: break branch exits the loop immediately. The loop never gets the chance to fail its own condition, so Python skips the else and no completion text appears.

Two details are easy to get wrong: continue does not skip the else (only break does), and the else belongs to the while, not to the if. If the break were removed, the loop would finish by condition failure and print ALL DONE after 11 and 12 - note that 12 is skipped because it is divisible by 4.

2. Rewrite the loop so it prints `STOPPED AT 10` exactly when the break happens and `ALL DONE` only on a full run.

Read the worked answer

Use an explicit flag and print after the loop, so the message no longer depends on the else clause:

n = 1
stopped = False
while n <= 12:
    if n % 4 == 0:
        n += 1
        continue
    if n == 10:
        stopped = True
        break
    print(n, end=" ")
    n += 1

print("STOPPED AT 10" if stopped else "ALL DONE")

stopped is set only on the break path, so the ternary prints exactly one message on every run. Equivalently, keep the while ... else and place print("STOPPED AT 10") immediately before the break: else then handles the full run and the explicit print handles the early exit. Both versions preserve the existing code output 1 2 3 5 6 7 9 .

3. Evaluate the colleague's claim that removing `n += 1` from the fragile-goods branch would hang the program, tracing the values.

Read the worked answer

The claim is correct.

When n becomes 4, n % 4 == 0 is true. Without the increment, the body hits continue, which jumps straight back to the condition n <= 12. n is still 4, so the condition is true again, n % 4 is still 0, and continue fires again. Nothing inside the loop ever changes n, so the condition can never become false and the loop runs forever, printing nothing further.

The n += 1 at the bottom of the loop does not help: continue skips the remainder of the body, including that line. This is the classic continue trap. It is also why the fix should not be "move the increment to the top": incrementing before the check would shift every printed value. Keeping one increment inside the branch and one at the bottom is the correct pattern here.