3.1 Introduction
This sheet will teach you a little about doing graphics (pictures or drawings) in Python. It will also explain a very important idea in programming: functions or procedures.
It's quite a long sheet. Don't worry if it takes you a while to get through it all.
3.2 What you need to know
- How to edit and run a Python program.
- What coordinates are (if you aren't familiar with these, you may want to talk with your math teacher about them.)
3.3 Points, lines and colors
In Sheet 1 (Introducing Python), you saw a rather boring example of graphics in Python. Let's go over it again, a little more carefully. It began like this:
from gasp import * begin_graphics()
and ended with the line end_graphics().
The first line there should be familiar by now. The second tells the
computer to make a new window in which you can put lines and circles and
things. The last line, end_graphics(), waits for the graphics
window to be closed and then resets some things so that you can say
begin_graphics() again to start over cleanly.
All the interesting stuff happens in between.
from gasp import * begin_graphics() Line((200,100),(100,300))
To understand these lines, you need to know how Python (actually, this isn't
Python itself so much as the gasp module, which is why you have to type from gasp import * at the beginning of all your python code.)
thinks about graphics.
Pixels
The graphics window -- like everything on the computer screen -- is made up
of pixels: little squares or rectangles of color. If you look closely
at your computer screen, you'll see what I mean. (Why the funny name
pixels? It's short for picture element
.)
You refer to places in the graphics window by their coordinates: first, how many pixels the place is to the right of the left-hand edge of the window (the x-coordinate), and then how many pixels it is above the bottom of the window (the y-coordinate). Here's a picture.

The current point
(When you read Sheet 1 (Introducing Python), I hope you actually tried typing in those commands I'm talking about now. If you didn't, go back to Sheet 1 (Introducing Python) and type them in now.)
The command beginning with Line does exactly what it sounds
like it should do - it draws a line. In this case it draws a line starting
from the pixel called (200, 100) to the pixel called (100, 300). (Because both
points have a different y-coordinate (second part) and
x-coordinate (first part) the line is drawn at an angle.)
You might (or might not) find it helpful to imagine a little man, or a
robot, walking around the graphics window. When you say
Line((200,100),(100,300)) the robot walks over to (200,100), then
drops a little marker at the pixel then as it walks over to the second point
(100,300) it draws a line underneath it creating the line you see on the
screen.
3.4 Facing the facts
Let's try to draw something a little more interesting than a plain old line. How about a face? (Later you can even go further than that by drawing a whole person.)
Unfortunately, it's not easy to draw anything at all like a face with straight lines. Faces are sort of round, after all. So...
Going round in circles
...you need to be able to draw things that are sort of round. Circles, for instance. Try this little program.
from gasp import * begin_graphics() Circle((300, 200), 100)
The three numbers are the two coordinates of the center of the circle, and the radius of the circle (i.e., the distance from the center to the edge). Try running the same program but with different values for the three numbers, to make sure you understand what they all do.
What does this do? (Try to guess before you actually run it.)
from gasp import * begin_graphics() for r in 100, 110, 120, 130, 140: Circle((300, 200), r)
If you still aren't sure, ask for help...
So, what about drawing that face? Try to draw something that looks a bit like this:

In other words, you'll need to draw
- One large circle (around the outside)
- Two small circles (the eyes)
- Part of a circle (the mouth)
- Two straight lines (the nose)
You'll find this easier if you have a bit of squared paper or graph paper. Failing that, you might find it helpful to draw some for yourself! Then, sketch the face on the squared paper:

