Editor

Python Turtle Snowman

Beginner · Festivals · 109 lines · draws in about 12 seconds

This program builds a snowman from three filled circles and decorates it with dots, a carrot nose, stick arms, a scarf and a top hat.

Python Turtle Snowman: the finished drawing
import random
import turtle
random.seed(7)
screen = turtle.Screen()
screen.title("Snowman")
screen.bgcolor("steelblue")
t = turtle.Turtle()
def ball(x, y, radius):
"""A ball of snow centred at (x, y), with a pale blue edge."""
t.penup()
t.goto(x, y - radius)
t.setheading(0)
t.pendown()
t.pensize(2)
t.color("lightsteelblue", "white")
t.begin_fill()
t.circle(radius, steps=60)
t.end_fill()
def shape(points, color):
"""A filled shape through a list of (x, y) points."""
t.penup()
t.goto(points[0])
t.pendown()
t.pensize(1)
t.color(color)
t.begin_fill()
for point in points[1:]:
t.goto(point)
t.goto(points[0])
t.end_fill()
def arm(x, y, heading):
"""A stick arm from the shoulder at (x, y), with two twigs at the end."""
t.penup()
t.goto(x, y)
t.setheading(heading)
t.pendown()
t.pensize(5)
t.color("saddlebrown")
t.forward(85)
t.left(35)
t.forward(25)
t.backward(25)
t.right(70)
t.forward(25)
t.backward(25)
# Falling snow. Speed 0 puts every flake down at once, instead of
# making the turtle walk across the sky to each one.
t.speed(0)
t.penup()
for flake in range(70):
t.goto(random.randint(-300, 300), random.randint(-170, 215))
t.dot(random.randint(3, 7), "white")
# Snowy ground: a gentle hill made from a slice of a very big circle
t.speed(6)
t.goto(-285, -215)
t.setheading(15)
t.color("white")
t.begin_fill()
t.circle(-1100, 30, steps=30)
t.goto(-285, -215)
t.end_fill()
# Three balls of snow, biggest at the bottom
ball(0, -115, 85)
ball(0, 15, 60)
ball(0, 110, 42)
# Coal eyes, a smile and three buttons
t.penup()
for x, y in [(-15, 122), (15, 122)]:
t.goto(x, y)
t.dot(10, "black")
for x, y in [(-18, 96), (-9, 90), (0, 88), (9, 90), (18, 96)]:
t.goto(x, y)
t.dot(6, "black")
for y in [40, 12, -16]:
t.goto(0, y)
t.dot(13, "black")
# A carrot nose pointing to the side
shape([(0, 114), (40, 107), (0, 102)], "darkorange")
# Stick arms
arm(-55, 35, 150)
arm(55, 35, 30)
# A red scarf: a band round the neck and an end hanging down
shape([(-44, 78), (44, 78), (46, 62), (-46, 62)], "crimson")
shape([(16, 66), (40, 66), (50, 14), (28, 12)], "crimson")
# A black top hat with a red band
shape([(-52, 144), (52, 144), (52, 152), (-52, 152)], "black")
shape([(-33, 152), (33, 152), (33, 212), (-33, 212)], "black")
shape([(-33, 156), (33, 156), (33, 168), (-33, 168)], "crimson")
t.hideturtle()
turtle.done()

How the code works

A function for each ball of snow

t.color("lightsteelblue", "white") sets two colours at once: a pale blue pen for the edge and white for the inside. Starting at the bottom of the ball puts its centre at (x, y).

def ball(x, y, radius):
    """A ball of snow centred at (x, y), with a pale blue edge."""
    t.penup()
    t.goto(x, y - radius)
    t.setheading(0)
    t.pendown()
    t.pensize(2)
    t.color("lightsteelblue", "white")
    t.begin_fill()
    t.circle(radius, steps=60)
    t.end_fill()

Arms with twigs

Each arm goes 85 steps from the shoulder. At the end the turtle turns 35 degrees left for one twig and 70 degrees right for the other, going back after each one.

def arm(x, y, heading):
    """A stick arm from the shoulder at (x, y), with two twigs at the end."""
    t.penup()
    t.goto(x, y)
    t.setheading(heading)
    t.pendown()
    t.pensize(5)
    t.color("saddlebrown")
    t.forward(85)
    t.left(35)
    t.forward(25)
    t.backward(25)
    t.right(70)
    t.forward(25)
    t.backward(25)

Three balls, biggest at the bottom

Each ball is smaller than the one below and overlaps it a little, so there are no gaps. The bottom ball sits over the top of the snowy hill.

ball(0, -115, 85)
ball(0, 15, 60)
ball(0, 110, 42)

A face made of dots

Each loop goes through a list of places and puts a black dot at each one: two eyes, five dots in a curve for the smile, and three buttons down the middle.

for x, y in [(-15, 122), (15, 122)]:
    t.goto(x, y)
    t.dot(10, "black")
for x, y in [(-18, 96), (-9, 90), (0, 88), (9, 90), (18, 96)]:
    t.goto(x, y)
    t.dot(6, "black")
for y in [40, 12, -16]:
    t.goto(0, y)
    t.dot(13, "black")

Make it yours

Change the code above and press Run. Some ideas:

  • Change arm(-55, 35, 150) and arm(55, 35, 30) to headings 210 and -30 so the arms point down.
  • Change "crimson" in the two scarf lines to "royalblue" for a blue scarf.
  • Change range(70) to range(150) for heavier snow.

What it uses

Every turtle command the site supports is listed on Python turtle online.