Counter and Accumulator Patterns
A divisor D of a positive integer N is a number where N % D equals zero, meaning the remainder is zero.
Try it: Loop Tracer
How a Python for loop visits each item in turn, and how an accumulator variable (a total, a count, a best-so-far or a result list) changes on every iteration.
How it works
- Initialise the accumulator before the loop.
- Each iteration, the loop variable takes the next value from the list.
- An if inside the loop decides whether to update the accumulator.
- After the last item the loop ends and the accumulator holds the answer.
Default run (13 steps): values = [4, 9, 2, 7, 5]. Run the loop one statement at a time. … The loop has used every value. print(total) shows 27.
Simplified: A model of five fixed loop programs (sum, count, maximum, minimum, filter) run on your list — it steps the program exactly as Python would, but it does not run Python.
Loading the simulation…
Predicting the Divisors of 12
This lesson starts with a program that already works. It asks the user for a positive integer N and then reports how many divisors N has. Before reading further, make a prediction. Think about the number 12 and the numbers that could possibly divide it: every whole number from 1 up to 12. Decide how many of them divide 12 with no remainder.
What do you think happens?
How many whole numbers from 1 to 12 divide 12 with no remainder?
Reveal answer
6. The divisors are 1, 2, 3, 4, 6, and 12.
Each of these leaves a remainder of zero when 12 is divided by it. The other candidates (5, 7, 8, 9, 10, 11) each leave a nonzero remainder, so they are not divisors. Note that 12 itself is counted, because every number is a divisor of itself.
What Makes a Number a Divisor
A divisor D of a positive integer N is a number where N % D equals zero, meaning the remainder is zero. The percent sign is the remainder operator: N % D gives the amount left over after N is divided by D.
The definition is a test you can run on any candidate. For N = 12 and D = 4, the remainder is 0, so 4 is a divisor. For N = 12 and D = 5, the remainder is 2, so 5 is not a divisor. The question the program answers is simple: out of all the candidates, how many pass this test?
Tracing the Loop for N Equals 12
The source describes the solution in plain language first. Get a positive integer N from the user. Start a counter for divisors at zero. For each number testDivisor in the range from 1 to N, check whether testDivisor divides N. If it does, add 1 to the counter. When the loop finishes, output the counter. This method is correct, although the source notes that much more efficient methods exist.
Each pass through the loop follows the same order. The loop variable testDivisor takes its next value, the remainder test runs, and then either the counter goes up by one or nothing changes. The loop then moves to the next candidate. The diagram below traces every pass for N equals 12, showing the candidate, the remainder, and the counter after that pass.
Counting the divisors of 12
Count how many integers from 1 to 12 divide 12 with no remainder, using the counter pattern.
- 1Start the counter
Set
divisorCountto 0 before the loop begins. No candidates have been tested yet. - 2Test candidates 1 through 4
12 % 1, 12 % 2, 12 % 3, and 12 % 4 all equal 0. Each passes, so the counter goes up by one each time, reaching 4.
- 3Test candidate 5
12 % 5 equals 2. The remainder is not zero, so the counter is left unchanged at 4 and the loop moves on.
- 4Test candidates 6 through 11
12 % 6 equals 0, so the counter rises to 5. The remainders for 7 through 11 are 5, 4, 3, 2, and 1, none of which is zero, so the counter stays at 5.
- 5Test candidate 12
12 % 12 equals 0. This is the final candidate, and it passes, so the counter reaches 6.
- 6Output the counter
The loop has finished, so the program prints the counter, which is 6.
12 has 6 divisors: 1, 2, 3, 4, 6, and 12.
Why the Loop Bound Includes N
The loop bound must be testDivisor <= N, because N itself is a divisor and must be counted. The loop runs its condition check on every pass, including the last one where testDivisor equals N. The bound uses less than or equal to, so N is tested. Leaving N out would produce a count one too low, because N is always a divisor of itself.
The Counter Pattern in Code
The program is a practical use of the for loop. Its job is not to build a clever mathematical formula. Its job is to check a list of candidates one at a time and keep a tally of the ones that pass a test. The sketch below follows the plan described in the source, using Python. The variable names match the source's wording.
Entering 12 prints 6.range(1, n + 1)produces the candidates 1 through n, so the bound includes N.- n %
testDivisor== 0 is the remainder test that decides whether a candidate is a divisor. divisorCount+= 1 is the counter increment that runs only for candidates that pass.
Once you can see this pattern, the same structure appears in many other programs. The shape is always the same: for each item in a sequence, if the item passes a test, process it. Counting divisors is one instance, where the test is the remainder check and the processing is adding one to a counter.
Remainder Results Across Candidates
The remainder operator maps each candidate to a result. A result of zero marks the candidate as a divisor, and any other result marks it as a non-divisor. The diagram below lists the remainder for the first six candidates when N is 12. Divisors give zero, while the other candidates give a nonzero value.
Progress Reporting for Long Loops
The loop can be slow for very large N, so the source adds a feature: printing a dot every ten million tests. This gives the user visible evidence that the program is still working. The technique is called progress indication, where a long computation reports itself at regular intervals.
This change needs a second counter. One counter, divisorCount, tallies the divisors that were found. The other, numberTested, tallies the candidates checked since the last dot. These are two different questions, so they need two variables. Each time a candidate is tested, numberTested goes up by one. When it reaches 10000000, the program prints a dot and resets numberTested to zero so the next group can be counted.
numberTestedis increased after every candidate, so it counts all tests, not just divisors.- The reset to zero is what lets the next group of ten million tests be counted.
Where Progress Logic Goes Wrong
Common mistake Using a strict less-than bound and missing N
What it looks likefor testDivisor in range(1, n) on N equal to 12 tests only 1 through 11.Why it failsN is always a divisor of itself, so the loop must test it.
Do this insteadUse range(1, n + 1), which is equivalent to testDivisor <= N.Common mistake Forgetting to reset numberTested after a dot
What it looks likeThe dot prints at 10000000 and then again on every later test once the counter has passed the threshold.
Why it failsThe counter never returns to zero, so the equality check for the threshold is no longer hit as intended.
Do this insteadReset numberTested to zero right after printing the dot.
Common mistake Placing the progress increment inside the divisor branch
What it looks likenumberTested += 1 written under the if n % testDivisor == 0 line.Why it failsOnly divisors would be counted toward progress, so the dots would appear far less often than the number of tests performed.
Do this insteadPlace numberTested += 1 at the same level as the if, so every candidate is counted.
Common mistake Confusing the two counters
Why it failsdivisorCountanswers how many divisors were found, whilenumberTestedanswers how many tests happened since the last dot. They are separate questions.
Counter Versus Accumulator
The divisor program keeps a counter, and the lesson's title pairs the counter with the accumulator. A counter adds one on each qualifying iteration, so it answers how many items passed. An accumulator, in the same pattern, adds a value on each qualifying iteration, so it answers what those items add up to. The source's program uses only the counter form, and the table below sets the two side by side.
| Feature | Counter | Accumulator |
|---|---|---|
| What it adds each iteration | The number 1 | A chosen value |
| What it holds at the end | How many items passed the test | The total of the values that passed |
| Divisor program example | divisorCount += 1 | Would add a value instead of 1 |
| Typical question answered | How many? | How much in total? |
Counter and accumulator compared within the same loop-and-test pattern.
Practice Tracing a Counter
Trace the divisor counter for N equals 8. List every candidate from 1 to 8, write the remainder for each, and state the final value of divisorCount. Then compare your result with the reveal in the first section's prediction pattern.
Hints
- Candidates 1, 2, 4, and 8 leave remainder 0 when dividing 8.
- The remainders for 3, 5, 6, and 7 are 2, 3, 2, and 1, none of which is zero.
- Increase the counter only at the candidates whose remainder is zero.
Suppose a teammate changes the loop bound to range(1, n) and tests N equals 7. Predict whether the reported count will be too high, too low, or correct, and explain which candidate causes the difference.
Hints
- Recall which candidate the strict bound leaves out.
- 7 is prime, so think about which divisors it has.
Key Takeaways
- A divisor D of a positive integer N is a number where N % D equals zero, meaning the remainder is zero.
- The counter pattern tests every candidate from 1 to N in a for loop and adds one to a counter for each candidate that passes the remainder test.
- The loop bound must be
testDivisor<= N, because N itself is a divisor of itself and must be counted. - A second counter,
numberTested, can drive a progress dot every ten million tests, and it must be reset to zero after each dot. - Bugs in progress logic show up as wrong dot timing or a missing reset, so the placement of each increment and reset matters as much as the test itself.