(If you're really too lazy, you can just use the face-on-a-grid above!)
That grid is 10 squares on each side. Let's suppose that the very center of the grid is the point (300, 200) (there's nothing special about that point; it's just somewhere near the middle of the graphics window), and that each of our little grid squares is 10 pixels across.
The mouth is a little tricky, so we'll worry about that a little later on. Everything else should be pretty easy to locate. For instance, the big circle has its center at (300, 200) and its radius is 4 small squares, or 40 pixels. The left eye has its center at (285, 210) and its radius is 5 pixels (half a square). I'll let you work out all the other coordinates you need. So:
Write a program that draws all of that face except the mouth.
Mouthing off
The mouth, as I said, is harder. You need to be able to draw just
part of a circle. You can do this by using a special command just like
Line and Circle, this time called Arc.
All you need to know is where the center of the arc will be, the radius of the
circle, and then two angles. These angles determine where on the circle the
computer starts and stops drawing.
It turns out that what you need to add to your program is:
Arc((300, 195), 10, 180, 360)
That's a bit intimidating, so I'll try to explain. First you give the center of the circle, just as if you were drawing all of it. Then you tell the computer the radius of the circle, just like when you drawing a full circle. The last set of numbers are the angles, since a circle is made up of 360 degrees, that's what you'll use to tell the computer where to start and stop drawing the circle.
What should happen when you type Arc((300, 195), 10, 180, 20)?
What actually happens?
The reason this happens is because when you pass the 360 mark on a circle,
it doesn't automatically jump back to 0. Instead it keeps on counting. This
means that instead of Arc((300, 195), 10, 180, 20), you need to
type Arc((300, 195), 10, 180, 380).
Challenge: Modify your face-drawing program so that it draws the face in a different place. You'll need to change all the numbers that define positions of points. You won't need to change the numbers that say how big the circles are!
Challenge: Make some other changes to the face, to get the hang of how these graphics commands work. For instance:
- Move the eyes up a little.
- Add eyebrows (lines across the eyes, maybe sloping a bit)
- Add ears, or hair.
- Change the shape of the nose slightly.
3.5 Two heads are better than one
What if you wanted to draw two of these faces?
You could copy out everything in your program twice, and then change one copy. This would work, but it would be boring and easy to get wrong. And if you then wanted a third face, you'd have to go through all the effort again.
There's a better way.
You already know that Python lets you give names to numbers, strings, lists and other things. It also lets you give names to bits of program. A piece of Python program with a name is called a function (for complicated reasons that don't matter just now). Sometimes the word procedure is used instead. (For instance, the language Logo -- which you may have used in school -- calls them procedures.)
Functions
Type in the following. (The prompt Python prints at the start of each
line will change, like in the for loop examples way back in
Sheet 1 (Introducing Python). Don't forget
to look out for spaces at the starts of lines!)
>>> def shout(): ... print 'Python is wonderful!' ... print 'And so am I.' ... # Just press Enter here.
What you've just done is to teach Python a new trick. If you now say
>>> shout()
what do you think will happen? Try it. What you've done is to define
a new word that Python will understand. (def is short for
define.)
Challenge: Write a definition so that saying moan()
will make the machine print:
Python is useless! And so are these worksheets.
Try it out and make sure it works.
A good argument
Functions are more than just ways of saving typing, though. Try typing in the following definition, and think about what it might mean.
>>> def twice(x): ... print x, '+', x, 'is', x + x ... # Just press Enter here.
When you think you understand it (or when you've decided you'll never
understand it), experiment with it. Ask Python for twice(3), or
twice(99), or even twice('ouch').
What's going on here is rather clever. When you say twice(7),
the machine does the stuff inside the definition of twice (just
like it did for shout and moan earlier), except that
x is 7. So it's rather as if you'd said
print 7, '+', 7, 'is', 7 + 7
For some reason, things that get inside function definitions in this way are
called arguments. So, when you say twice('beri'), the
string 'beri' is the argument to the function twice.
You'll need to know this word to understand what happens if you type
twice() instead of twice(7). (Try it.)
Challenge: Write a function that behaves a bit like
twice but, instead of telling you what x+x is
(where x is the argument of the function), tells you what
x*x is. Try it out. (Unfortunately it won't work on strings!)
A function can have more than one argument. The way this works is pretty obvious once you've seen it, so I'll just give an example.
def add(x, y): print x, '+', y, '=', x + y
Then you can say add(7, 5) and the computer will tell you what
happens when you add 7 and 5.
Built-in functions
Incidentally, lots of the things you've told Python to do are really
functions. For instance, when you say Line((100,200), (300, 150))
you're just using a function with two arguments (two sets of coordinates). The
only difference is that you didn't have to write the definition of the
Line function yourself.
As I was saying...
This is all a digression. Before I started blathering about functions, you were thinking about how to draw two (or more) of those faces. Maybe you've guessed what's coming next: the Right Thing to do is to write a function that draws a face. The function should take arguments saying where in the graphics window the face should go. When you've done that, drawing 5 faces will just mean 5 uses of your function, instead of having to copy out the face-drawing program 5 times and make lots of changes to each copy.
So, what should your face-drawing function look like?
It needs to be able to be told where to draw the face, so let's give it two
arguments saying where (like the two arguments to move or
draw).
So far, you know that the function will look like this.
def draw_face(x,y): blah blah # Whatever you need to draw a face at (x,y)
Obviously filling in the blah blah is the difficult bit.
What exactly should the arguments, x and y, mean?
When you were designing the face, you thought about the positions of all the
bits of the face relative to the point right in the middle of the big circle.
(That was (300, 200), remember?) So a reasonable idea would be to say that
x and y are the coordinates (i.e., the two parts of
the name) of the pixel right in the middle of the face. So, saying
draw_face(300, 200) ought to do exactly the same as the program
you've already written.
Challenge: If you're feeling brave, go back to your face-drawing program and try to turn it into a face-drawing function. Then test the function. --- If you're not feeling brave, read on and I'll try to lead you through the process.
(If you want to take up that challenge, you should stop reading right now.)
To begin with, edit your face-drawing program so that instead of saying
first line second line third line etc
it says
def draw_face(x, y): first line second line third line etc
You now have a function that takes two arguments, and then ignores them and
draws a face centered at (300, 200) whatever the arguments were. Now you need to
tidy it up so that the face is centered at (x, y)
instead.
The outline
The first thing you drew originally was the circle around the outside of the face. This also happens to be the easiest thing to adapt for putting into our function.
Originally, you had a line Circle((300, 200), 40). The first
two arguments to Circle say where the center of the circle is,
so they should become x, y. The last argument (40)
says how big the circle is. All your faces are going to be the same size, so
that should be left alone.
(Incidentally, you'll find all this much easier to follow if you look at the face-on-a-grid earlier in this sheet.)
So the new line should be circle((x, y), 40).
The eyes
You drew the eyes next. Originally the eyes were at (285,310) and (315,310): 15 pixels away from the middle horisontally (one in each direction), and both 10 pixels above the center.
Well, that's easy enough. Here's how to draw the left eye; you can probably work out how to draw the right eye.
Circle((x-15, y+10), 5)
The nose
The nose is made up of two lines. The first one goes from 10 pixels above the very center of the face to 10 pixels leftward and 10 pixels downward from the center. That's easy enough.
Line((x, y+10), (x-10, y-10))
The second line goes from where the first one left off, to a point 10 pixels down and 10 pixels to the right from the center of the face. I'll leave drawing that line up to you,
The mouth
You might expect this to be harder than the other bits. Instead, it's only about as difficult as figuring out the eyes.
The reason for this is that you only need to edit two of the numbers - the coordinates of the circle. This is because the other numbers (the radius and the angles) are all based off of the coordinates of the arc, not the center of the face.
I'm going to be mean, and leave you to work out exactly how to adapt the line of program that draws the face's mouth. It really isn't very difficult.
Does it work?
Test your function. Add a few lines below it:
draw_face(300, 200) draw_face(400, 200) draw_face(350, 270)
and run the program. Do you get three heads? Or a ghastly mess of detached bits of head? Or what?
draw_face, because until it's read that definition the
computer doesn't know what draw_face is.
3.6 The whole person
If you've had enough of graphics, you might want to skip ahead a little. But if you're still having fun, you might like to use your head-drawing function to make a person-drawing function.
Here's a simple stick figure. Sketch something like this on graph paper or
squared paper, and use it to design a function that draws a stick person.
Where I've just drawn a circle for the head, you should actually use the
draw_face() function.
I don't know what should go in here

This may take you a while. You'll have to think carefully about what arguments
you give to draw_face to make the head and the body fit together
properly.
Make sure your functions work by making your program draw several stick figures in different places on the screen.
You may well find it much easier if you start by just drawing a single stick figure anywhere, and then turn it into a function in the same sort of way as you did for the face.
Challenge: Work out how to give one of your stick figures a hat.
I don't know what should go in here
3.7 Some nice patterns
This doesn't have anything to do with the stick figures. I'm just including it because I think it looks nice. Give it a try and see if you agree.
from gasp import * begin_graphics() for i in range(0, 400): Line((i, 0), (0, 400-i))
The weird thing about this is that all it does is to draw a lot of straight lines, but the result is to produce a nice smooth curve!
3.8 Ending it all
At the end of any program that draws graphics, you should actually have a line
end_graphics()
to tell the computer that you're finished with the graphics window. When it sees that line, the computer will sit and wait until you close the graphics window. (If it just went ahead and closed it for you, you might not have time to see what it had drawn in the window. That would be a shame.)
3.9 What next?
- Read Sheet G (Graphics/Gasp) for more information on doing graphics with Python
- Work out how to draw faces and people of different sizes as well as in different places. Work out how to make them face in different directions, too. Then you can draw a scene in which some of them are talking to others, or standing alone, or whatever.
You could also just go on to Sheet 4 (Higher! Lower!), in which you'll write a simple game. (It doesn't use graphics, I'm afraid.)