Counters, Accumulators, Results, and Flags
Unit ID: M04-U06 Estimated active time: 25-35 minutes
Loops often build state
Four common patterns are:
- counter: how many items met a rule;
- accumulator: a running total;
- result collection: accepted, rejected, or transformed items;
- flag: whether an event occurred.
Count and total valid values
values = [8, 12, -2, 4]
valid_count = 0
valid_total = 0
for value in values:
if value < 0:
continue
valid_count = valid_count + 1
valid_total = valid_total + value
Initial values must represent an empty result: zero count and zero total.
Build accepted and rejected outputs
accepted = []
rejected = []
for value in values:
if value < 0:
rejected.append(value)
else:
accepted.append(value)
The outputs preserve the decision evidence.
Track whether anything failed
has_invalid_value = False
for value in values:
if value < 0:
has_invalid_value = True
If you only need to know whether any failure exists, you may break after setting the flag. If you need all rejection details, continue processing.
Avoid stale state
In a notebook, rerunning only the loop cell without resetting counters can double the totals. Keep initialisation in the same cell or ensure restart-and-run-all recreates clean state.
Use descriptive names
total is vague when several totals exist. Prefer accepted_hours_total, rejected_count, or found_target.
Practice
Process [8, 0, 41, "6", 12]. Build:
- valid integer values from 0 to 40;
- rejected values;
- accepted count;
- rejected count;
- accepted total; and
- a flag showing whether any rejection occurred.
Expected accepted values are [8, 0, 12] and accepted total is 20.
Takeaway
Initialise state before the loop, update it only in the correct branch, and keep names specific. Next, we will compare an explicit loop with a concise comprehension.
