Making Decisions and Repeating Work

Counting, Accumulating, and Searching


Learning Objectives

  • You can use the accumulator pattern to compute a total or an average over a list.
  • You can count how many items in a list match a condition.
  • You can search a list for an item matching a condition.
  • You can recognize these three shapes when you see them in code you did not write.

Once you can write a loop, the next step is recognizing the shapes loops tend to take. Most useful loops fall into a handful of patterns that show up over and over. This chapter introduces three of them: accumulating, counting, and searching.

The point is not to memorize syntax. The point is to recognize the shapes — both when you are writing your own code, and when you are reading someone else’s. Once you have a name for a pattern, programs that use it become much faster to read.

The Three Shapes

Each of the patterns in this chapter follows the same outline:

  1. Set up a variable before the loop.
  2. Update the variable inside the loop, once per item.
  3. Use the variable after the loop.

The before/inside/after structure is the same. What changes between patterns is what the variable means and how it gets updated.

Accumulating: Computing a Total

The most common loop shape adds up the items in a list.

minutes_list = [45, 30, 60, 90, 15]
total = 0
for minutes in minutes_list:
total = total + minutes
print(f"Total minutes: {total}")

This prints Total minutes: 240. A trace shows what is happening:

Iterationminutestotal after the update
(before loop)—0
14545
23075
360135
490225
515240

The variable total is set to 0 outside the loop. Inside the loop, each iteration adds the current item to it. By the time the loop ends, total contains the sum of all the items.

The line total = total + minutes is so common that Python has a shorthand for it: total += minutes. Both mean exactly the same thing. The += form is the one you will see most often.

total = 0
for minutes in minutes_list:
total += minutes

Three things to notice:

  1. The starting value 0 matters. If you accidentally start total at 1, every total will be off by one. For sums, 0 is the right starting value because adding 0 to anything leaves it unchanged.
  2. The starting value is set outside the loop. If you put it inside, it would reset to 0 on every iteration, and total would always end up equal to the last item.
  3. If the list is empty, the loop body runs zero times, and total stays at 0. That is the right answer: the total of nothing is nothing.

Accumulating: Computing an Average

An average is a total divided by a count. With the accumulator pattern, this is two lines after the loop:

minutes_list = [45, 30, 60, 90, 15]
total = 0
for minutes in minutes_list:
total += minutes
average = total / len(minutes_list)
print(f"Average: {average:.1f} minutes")

This prints Average: 48.0 minutes.

In the following exercise, you will compute the average without using len(). Instead, you will count the items in the loop by incrementing a variable on each iteration. The result is the same, but it is a different shape — one that shows up often when you are processing data that does not come in a list.

Counting the average, differently

0 / 5 points

Drag and drop the blocks to build a natural-language program that calculates the average of the numbers in a list. In this exercise, the count is calculated by incrementing a variable inside the loop instead of using the length of the list.

In both approaches shown above, there is a quiet edge case. What if the list is empty? Then, in the example len(minutes_list) is 0, while in the exercise, count is 0. Dividing by zero raises an error. The loop itself handles the empty case gracefully — it just does not run — but the line after it does not. The full version of an average over a possibly-empty list looks like this:

minutes_list = [45, 30, 60, 90, 15]
if len(minutes_list) == 0:
print("No sessions yet.")
else:
total = 0
for minutes in minutes_list:
total += minutes
average = total / len(minutes_list)
print(f"Average: {average:.1f} minutes")

This is the kind of detail that surface-level testing misses. You will see this exact case in Verifying Behavior and Finding the Edge Cases AI Misses when you start looking at AI-generated code.

Average and empty lists

0 / 5 points

Why should a program check whether minutes_list is empty before computing total / len(minutes_list)?

Counting Matching Items

The next pattern counts how many items in a list satisfy some condition.

minutes_list = [45, 30, 60, 90, 15]
long_sessions = 0
for minutes in minutes_list:
if minutes >= 60:
long_sessions += 1
print(f"Long sessions: {long_sessions}")

This prints Long sessions: 2.

The structure is the same as the accumulator. A counter starts at 0 outside the loop, gets incremented inside the loop, and is used after the loop. The only new thing is the if inside the body — the counter only goes up when the item matches the condition.

The starting value 0 is still right. So is the “empty list gives zero” behavior. Counting nothing should give zero, and the loop body running zero times produces exactly that.

Searching: Did Anything Match?

