You are the artist. Your robot turtle holds the pen and draws whatever you command. By the end of this unit you will run a spirograph design — one small shape turning into a whole design. Your mission is to discover how a short set of commands makes it.
Each idea comes as a short ladder — simplest first, then one step up — with a Notice naming the one new thing. Every turtle program here also lives in assets/ so you can run it and watch the window.
You will learn
- Command the turtle to move, turn, lift its pen, and change color and pen size.
- Repeat a block with a
forloop andrange(). - Work out the turn for any polygon with
360 / n, which gives a float. - Nest one loop inside another to build a spirograph.
Lesson 1: Move the Pen
import turtle brings in the drawing tools. forward(100) moves the turtle 100 steps; right(90) turns it one square corner. The turtle draws wherever its pen touches the page.
import turtle
turtle.forward(100)
turtle.right(90)
turtle.done()
Notice
forward moves the turtle and right turns it — one move, one turn leaves an open corner.
Turtle drawings open their own window, so this program runs as a file, not in the notebook. Open a terminal in JupyterLab (File ▸ New ▸ Terminal) and move into this unit folder:
cd python-projects/units/unit-03-turtle-art-studio
Then run the file. On Windows, enter:
py assets/l1_corner.py
On a Mac, enter:
python3 assets/l1_corner.py
You can also open assets/l1_corner.py in Thonny and click Run. A drawing window opens (it may hide behind JupyterLab); close it when done.
import turtle
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.done()
Notice
Repeating the same move-and-turn four times draws a closed square — the turtle ends where it began.
Run assets/l1_plain_square.py the same way — a drawing window opens; close it when done.
import turtle
turtle.penup()
turtle.forward(80)
turtle.pendown()
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.done()
Notice
penup() lifts the pen so a move leaves no mark; pendown() drops it again before drawing.
Run assets/l1_travel.py the same way — a drawing window opens; close it when done.
import turtle
turtle.color("blue")
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.done()
Notice
color("blue") changes the pen color — the shape is the same, the ink is different.
Run assets/l1_color.py the same way — a drawing window opens; close it when done.
import turtle
turtle.color("teal")
turtle.pensize(4)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.done()
Notice
pensize(4) makes the line thicker — a fourth pen setting, separate from color.
Run assets/l1_square.py the same way — a drawing window opens; close it when done.
Lesson 2: Repeat with for and range()
Writing the same two commands four times is a lot of typing. A for loop repeats an indented block, and range(n) runs it exactly n times. The counter starts at 0 and stops before n.
import turtle
for side in range(4):
turtle.forward(100)
turtle.right(90)
turtle.done()
Notice
for side in range(4): repeats the block four times — the loop replaces the written-out square.
Run assets/l2_square_loop.py the same way — a drawing window opens; close it when done.
import turtle
angle = 120
for side in range(3):
turtle.forward(100)
turtle.right(angle)
turtle.done()
Notice
Change range(3) and the corner turn to draw a triangle — the number of sides is now yours to choose.
Run assets/l2_triangle.py the same way — a drawing window opens; close it when done.
import turtle
n = 7
side_length = 70
angle = 360 / n
for side in range(n):
turtle.forward(side_length)
turtle.right(angle)
turtle.done()
Notice
Let Python compute angle = 360 / n. The / always makes a float — a decimal like 360 / 7 = 51.428… — and the turtle turns by it just the same.
Run assets/l2_polygon.py the same way — a drawing window opens; close it when done.
import turtle
n = 7
side_length = 70
angle = 360 / n
turtle.color("blue")
turtle.pensize(2)
turtle.penup()
turtle.forward(20)
turtle.pendown()
for side_number in range(n):
turtle.pensize(side_number + 1)
turtle.forward(side_length)
turtle.right(angle)
turtle.done()
Notice
The loop counter side_number can do work too — here pensize(side_number + 1) makes each side a little thicker than the last.
Run assets/l2_polygons.py the same way — a drawing window opens; close it when done.
Lesson 3: Loops Inside Loops
One loop can live inside another — nested loops. The inner loop draws one whole shape; the outer loop turns the turtle and starts the next.
import turtle
for shape_number in range(2):
for side_number in range(4):
turtle.forward(90)
turtle.right(90)
turtle.right(180)
turtle.done()
Notice
The inner loop finishes a whole square before the outer loop turns 180° and starts the next — a loop inside a loop.
Run assets/l3_two_squares.py the same way — a drawing window opens; close it when done.
import turtle
for shape_number in range(6):
for side_number in range(4):
turtle.forward(60)
turtle.right(90)
turtle.right(60)
turtle.done()
Notice
More repeats with a smaller turn between them — six squares fan out into a ring.
Run assets/l3_rings.py the same way — a drawing window opens; close it when done.
Put it together: the gallery spirograph nests the same two loops, using angle = 360 / n for the shape and a small turn_between_shapes for the outer sweep. Compare the result with the spirograph promised at the start of the unit — you now know what both loops are doing.
import turtle
n = 6
side_length = 80
angle = 360 / n
shape_count = 24
turn_between_shapes = 15
turtle.color("purple")
turtle.pensize(2)
for shape_number in range(shape_count):
for side_number in range(n):
turtle.forward(side_length)
turtle.right(angle)
turtle.right(turn_between_shapes)
turtle.done()
Run assets/l3_spirograph.py the same way — a drawing window opens; close it when done.
Recap
forward,right,penup,pendown,colorandpensizecontrol the turtle's pen.for side in range(n):repeats a block exactlyntimes, counting from 0.angle = 360 / ngives the turn for ann-sided shape, and/always makes a float.- The loop counter can do work too, such as making each side thicker.
- In nested loops the inner loop draws a whole shape before the outer loop turns and starts the next.
You can now design and run a spirograph of your own.