Turtle Graphics
using Python

We shall take a look at programming, having fun.

Computer Programming

Computers are machines. They perform tasks by instructions: In short, we need a programming language to instruct computers to work.

Like human languages, there are many programming languages. However, ideas are the same: every language can express numbers (1, 2, 3), characters ('a', 'b', 'c'), strings ("apple", "orange"), and others to represent data.

Programming languages are used to express programming ideas:

Python in Browser

For a demonstration, we shall use a version of Python【1】running in a browser.

Once the webpage is loaded, you'll find an editor on the left, and a drawing board (also called the canvas) on the right. The editor may have a program loaded, in an editor tab called main.py. The drawing board shows the result of running the program.

We shall begin with a clean sheet, so clear the program on the left. Move the cursor along the top, click dropdowns (▽) to be familiar with the buttons.

Making a Turtle

Start by typing this line:
import turtle
This loads the module turtle, some codes written by a team so that we can make use of it to draw graphics. We name our little turtle bob, and create it by invoking the contructor Turtle():
bob = turtle.Turtle()
So far we have two lines. If you 'run' this program (the button ▷), there is nothing shown on the drawing board. Now add these two lines:
bob.shape("turtle")
bob.speed(10)
Click 'run' again, and bob appears on the drawing board!

So far, there are 4 lines for the program. We can add comments in Python, prefix by #, to explain what they are doing:

import turtle          # load module
bob = turtle.Turtle()  # construct turtle instance

bob.shape("turtle")    # give bob a shape
bob.speed(10)          # set speed for bob
We shall type more lines later, but these 4 lines will stay.

Moving a Turtle

Now bob is an object, let us make bob move. Any turtle can respond to certain methods: To make an object respond to a method, put them together with a dot '.' as connective. Try these three lines:
bob.fd(100)
bob.lt(90)
bob.fd(100)
Click 'run' and see how bob moves. Now replace these 3 lines by:
for j in range(4):
   bob.fd(100)
   bob.lt(90)
Note the indentation, which is required for Python. Run and bob will draw a square. Can you see why?

The above is a Python for-loop, with range(4) giving the list [0, 1, 2, 3]. The index j takes each value of the list, successively. The effect of this for-loop is to repeat the indented body 4 times. Each time the body code runs, bob moves forward and makes a left right-angle turn. This draws one side of a square. Repeating 4 times draws the complete square.

Using a Function

Now bob can draw a square, but we would like bob to draw many squares. Surely, we don't want to retype the square for-loop again and again. To simplify the work, we shall use a function.

In math, a function looks like this: f(x) = 2 ⁎ x + 3. The function has a name f, and works on a variable x. The variable x is the input, and f(x) gives the formula for the output. A function can have more variables. For example, g(x,y) = 2 ⁎ x + 3 ⁎ y. The important idea of a function is: variables are input, the function formula gives output.

In programming, a function also has a name, with input variables called parameters, and the formula is replaced by a body of instructions, giving output action. The parameters, like variables, are symbols to be substituted in the body to produce specific actions. Let's see this in Python.

Remove the for-loop, and define a drawSquare function, with turtle and size as parameters:

# draw square for turtle, with size
def drawSquare(turtle, size):
   for j in range(4):
      turtle.fd(size)
      turtle.lt(90)
In Python, def is the keyword to signify the definition of a function. After specifying the name with parameters in brackets, a colon (:) terminates this declaration. This is followed by an indented body of the definition, which is the previous for-loop, but using the parameter turtle instead of bob. The forward movement takes the parameter size, so that drawSquare(turtle, size) can be applied to any turtle and draws a square of any size.

After typing in this definition, add a blank line, and invoke it by this line:

drawSquare(bob, 100)
This means drawSquare(turtle, size) is applied with actual parameters turtle = bob, and size = 100. Run this code, and surely bob draws the same square. Change this line to:
drawSquare(bob, 150)
and bob draws a bigger square. We can go on to teach bob to draw a picture building from squares. Before we do that, we would like to convert this function to a method for the object.

Using a Method

Recall that the turtle bob is an object. An object responds to its methods. For example, bob.fd(100) means bob responds to the method forward, with a step size 100. Therefore, methods are functions attached to an object, for an object to respond to.

Wouldn't it be nice if we can write bob.square(100), so that bob can respond to a method with step size 100, by itself? Maybe we can teach bob other methods, so that eventually bob can respond and draw a beautiful picture for us!

In Python, there are several ways to do this. One way is to reuse our code drawSquare:

# cast method for object
bob.square = drawSquare.__get__(bob)
Remove the line 'drawSquare(bob, 150)', and type in the lines above. The line means we set a method square for bob, which is the function drawSquare with the first parameter turtle substituted by bob. Thus bob.square needs only 1 parameter, the size of the square. We can test this by:
bob.square(100)
Run it, and now bob draws a square by itself, responding to its own method.

