Lesson 9 · Python Loops
Lesson 9 · Python Loops
Teacher mode is on. Toggle it off (bottom-right) to preview the student view.
Remember the Repeat block that made shapes so much shorter? Python has the
same tool: the for loop. In this lesson you'll write loops in text and use
them to draw the shapes you already know — proving the logic is identical, only
the syntax changed. Then you'll do something Blockly made awkward: put a loop
inside another loop.
Learning Objectives
By the end of this lesson you will be able to:
- Write a Python
forloop and use it to repeat robot commands - Explain what
range(n)produces and why counting starts at0 - Use indentation to define exactly what's inside the loop
- Nest one loop inside another, using the outer counter to change what the inner loop draws
The Repeat block, in text
Here's the square you drew in Lesson 2 as a Blockly Repeat — and the Python for
loop that does the same thing:
← repeat 4 times
← cm: 30
← Deg: 90
for i in range(4):
drivetrain.straight(30)
drivetrain.turn(90)
Breaking down that first line:
for— the keyword that starts a loop.i— a counter variable (you can use it or ignore it).range(4)— produces the numbers0, 1, 2, 3— four of them.:— required, and everything indented under it is the loop body.
What numbers does range(4) produce?
Indentation decides what repeats
Indentation isn't decoration — it's how Python knows which lines are inside the loop. Compare:
for i in range(4):
drivetrain.straight(30)
drivetrain.turn(90)
print("Square complete!") # NOT indented → runs once, after the loop
The two indented lines repeat four times; the print runs once at the end because
it's not indented.
In the code above, how many times does print("Square complete!") run?
Use the counter
The loop variable isn't just for counting — you can use it. This prints which side it's drawing as it goes:
for i in range(5):
print(f"Drawing side {i + 1} of 5")
drivetrain.straight(20)
drivetrain.turn(72)
The f"…{i + 1}…" is an f-string — it drops the value of i + 1 right into
the text. We use i + 1 so the messages read "1, 2, 3…" instead of "0, 1, 2…".
You want a loop to run 6 times to draw a hexagon. What goes in the range?
Try these: write loops to draw a triangle (range(3), turn 120) and a pentagon
(range(5), turn 72). Add a print() inside each so you can watch the progress.
A loop inside a loop
New problem: draw four squares, each bigger than the last — 20 cm, then 25, then 30, then 35.
You already know how to draw one square with a loop. So you could write that loop four times, changing one number in each copy… and you know where that goes. In Lesson 2, the answer to "the same thing, over and over" was a loop. It still is. The only difference this time is that the thing being repeated is itself a loop.
from XRPLib.defaults import *
board.wait_for_button()
for square in range(4): # outer loop — one pass per square
size = 20 + square * 5 # 20, 25, 30, 35
for side in range(4): # inner loop — one pass per side
drivetrain.straight(size)
drivetrain.turn(90)
Read it from the inside out. The inner loop is the square you already wrote:
four sides, four corners. The outer loop runs that entire square four times —
and this is the useful part, square counts 0, 1, 2, 3 as it goes, so
20 + square * 5 works out to a different size on every pass.
Indentation is doing real work here. size is indented once, so it belongs to the
outer loop and is recalculated once per square. The two drivetrain lines are
indented twice, so they belong to the inner loop and run four times per square —
sixteen sides in total.
Because a square finishes where it started, each new square sets off from the same corner as the one before it, so the four nest inside each other.
In the nested program above, how many times does drivetrain.straight() run in total?
What happens if you indent the size line twice, so it lines up with the drivetrain lines?
Activity · Draw a nest of squares
- Type the nested-loop program above and run it. Before you press the button, write down two predictions: the total distance the robot will drive, and how many turns it will make. Check them against what you see.
- Change it to draw six squares. What did you have to change — and what stayed the same?
- Change the step from
5cm to10cm and run it again. - Challenge — make the squares shrink instead of grow, so the largest is drawn first. There are two ways to do it: change the arithmetic, or count down.
- Challenge — right now every square starts from the same corner. What would you add between squares to centre them all on one point instead?
Real-world connections
Loops are how software handles "do this for every…" without endless copy-paste:
Feeds & lists
A social feed loops over posts, drawing each one with the same code.
Processing records
Analyzing a million rows is one loop that runs a million times — no extra code.
Sensor polling
Robots loop constantly: read sensors, decide, act, repeat — thousands of times a second.
Wrap-up
- What does
range(4)produce, and how many times does the loop run? (0,1,2,3— four times.) - What decides which lines are inside the loop? (Indentation.)
- In a nested loop, which loop runs more often — the inner one or the outer one? (The inner one: once per side, per square.)
- How did the outer loop change the size of each square? (Its counter was used in the arithmetic that set
size.)
Resources
- XRPLib Documentation
- VS Code — the editor we use for Python