Exercise 6 of 10 · Loops and conditions
The Clapping Game
What you will make
A count from one to twenty where every third number is replaced by a clap, so the beat is visible straight down the screen.
The one new idea: An if inside a for loop, decided again on every pass
Looking at each thing as it goes past and treating some of them differently is most of what software does — every tenth customer, the overdue rows, the weekends in a calendar. It is a loop with a question inside it.
Go straight to the code ↓A question asked on every pass
You already have both halves of this. A for loop repeats lines. An if picks between two outcomes. Put
the if inside the loop and the question is no longer asked once — it is asked again for every number the
loop hands over, and the answer can come out differently each time.
Think of an inspector walking down a train carriage. Passing every seat is the loop; glancing at the ticket is the question. Most people are left alone, but the glance happens at every seat without exception.
Indentation is what puts it inside
Until now indentation was a rule to follow. Here it does the work, because there are two levels of it and they mean different things.
for count in range(1, 21):
if count == 3:
print("clap")
else:
print(count)
print("finished")Read it by how far each line is pushed in:
- Four spaces means inside the loop. The
ifline sits there, so it runs once per number — twenty times. - Eight spaces means inside a branch of the if. Those
printlines run only on the passes where their side of the question was chosen. - No spaces at all means outside everything.
print("finished")runs once, after the loop is done.
Nothing else marks those boundaries. Python has no closing bracket or end word for a loop; the left edge of
each line is the whole story. Slide the if back to the left edge and it stops being part of the loop,
which is why one stray space changes what a program means rather than how it looks.
Every third, not the third one
count == 3 is true on exactly one pass. To catch 3, 6, 9, 12 and the rest you need something they all
share: divide any of them by 3 and nothing is left over.
% from the pizza order measures that leftover. 7 % 3 is 1, because two threes fit into seven and one is
left behind. 9 % 3 is 0, because three threes fit exactly. A leftover of zero is the mark of every third
number, so asking whether the leftover equals zero is the test you want.
A worked example
A row of seats, not a clapping game, so the answer to this exercise stays yours to write:
for seat in range(1, 5):
if seat % 2 == 0:
print(seat, "aisle")
else:
print(seat, "window")
print("all seated")Running that prints five lines:
1 window
2 aisle
3 window
4 aisle
all seatedFour numbers, four decisions. Seats 2 and 4 leave nothing over when halved, so they take the first branch; 1 and 3 take the second. The last line is at the left edge, so it appears once at the bottom rather than after every seat.
Your turn
Press Run before changing anything. The count from 1 to 20 prints fine, but there is a single clap at 3 and then nothing but numbers, because the test currently reads:
if count == 3:Replace it with a test that is true for every third count: use % and compare the leftover with 0. The
loop, the print lines, the indentation and the banners are finished — that one test is the only thing to
touch.
When it works the claps land on 3, 6, 9, 12, 15 and 18, and the beat is visible from across the room.
If something goes wrong
If the message mentions indentation, count the spaces. An error saying an indented block was expected means
a line ending in a colon has nothing pushed in underneath it — usually the if line lost its indentation
and drifted out of the loop, taking the loop's only instruction with it.
If the claps come out on 1, 4, 7 and 10 instead, the test is comparing the leftover with the wrong number. Leftovers after threes go 1, 2, 0, 1, 2, 0, and it is the 0 that marks every third count.
And if Python stops on the if line complaining about the syntax, count the equals signs: one stores a
value, two ask a question, and only the question is allowed there.
None of these break anything. The program either runs with an odd rhythm or refuses to start, and either way the fix is a single line away.
Write your code
Runs in your browser. Press Run (or Ctrl/Cmd+Enter) and the output is checked for you.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.The runtime is starting in the background. You can type now — it will be ready before you are.
The answer appears here once you have run your code at least once.
Things that often go wrong here
- Leaving the if line at the left edge instead of indenting it under the for line
- The loop is then left with no lines belonging to it, and Python stops before running anything with an indentation error saying it expected an indented block. A line has to be pushed in below the for line, and here that line is the if.
- Writing the test as count % 3 == 1
- The leftover is 1 for 1, 4, 7 and 10, so the claps land one beat early and every multiple of three prints as an ordinary number. The rhythm is still regular, which is what makes this one easy to miss.
- Keeping count == 3 and expecting it to repeat
- The question is asked on all twenty passes, but it is only ever true on the pass where count holds 3. You get a single clap near the top and plain numbers for the rest.
- Giving the print lines the same indentation as the if line
- Python then reads them as the next instruction after the question rather than as the answer to it, and reports that it expected an indented block after the if line.
Longer explanation: read the full lesson. Want a blank editor instead? Open the Python playground.