Compose a Picture

Comment out the test 'bob.square(100)' by inserting a # at the very start. Type in the following lines, and see if you can imagine what a turtle will draw as a result:
# draw a picture
def drawPicture(turtle, size):
   for j in range(36):
      turtle.square(size)
      turtle.lt(10)
The body of the for-loop tell a turtle to draw a square, then turn left by 10 degrees. The for-loop will repeat the body 36 times, thus the turtle will turn 36 ⁎ 10 = 360 degrees, a full circle. Can you figure out the final picture?

Before we test this, we can convert this function into a method by the same trick above:

# cast method for object
bob.picture = drawPicture.__get__(bob)
Now we test this by running:
bob.picture(100)
Does the picture match what you expect?

Turtle Documentation

The turtle bob is an object, and it responds to methods of two types: To find out all methods attached to object bob, first we need to run our code in the console mode. This is achieved by clicking the drop-down ▽ (next to ▷), and choose 'Console', and the icon for 'run' changes to that of the console. Meanwhile, you can read some output in another window, ending with:
>>>
This shows up in color green, and represents the console prompt, waiting for some input text here. Now if you place the cursor after the green prompt, and type:
dir(bob)
The console window will give the following output (you can resize the console window):
>>> dir(bob)
['__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__',
 '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__repr__',
 '__setattr__', '__str__', 'back', 'backward', 'begin_fill', 'bk', 'circle', 'clear',
 'clone', 'color', 'degrees', 'delay', 'distance', 'done', 'dot', 'down', 'end_fill',
 'fd', 'fill', 'fillcolor', 'forward', 'getpen', 'getscreen', 'getturtle', 'heading',
 'hideturtle', 'home', 'ht', 'isdown', 'isvisible', 'left', 'lt', 'mainloop', 'onclick',
 'ondrag', 'onrelease', 'pd', 'pencolor', 'pendown', 'pensize', 'penup', 'picture',
 'pos', 'position', 'pu', 'radians', 'reset', 'right', 'rt', 'seth', 'setheading',
 'setpos', 'setposition', 'setundobuffer', 'setx', 'sety', 'shape', 'showturtle',
 'speed', 'square', 'st', 'stamp', 'towards', 'tracer', 'undo', 'undobufferentries',
 'up', 'update', 'width', 'window_height', 'window_width', 'write', 'xcor', 'ycor']
The command dir gives the directory of object bob. The output is a list of methods known to bob. Only picture and square are user-defined methods, all others are built-in methods. There are some method aliases: fd as forward, lt as left, bk as back and backwards, rt as right, etc.

If you examine the build-in methods for bob, there is this one: circle. To find out its parameter, we need to check out the full documentation of the module turtle.

Click the question mark "?" button (next to ▽) for a list of available modules for Trinkets Python, in a new tab. Click "turtle" to find a list of built-in methods for turtles, with details. Locate the method circle, and find its signature circle(radius) -- ignore the optional arguments for now.

Scroll down a bit to find also the method color, and some examples of using it.

Back to the Python tab, we can change the drawPicture code by commenting out a line, and inserting another line:

      # turtle.square(size)
      turtle.circle(size)
Also, add this line before 'bob.picture(100)', so that they become:
bob.color('pink')
bob.picture(100)
If you have resized the console window, resize it again to as low as possible. Now change the 'Console' back to just 'Run' using the drop-down ▽, and see the result on the drawing board. Isn't that beautiful?
Click to enlarge (click again to close)   
Think Python (2nd Edition) by Allen B. Downey.

Python Thinking

Flip to the Documentation tab, and find a big blue button 'Example'. Click it for a demo. See the picture on the right. Now read the Python code on the left. You should be able to figure out how the picture is produced.

You can find the official Turtle Graphics documentation at【2】, and source code in【3】. They give the background and history of this module. Although the source code is not easy to understand, note that it is a single file, entirely written in standard Python.

More examples of turtle graphics can be found in Allen B. Downey's Think Python: How to think like a computer scientist 【4】, chapter 4. This book has a comprehensive treatment of Python in various computer science applications, including the last chapter: analysis of algorithms.




Epilog

Click to enlarge (click again to close)   
On March 9, 2016, the worlds of Go and artificial intelligence collided in South Korea.
Python is a programming language used widely in the field of data science, and for integration among engineering systesm. It is popular among game developers, web developers, cybersecurity professionals and others. Python is also used in machine learning for artificial intelligence projects. In 2016, AlphaGo【5】beat the world's Go champion using the techiques of deep learning: learning and extracting strategies by playing between a clone of itself millions of games.

Happy Python coding, with turtles!

Links