Unit 05 · lesson
Counters, Accumulators, and Repeated Decisions
Core path: 30 minutes
How can a loop remember what happened across several iterations?
A loop becomes much more useful when one iteration can affect the next.
That means some variables need to survive across the loop instead of being recreated from scratch each time.
A counter tracks how many times something happened
count = 0
for number in range(5):
count += 1
print(count)
The loop performs five iterations, so count ends at 5.
Trace the state:
| Iteration | count before | update | count after |
|---|---|---|---|
| 1 | 0 | + 1 | 1 |
| 2 | 1 | + 1 | 2 |
| 3 | 2 | + 1 | 3 |
| 4 | 3 | + 1 | 4 |
| 5 | 4 | + 1 | 5 |
The value persists from one iteration into the next.
That persistence inside the running program is different from file persistence in Week 9. Here, the state disappears when the program stops.
An accumulator builds a result from changing values
total = 0
for score in [10, 20, 30]:
total += score
print(total)
Trace it:
start total = 0
score = 10 → total = 10
score = 20 → total = 30
score = 30 → total = 60
Use the existing accumulator runtime to make the state transition visible after every iteration:
Run the code to see output.
The intermediate prints are intentional. They make the loop state visible instead of hiding the accumulator.
A counter usually adds a fixed amount such as 1.
An accumulator combines changing values into some ongoing result.
The same variable can technically do both kinds of work, but naming the pattern helps you reason about what state the program is preserving.
Where you initialize the variable matters
Compare:
total = 0
for score in [10, 20, 30]:
total += score
with:
for score in [10, 20, 30]:
total = 0
total += score
In the second version, total is reset to 0 during every iteration.
The final value becomes only the last score, not the sum of all scores.
So ask:
Does this state need to survive into the next iteration?
If yes, its initialization usually belongs before the loop.
Repeated input creates changing per-iteration state
total = 0
for round_number in range(1, 4):
score = int(input(f"Score for round {round_number}: "))
total += score
print(f"Total score: {total}")
There are two different kinds of variables here:
round_number → changes automatically each iteration
score → replaced by new user input each iteration
total → carries accumulated state across iterations
That distinction is more useful than saying "these are all variables."
Decisions inside loops let us count only matching events
even_count = 0
for number in range(1, 11):
if number % 2 == 0:
even_count += 1
print(f"Even numbers found: {even_count}")
The remainder operator % helps test divisibility:
8 % 2 → 0
9 % 2 → 1
So:
number % 2 == 0
asks whether dividing by 2 leaves no remainder.
The branch decides whether this iteration should affect the counter.
One trace reveals the whole mechanism
For values 1, 2, 3, 4, trace:
| number | even? | even_count before | after |
|---|---|---|---|
| 1 | False | 0 | 0 |
| 2 | True | 0 | 1 |
| 3 | False | 1 | 1 |
| 4 | True | 1 | 2 |
That table shows more than the final answer 2.
It shows why the state changed only on certain iterations.
break changes the normal loop plan
correct_password = "python1337"
for attempt in range(3):
password = input("Password: ")
if password == correct_password:
print("Access granted.")
break
print("Incorrect password.")
Normally the loop has up to three iterations.
break creates an early exit when the condition is satisfied.
If the correct password is entered on attempt 1, attempts 2 and 3 never happen.
That means there are now two ways for the loop to stop:
range runs out
or
break executes
Use break when that early exit expresses the real requirement. Do not use it as a magic escape hatch because the loop's normal termination logic is unclear.
Count warnings in sensor data
warning_count = 0
temperatures = [65, 82, 74, 91, 68]
for temperature in temperatures:
if temperature >= 80:
warning_count += 1
print(f"WARNING: {temperature}")
print(f"Warnings: {warning_count}")
Before running, predict:
- how many iterations occur;
- which temperatures enter the branch;
- how many times
warning_countchanges; - the final value.
Then run the same state trace directly:
Run the code to see output.
Track exactly which iterations change warning_count. Move the increment outside the if block and explain why the final count changes even though the warning condition does not.
Move the counter update outside the if block and explain why the result becomes the number of temperatures processed rather than the number of warnings.
Then modify the threshold from 80 to 90 and trace which iterations change behavior.
One comparison changed. The loop structure stayed the same.
A bad counter can still look believable
This code runs:
warning_count = 0
for temperature in temperatures:
if temperature >= 80:
print("warning")
warning_count += 1
The warning messages may look correct, but the final counter reports the number of temperatures processed, not the number of warnings.
The bug is where the state update occurs.
No traceback will save you from that one.
Before Lesson 3
You should be able to point at a variable in a loop and say whether it is:
- the current item/iteration variable;
- temporary state for this iteration;
- a counter;
- an accumulator;
- part of a stop condition.
That is how loops become readable systems instead of repeated indentation.
Vocabulary lab
Flip the idea, not just the card
Explain the term before you reveal the back. Then compare your explanation with the definition, example, and warning.
Read all terms without animation
- Counter
- A variable that tracks how many times an event occurs, often by adding one when the event happens. Example: warning_count += 1 when a warning is detected. Do not confuse it with: An accumulator that combines changing values into a total or other result.
- Accumulator
- A variable that builds an ongoing result across iterations. Example: total += score adds each score into the running total. Do not confuse it with: A variable that is reset every iteration.
- State Across Iterations
- Information preserved from one loop iteration so a later iteration can use the updated result. Example: The current running total after several scores. Do not confuse it with: A temporary value replaced each time and never needed later.
- break
- A statement that exits the nearest loop immediately. Example: Exit the password-attempt loop after successful authentication. Do not confuse it with: The normal condition or sequence exhaustion that ends a loop.