Sentinel-Controlled Input
Priming a loop means preparing a valid current value for the first while-condition test.
Try it: while Loops, break and continue
How a while loop re-evaluates its condition before every pass, how break leaves the loop at once, how continue jumps back to the condition, how a sentinel value ends a while True loop, and why a loop whose condition never becomes False runs forever.
How it works
- Evaluate the condition. If it is False, skip the body and continue after the loop.
- If it is True, run the body from the top, then go back and evaluate the condition again.
- continue skips the rest of the body and goes straight back to the condition check.
- break leaves the loop immediately; the condition is not checked again (while True loops rely on it, e.g. stopping at a sentinel like 'done').
- If nothing in the body can make the condition False, the loop never ends; the lab's guard stops it after N iterations and says so.
Default run (21 steps): Ready: Countdown. A while loop checks its condition before every pass. … Finished after 5 iterations and 6 condition checks.
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. input() returns the lines you type in the list, one per call (the prompt is not printed), and raises EOFError when they run out, like a closed keyboard stream. The guard is the lab's, not Python's.
Loading the simulation…
A Loop That Asks a Question Too Early
Many programs read an unknown number of values from a user and stop when the user enters a special marker. That marker is called a sentinel. A while loop is a natural fit for this job, because the loop keeps going while the input is still real data and stops when the sentinel arrives. The difficulty is that the loop's condition is tested before the body runs, so the condition needs a value to examine right from the start.
A common misunderstanding is that a while loop can begin by asking whether an input value has some particular property, even though no input has been obtained yet. The first test happens before the loop body runs. If there is no current value to inspect, the condition does not yet make sense. This section explains why, and how the fix called priming solves it.
Priming the Loop with a First Read
Priming a loop means preparing a valid current value for the first while-condition test.
Reading the first integer before the loop is a standard way to prime an input loop. Once that initial read has happened, the loop has a current integer available. The condition can examine it, and the body can process it when it is not the sentinel. At the end of the body, the program reads another integer. Control then returns to the condition, which examines the newly read value. Every test in the loop therefore has a meaningful current value to look at.
The diagram shows the key idea. The first value enters the loop through the initial read, not through the body. The condition is always tested against a value that has already been obtained. Without the first read, the very first test would have nothing to inspect.
Enter a number: 4
Processing 4
Enter a number: 7
Processing 7
Enter a number: -1
Loop finished- The first read happens before the while line, so the condition has a current value to test.
- The sentinel here is -1, chosen for this example. The loop body only runs for real values.
- The last line inside the body reads the next value, returning control to a condition that has something to examine.
Sentinel Versus Data
The sentinel ends the input sequence but is not part of the data being processed. This distinction matters. The condition must reject the sentinel before the loop body handles it. The body should only act on the values that belong to the data set.
| Aspect | Sentinel value | Data value |
|---|---|---|
| Role in the program | Signals that input is finished | Is a real item to be handled |
| Does the loop body act on it? | No, the condition rejects it first | Yes, the body processes it |
| Should it appear in totals or counts? | No | Yes |
| Example with sentinel -1 | The value -1 that stops the loop | The values 4, 7 and 2 |
Sentinel values and data values play different roles in the same loop.
Tracing a Sentinel Loop Pass by Pass
Predict the stopping point before reading the trace. Suppose the user enters 4, 7, 2, and then -1. At which pass does the loop stop, and which value is the current value when the condition first sees the sentinel?
Summing Values Until the Sentinel
Sum the values entered by the user, stopping when the sentinel -1 is entered. The input is 4, 7, 2, -1.
- 1Prime the loop
Read 4 before the loop. The current value is 4 and total is 0.
- 2Pass 1
The condition sees 4, which is not -1, so the body runs. total becomes 4. The next read gives 7.
- 3Pass 2
The condition sees 7, which is not -1. total becomes 11. The next read gives 2.
- 4Pass 3
The condition sees 2, which is not -1. total becomes 13. The next read gives -1.
- 5Pass 4 and exit
The condition sees -1, which is the sentinel. The condition is false, so the body does not run and -1 is not added to total.
The total is 13. The three data values were processed, and the sentinel was never added.
Each pass tests the current value, processes it only if it is data, and then replaces it with the next read. The stopping pass is the one where the current value is the sentinel. The loop finishes without processing that value.
Enter a number: 4
Enter a number: 7
Enter a number: 2
Enter a number: -1
Total: 13- total starts at 0 and only changes inside the body.
- The sentinel -1 fails the condition and is never added to total.
- The printed total is 13, the sum of the three data values.
Counting the Sentinel by Mistake
Rejecting the sentinel before the loop body prevents incorrect totals and off-by-one counts. The most common version of this error comes from counting every read rather than every data value. The sentinel is read, so a careless counter includes it.
count = 0
value = int(input('Enter a number: '))
count = count + 1
while value != -1:
total = total + value
value = int(input('Enter a number: '))
count = count + 1Every read is counted, including the sentinel, so count is 4 for the input 4, 7, 2, -1. This is one too many.
count = 0
value = int(input('Enter a number: '))
while value != -1:
total = total + value
count = count + 1
value = int(input('Enter a number: '))Only data values are counted. For the same input, count is 3, which is the correct number of items.
Common mistake Testing a condition before any value has been read
What it looks likewhile value > 0: appears above the line that assigns value = int(input(...))Why it failsThe first test occurs before the body runs, so there is no current value to inspect. The condition does not yet make sense.
Do this insteadRead the first value before the loop so that the condition has a current value for its first test.
Common mistake Adding the sentinel to the total
What it looks likeLetting the body run for -1 and adding it to total
Why it failsThe sentinel ends the input sequence and is not part of the data being processed.
Do this insteadMake the condition reject the sentinel so the body only handles real values.
Common mistake Counting every read instead of every data value
What it looks likeIncrementing count right after each input call, including the one that returns the sentinel
Why it failsThe count includes the sentinel, so it is one larger than the number of data items. This is an off-by-one error.
Do this insteadIncrement count only inside the body, where real data values are processed.
Debugging a Primed Loop
When a primed loop gives wrong results, find the first point where the expected role of the current value changes. Then ask three questions in order. These questions separate a missing setup step from a boundary mistake and from a counting mistake.
- 1Was a first value read before the condition?
- 2Did each real value reach the loop body?
- 3Did the sentinel stop the loop before it was processed?
Predict an Empty Input
What do you think happens?
Using the primed loop from earlier, what happens if the user's very first entry is -1?
Reveal answer
The body never runs, so total stays 0 and count stays 0
The first read returns the sentinel. The condition tests it before the body runs, finds it false, and the loop exits immediately without processing the sentinel.
Write a primed sentinel loop that reads integers until the user enters 0, and prints both the total and the count of the real values entered. Test it with the input 5, 3, 0. The count should be 2 and the total should be 8.
Hints
- Read the first integer before the while line.
- Increment count only inside the loop body.
- Make the condition compare value with 0 so the sentinel is never added or counted.
Key Takeaways from Priming
- 1Priming a loop means preparing a valid current value for the first while-condition test.
- 2Reading the first value before the loop gives the condition something meaningful to examine on every pass.
- 3The sentinel ends the input but is not data, so the condition must reject it before the body handles it.
- 4Counting the sentinel produces an off-by-one error, so count only the values that the body processes.
At a glance
- Priming a loop means preparing a valid current value for the first while-condition test.
- Reading the first value before the loop gives the condition something meaningful to test on every pass.
- The sentinel ends the input but is not data, so the condition must reject it before the body handles it.
- Counting the sentinel produces an off-by-one error, so count only values that the loop body processes.