Functions & Colour

Your mandala loop works, but it's anonymous. To draw a polygon anywhere else, you'd have to copy the whole block again, and copying code always comes back to bite you. A function gives the block a name and turns its numbers into knobs.

Defining a Function

def draw_shape(sides, length, colour):
    t.color(colour)
    exterior_angle = 360 / sides
    for _ in range(sides):
        t.forward(length)
        t.left(exterior_angle)
  • def starts the definition. The indent rule is the same as loops: the body is the indented block.
  • sides, length, colour are parameters: local variables whose values arrive when the function is called.
  • The loop inside is unchanged from before. You've only named it and exposed three knobs.

Calling it:

draw_shape(4, 80, "#E63946")    # a red square
draw_shape(6, 50, "#A8DADC")    # a small pale-blue hexagon
draw_shape(3, 100, "#F4A261")   # a big orange triangle

One call, one shape. By the end of the day this little function gets called 80 times, so it's worth getting friendly with it now.

Vocabulary, briefly: parameters are the names in the def line; arguments are the values you pass at the call site. You can also pass by name, like draw_shape(sides=5, length=60, colour="#E63946"), which helps when a function has many parameters.

Hex Colours

Named colours like "coral" only go so far. A hex code like #E63946 specifies any colour exactly. Two things make them work here:

  • turtle.colormode(255), already in the setup block, switches turtle to accept hex strings. If you move or duplicate that line you'll get a TurtleGraphicsError, so leave it in SETUP.
  • VS Code shows a little colour swatch next to any hex string in your file. Click the swatch to open a colour picker.

Define your palette as a list of 3 to 6 colours that belong together:

PALETTE = ["#E63946", "#F1FAEE", "#A8DADC", "#457B9D", "#1D3557"]

This is a design decision rather than a technical one. Monochrome, warm/cool, complementary... pick a direction, not six random favourites.

Instant Rendering

Two lines already in your file make drawing instant instead of animated:

  • turtle.tracer(0, 0) (top, in SETUP) turns off the line-by-line animation.
  • screen.update() (bottom) displays everything drawn in memory.

Don't delete either. Without them, 80 shapes take about 10 seconds to crawl onto the screen. With them, it's instant.

Try It: sides=2

Predict first: what does draw_shape(2, 80, ...) draw? A crash? Nothing? Run it. You get a stripe, which is just two forward moves with a 180° turn between them. Not an error. Just geometry, following the rule you gave it.

Stretch Challenges

  • Default parameter: change the signature to def draw_shape(sides, length, colour="#1D3557"): and call it with only two arguments. What happens?
  • A draw_row function: write a second function that calls draw_shape five times in a horizontal row, using penup()/goto()/pendown() between calls.
  • Filled shapes: wrap the loop in t.begin_fill()t.end_fill() to draw solid polygons instead of outlines.