Sum and count: the accumulator
Almost every loop you will ever write is one of four patterns: sum, count, find, or build. All four share one idea, the accumulator: a variable created before the loop that each pass updates.
total = 0 count = 0 for n in range(1, 101): if n % 3 == 0: total = total + n count = count + 1
Shorthand you will see everywhere: total += n means total = total + n (works for -=, *= too).
One more tool first: in tests membership. "e" in "hello" is True. It works on strings now and on every collection in the coming units.
Sum and count in one pass
Two accumulators are set up before the loop, and the if decides which numbers contribute to them.
total = 0 count = 0 for n in range(1, 101): if n % 3 == 0: total += n count += 1 print(total, count)
Output
1683 33
The loop visits all 100 numbers but only 33 of them pass the divisibility test, which is why count ends at 33 rather than 100. Both accumulators start at 0 outside the loop, so they survive across passes, and both are updated together inside the same if body. Putting the print after the loop is what makes it report the finished totals, since printing inside would produce 33 lines of partial results.
Find and build
Find scans for the first item that matches, then stops (that was your while n % 7 != 0 in lesson 5-2, and break does it in a for).
Build constructs a new value piece by piece. With strings, start from "" and concatenate, meaning join strings end to end with +:
result = "" for ch in "hello world": if ch != "o": result = result + ch print(result) # hell wrld
Name the pattern before you write the loop. I am counting matches or I am building a cleaned-up string tells you what the accumulator is, what it starts as, and what each pass does to it.
Find, with break ending the scan
The find pattern stops as soon as it has an answer, which break is what accomplishes inside a for loop.
for n in range(501, 600): if n % 13 == 0: print("found:", n) break
Output
found: 507The range allows for up to 99 passes, but only seven happen. Numbers 501 through 506 fail the test, 507 passes, and the break ends the loop before 508 is ever examined.
That matters for more than tidiness. Without the break the loop would keep scanning and print every multiple of 13 in the range, which is a different question, and on a large sequence it would also waste real time. A find loop is defined as much by where it stops as by what it looks for.
Counting vowels combines the count pattern with the in membership test, using a short string as the set of characters that qualify.
text = "programming is powerful" count = 0 for ch in text: if ch in "aeiou": count += 1 print(count)
Output
7The accumulator is created before the loop so that it persists across passes, and count += 1 is the shorthand for adding one to whatever it currently holds. The condition ch in "aeiou" replaces what would otherwise be five separate comparisons joined by or, and it reads much closer to the intent. Spaces and consonants simply fail the test and contribute nothing, and the print after the loop reports the final tally rather than a running one.
This loop prints the single number 6.
total = 0 for i in range(4): total += i print(total)
Tracing the accumulator by hand is the reliable method. range(4) yields 0, 1, 2, and 3, so total moves from 0 to 0, then to 1, then to 3, and finally to 6. The print is unindented and therefore outside the loop, so it runs once and shows the completed sum.
Hand-tracing like this is also the fastest way to debug a loop that produces the wrong number, because it exposes both off-by-one range errors and accumulators that were reset in the wrong place.