A search loop asks a yes/no question: is there an item in the list that matches something? The basic pattern uses a Boolean flag:

subjects = ["Math", "Physics", "Linear Algebra"]
found = False
for subject in subjects:
if subject == "Math":
found = True
if found:
print("Math is in the list.")
else:
print("Math is not in the list.")

The same shape as before: variable set outside the loop, updated inside, used after.

There is one twist worth noticing. Once found is True, there is no point in continuing to check the rest of the list — the answer is already known. In While Loops and Range you will see the break keyword, which lets you exit the loop early in exactly this case. For now, the version above is correct, just slightly wasteful on long lists.

Python’s built-in in operator (from Lists) does this exact pattern for you in one line: if "Math" in subjects:. You should use in in real code. The point of writing the loop by hand once is so you understand what in is doing under the hood. Many built-in operations are just named versions of patterns from this chapter.

Search flag shape

0 / 5 points

Arrange the blocks into a search loop that records whether "Art" is present in subjects.

Finding the Maximum

A close relative of searching is tracking the best: walking the list and keeping the largest value seen so far.

minutes_list = [45, 30, 60, 90, 15]
longest = minutes_list[0]
for minutes in minutes_list:
if minutes > longest:
longest = minutes
print(f"Longest session: {longest} minutes")

This prints Longest session: 90 minutes.

The pattern is similar but with one important difference: the starting value cannot be 0. If every session were 5 minutes long, starting at 0 would give the wrong answer because 0 would be considered the maximum. The fix here is to start at the first item of the list.

That fix introduces its own edge case: what if the list is empty? Then minutes_list[0] is an IndexError. The full version that handles the empty case looks like this:

if len(minutes_list) == 0:
print("No sessions yet.")
else:
longest = minutes_list[0]
for minutes in minutes_list:
if minutes > longest:
longest = minutes
print(f"Longest session: {longest} minutes")

Python also has a built-in max() function: max(minutes_list) gives you the largest value directly. Like in, it is shorthand for a pattern you should be able to recognize and implement yourself. max() of an empty list also raises an error, so the edge case has to be handled either way.

Finding the shortest session

0 / 10 points

Ask the user for three study-session lengths in minutes. Convert each answer to an integer and store the values in a list.

Because this exercise always asks for exactly three values, the list will contain three items. Find the shortest value by starting with the first list item and comparing each value. Print the shortest session.

Example input:

20
95
45

Required output text:

Shortest session: 20 minutes

Recognizing the Shapes in Other Code

Once you know these patterns, programs that use them get much faster to read. When you see a loop in someone else’s code, ask:

  • Is there a variable being set up before the loop?
  • Is it being updated on every iteration, or only when a condition matches?
  • Is it being used after the loop?
  • What does it represent — a sum, a count, a flag, a best-so-far?

Most of the time, the answer fits one of these patterns. Code that follows a familiar shape is much easier to verify, debug, and modify.

This is also a useful lens for reading AI-generated code, which is what the next-to-last chapter of this part is about. The most common AI mistakes in loop code are not “the syntax is wrong”. They are “the pattern is almost right, but the starting value is wrong” or “the condition inside the if is slightly off.”

Recognize loop patterns

0 / 10 points

Read this code:

total = 0
short_count = 0
for minutes in [10, 45, 20]:
total += minutes
if minutes < 30:
short_count += 1
print(total)
print(short_count)

Identify the loop patterns used, give the final values, and explain how you recognized each pattern.

Your answer should include:

  • which variable is accumulating a sum,
  • which variable is counting matching items,
  • the final values printed by the program,
  • and the before-loop setup and inside-loop updates that reveal the patterns.

Check Your Understanding

  1. In the accumulator pattern, why is the starting value set outside the loop?
  2. What is the total of an empty list, using the accumulator pattern? Why?
  3. What is the maximum of an empty list, using the track-the-best pattern? Why is this different from the total case?
  4. What pattern is the following loop using, and what does it compute?
count = 0
for s in subjects:
if len(s) > 5:
count += 1

AI Study Aid

Create a chapter diagram

We're looking into to what extent AI-generated diagrams could help with studying.

Use this study aid to generate an AI-generated visual summary of the material you just studied. Each diagram style emphasizes the content in a different way, so you can choose the focus that feels most useful.

Using the diagram generator is voluntary and does not affect your course progress. We encourage you to try it out and see if it helps, but it's totally up to you! Your answers help us understand how to make better study aids in the future.

Diagrams tried: 0