Your challenge is to build a gallery picture from only straight moves, turns, and loops.
30-second gallery teaser: Run the gallery program assets/l3_gallery.py and watch one polygon become a ring. By Lesson 3, you will be able to explain both loops and build the whole design yourself.
You will learn
- Import the turtle drawing tools and run a drawing program from a file.
- Move and turn the turtle, lift its pen, and change how its line looks.
- Use
360 / nand loops to draw polygons and repeat them in a pattern.
Lesson 1: Move & Draw
A turtle is a tiny drawing robot. It knows how to move forward and turn.
Predict before running: A full turn is 360 degrees. If four equal turns make a square, how many degrees should each turn be?
Your first turtle program
import turtle brings Python's turtle drawing tools into the program. Because we imported the module, every turtle command starts with turtle..
The turtle draws when it moves with its pen down. turtle.forward(82) moves 82 steps. turtle.left(90) turns left without moving. pencolor picks the ink colour; pensize sets the line thickness.
import turtle
turtle.pencolor("blue")
turtle.pensize(3)
turtle.forward(82)
turtle.left(90)
turtle.forward(82)
turtle.left(90)
turtle.forward(82)
turtle.left(90)
turtle.forward(82)
turtle.left(90)
turtle.done()
Notice
Four 82-step moves and four 90-degree left turns make a closed square. The turtle ends where it started and faces its starting direction. turtle.right(90) turns the other way and would draw a mirror image. We will use left for our drawings so the direction stays consistent.
turtle.done() goes once, at the very end—not inside a loop. It keeps the drawing window open until you close it.
First terminal encounter: run, edit, save, rerun
Turtle drawings run as Python files, not inside the lesson notebook.
-
In JupyterLab, choose File ▸ New ▸ Terminal. The terminal opens in the course folder, as Unit 0 explains.
-
Move into this unit directory:
cd python-concepts/units/unit-06-turtle-geometry -
Run the square file. On Windows, enter:
py assets/l1_square.pyOn a Mac, enter:
python3 assets/l1_square.py -
Look for the turtle window. It may open behind JupyterLab. Close it when you finish looking.
-
Open
assets/l1_square.py, changepencolor("blue")to another color, and change82to a new side length. -
Save the file, return to the terminal, and run the same command again.
Closing the window ends the script. To see it again, rerun the command.
Notice
Notice: errors are directions
If you write forward(100) without the turtle. prefix, Python reports:
NameError: name 'forward' is not defined
Read the last line first. The name forward is unknown. Fix it by writing turtle.forward(100), then save and rerun.
If you run the command from the wrong directory, Python reports text like:
py: can't open file 'assets/l1_square.py': [Errno 2] No such file or directory
python3: can't open file 'assets/l1_square.py': [Errno 2] No such file or directory
The file is not in your current location. From the course folder, use cd python-concepts/units/unit-06-turtle-geometry, then rerun py assets/l1_square.py on Windows or python3 assets/l1_square.py on a Mac.
Replace repetition with a loop
The hand-written square lists all four corners line by line. A for loop gives the repeated forward-and-left job a name. The integer n = 4 controls how many sides to draw.
import turtle
n = 4
side = 73
angle = 360 / n
turtle.pencolor("teal")
for side_number in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.done()
Run assets/l1_square_loop.py the same way.
Notice
side_number is the loop variable. Its values are 0, 1, 2, and 3. Each value traces one square edge and aims the turtle toward the next corner. The name tells us what one loop trip draws.
Travel without drawing
Sometimes the turtle must move to a new starting place. penup() lifts the pen, and pendown() lowers it again. Predict which move below will be invisible.
import turtle
turtle.penup()
turtle.forward(35)
turtle.pendown()
n = 4
side = 58
angle = 360 / n
turtle.pencolor("darkgreen")
for corner in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.done()
Run assets/l1_travel.py the same way.
Notice
The first 35-step move changes the starting place but leaves no line. If you forget pendown(), the square will also be invisible.
Try it yourself
Choose a side length for a square: this program asks for it, then the loop draws four equal sides.
The first line, # sample-input: 60, is only a comment — it records the number this book typed to make the drawing below.
Try it yourself
# sample-input: 60
import turtle
side = int(input("Side length: "))
for corner in range(4):
turtle.forward(side)
turtle.left(90)
turtle.done()
Sample input
60Notice
Change the number you type and watch the loop draw a larger or smaller square. The loop still makes four sides.
Run assets/l1_square_input.py the same way as the other lesson programs, type a number, and press Enter.
Lesson 2: Any Polygon
A square turns 90 degrees four times. A triangle, pentagon, or heptagon needs a different turn. Can one rule draw every regular polygon?
When the turtle returns to its starting direction, all its outside turns total 360 degrees. For n equal corners, the general rule is:
angle = 360 / n
n = 7
angle = 360 / n
print(angle)
Output
51.42857142857143The result is about 51.428571. The / calculation makes a float, which can hold a decimal value.
Core prediction: Will seven decimal turns really bring the turtle all the way around? Predict, then run the heptagon.
import turtle
n = 7
side = 64
angle = 360 / n
turtle.pencolor("purple")
for corner in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.done()
Run assets/l2_heptagon.py the same way.
Notice
The turtle turns by a decimal just the same. Seven turns of 360 / 7 total one full 360-degree turn, so the heptagon closes. A triangle uses 120 degrees, not its 60-degree inside angle: turtle turns use the outside angle.
Style the same geometry
pencolor() or color() chooses the ink color. pensize() chooses the line thickness. These settings change how a polygon looks, not how its angle works.
import turtle
n = 5
side = 88
angle = 360 / n
turtle.color("coral")
turtle.pensize(5)
for corner in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.done()
Run assets/l2_styled_pentagon.py the same way.
Notice
A pentagon has n = 5, so its turn is 360 / 5 = 72.0 degrees. It makes five pen-down moves and ends where it started.
Notice
Contrast Notice: / and // are not the same rule
360 // n is a whole-number shortcut. It matches 360 / n only when n divides 360 evenly.
For seven sides, 360 // 7 = 51. Then 7 * 51 = 357, not 360. The turtle would finish with a 3-degree gap in its total turn, so the path would not close. Use true division—360 / n—for polygon angles.
A star turns twice around
A regular polygon's turns total 360 degrees. A five-point star skips across the shape, so its turns total 720 degrees—two full turns. Its rule is angle = 720 / n.
import turtle
n = 5
side = 105
angle = 720 / n
turtle.pencolor("gold")
turtle.pensize(4)
for point in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.done()
Run assets/l2_star.py the same way.
Notice
720 / 5 = 144.0. Five 144-degree turns make the closed five-point star.
Try it yourself
Choose the number of sides and the side length for a polygon: this program asks for both, then one loop draws the shape.
Try it yourself
# sample-input: 6 | 50
import turtle
sides = int(input("Number of sides: "))
side = int(input("Side length: "))
angle = 360 / sides
for corner in range(sides):
turtle.forward(side)
turtle.left(angle)
turtle.done()
Sample input
6 | 50Notice
Change the number of sides you type and watch the loop draw more or fewer sides. The turn 360 / sides changes with your choice.
Run assets/l2_polygon_input.py the same way, then type one number for each prompt.
Lesson 3: Patterns with Nested Loops
First draw two squares with one loop at a time. Each square returns to the starting point; the turn between them changes which way the second square faces.
Draw a side-60 square, turn left 90 degrees, draw another side-60 square, then turn right 90 degrees to restore the starting heading.
import turtle
side = 60
for corner in range(4):
turtle.forward(side)
turtle.left(90)
turtle.left(90)
for corner in range(4):
turtle.forward(side)
turtle.left(90)
turtle.right(90)
turtle.done()
Run assets/l3_two_squares.py the same way.
Notice
Each square closes at the same starting point. The extra left turn changes the second square’s direction, and the final right turn restores the original heading.
Now put one square or polygon loop inside a second loop. The inner loop finishes one shape; the outer loop turns before starting the next shape.
import turtle
n = 6
side = 44
angle = 360 / n
shape_count = 10
turn_between_shapes = 360 / shape_count
turtle.pencolor("darkcyan")
turtle.pensize(2)
for shape in range(shape_count):
for corner in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.left(turn_between_shapes)
turtle.done()
Run assets/l3_ring.py the same way.
Notice
The inner corner loop draws six sides per hexagon. The outer shape loop draws ten whole hexagons. That makes 10 * 6 = 60 pen-down moves. The ten between-shape turns total 360 degrees, so the complete ring closes.
Try it yourself
Choose how many squares go around a ring: this program asks for the number of shapes, then the outer loop places them.
Try it yourself
# sample-input: 8
import turtle
shapes = int(input("Number of shapes: "))
side = 36
turn_between_shapes = 360 / shapes
for shape in range(shapes):
for corner in range(4):
turtle.forward(side)
turtle.left(90)
turtle.left(turn_between_shapes)
turtle.done()
Sample input
8Notice
Change the number of shapes you type and watch the outer loop draw more or fewer squares. Each inner loop still draws four sides.
Run assets/l3_ring_input.py the same way and type the number of shapes.
Grow a spiral with an accumulator
A spiral is meant to stay open. Start with a short side, then add the same step after every move. The variable side is an accumulator because it keeps the growing value from one loop trip to the next.
import turtle
side = 8
step = 5
turtle.pencolor("brown")
turtle.pensize(2)
for side_number in range(18):
turtle.forward(side)
turtle.left(91)
side = side + step
turtle.done()
Run assets/l3_spiral.py the same way.
Notice
This spiral stays open rather than returning to its start. There are 18 pen-down moves. After each move, side = side + step makes the next one 5 steps longer. Turning a little more than 90 degrees—91 degrees here—makes each square corner rotate slightly, so the path winds outward instead of stacking.
Gallery final build
Now return to the opening picture. This version draws fifteen octagons. speed(0) draws as fast as possible; bgcolor sets the background colour. Predict the pen-down-move count before running it.
import turtle
n = 8
side = 36
angle = 360 / n
shape_count = 15
turn_between_shapes = 360 / shape_count
turtle.bgcolor("white")
turtle.pencolor("navy")
turtle.pensize(2)
turtle.speed(0)
for shape in range(shape_count):
for corner in range(n):
turtle.forward(side)
turtle.left(angle)
turtle.left(turn_between_shapes)
turtle.done()
Run assets/l3_gallery.py the same way.
Put it together: Fifteen shapes times eight sides makes 15 * 8 = 120 pen-down moves. The inner loop uses 360 / 8 to close each octagon. The outer loop uses 360 / 15 to close the ring. Meaningful names and comments make the two jobs readable.
Recap
import turtlemakes drawing commands such asturtle.forward()available.- The turtle draws when its pen is down and travels without a line when it is up.
- For a regular polygon with
nsides, turn360 / ndegrees at each corner. - A loop draws the sides; a second loop can repeat the whole shape.
You can now draw a gallery of octagons arranged in a ring.