Assignment 4: Turtles



CS 1110: Introduction to Computing Using Python

Assignment 4:

Computer graphics can be tricky, and you often need a lot of experience with programming
before you can get started. However, for over forty years, the LOGO Turtle has allowed
elementary-school students to draw cool and interesting shapes on their computer. And if
they can do it, so can you.
The Turtle is a cursor on the screen that uses a Turtle for its icon. To draw a line, you push
the Turtle forward. The screen draws a line of the same color as the Turtle (which can be
changed at any time) along its path of movement. To draw more interesting shapes, you
simply change the direction of the Turtle. With a few more commands you can even draw
solid shapes.
While programming languages have come a long way since the early days of LOGO, the
graphics Turtle lives on. Every major programming language, from C/C++ to Java to Python,
has a version of the Turtle. For today’s assignment you get to participate in this 50 year
tradition, and hopefully have some fun in the process.
This assignment is a little harder than the previous one, but you have two full weeks to work on it. In the past we have found this to
be more than enough time for this assignment. But get started early! If you do not know where to start, or if you are completely
lost, please see someone immediately: either the instructor, a TA, or a consultant. A little in-person help can do wonders.
Again, please remember to fill out the survey telling us how long you worked on this assignment.
Learning Objectives
This assignment serves several important roles.
It introduces you to the famous Turtle, which is a great way to learn a new language.
It gives you experience with writing simple for-loops.
It gives you experience with recursion.
It gives you experience with complex objects that have both attributes and methods.
It gives you experience with using asserts to enforce your preconditions.
Table of Contents
Authors: D. Gries, W. White, L. Lee, S. Marschner.
Academic Integrity and Collaboration
Turtle Graphics
Assignment Source Code
Drawing with the Turtle
Assignment Instructions
Asserting Preconditions
Task 1. Triangles
Task 2. Hexagons
Task 3. Radial Shapes
Task 4. Sierpinski Shapes
Task 5. H-Trees
Finishing the Assignment

Turtle Graphics
Python actually has a built-in Turtle provided by the turtle module. However, we find this module a bit confusing to use,
particularly for a beginner. Instead, we provide an alternative Turtle, which we call the Tk Turtle. This Turtle is provided by the
module cornell, which you should be well familiar with right now.
Assignment Source Code
This assignment is much more bare-bones than previous ones. There is only one file to download:
This is file contains stubs for all the functions in this assignment, and is the file you will submit for a grade.
To save you time, we have given complete specifications of most of the functions you are to write. Study them carefully. Note how
precise and thorough they are. You should aim for this level of quality when you start to write your own specifications.
You will not be creating a test script this time. Writing test cases for graphics is almost impossible. Therefore, you will be looking
at the the drawings produced by your functions to determine correctness.
However you will notice that you can actually run as a script. Run it as a script by typing
You will see that it asks you yes/no questions. Answer ‘y’ to this first question. The turtle will draw two lines for you. In general,
answering ‘y’ will call the specific drawing function so that you can test it. Any other answer will skip over that drawing function.
Since drawing can take a long time, this gives you a nice way to test only the specific drawing function that you are working on.
However, right now it does not do much. That is because you have not started on the assignment.
If you want more control over your testing, you will need to import the functions of manually. To do this, you need to
understand the cornell module a bit more. This module provides three classes: Window, Turtle, and Pen.
To create a window, you use the constructor Window() and assign the result to a variable. Try this command at the interactive
>>> import cornell
>>> w = cornell.Window()
This will display a window on your screen. The window object has several attributes that you can change.
Attribute Meaning Invariant
w.x x-coordinate of top left corner Must be an int
w.y y-coordinate of top left corner Must be an int
w.width Width of the window in pixels Must be an int
w.height Height of the window in pixels Must be an int
w.title Title at top of window Must be a string
Try changing the values of these attributes (with assignment statements). For example, what happens when you type the following
12/21/2018 CS 1110: Assignment 4 3/10
>>> w.width = 100
In addition, there are two important methods:
This erases the contents of the Window. It also detaches any Turtles so that they no longer work.
This closes the Window permanently.
Pixels inside of the window follow a rather intuitive coordinate system. The point (0,0) is the center of the window. The xcoordinates get larger to the east and the y-coordinates get larger going up.
The Turtle class is used to draw on your Window. Each Turtle object t has the following important attributes:
Attribute Meaning Invariant
t.x x-coordinate of the Turtle Must be an int or float.
Cannot be altered directly
t.y y-coordinate of the Turtle Must be an int or float.
Cannot be altered directly
t.heading Turtle heading in degrees counter-clockwise from east. Must be an int or float.
t.color Current Turtle color Must be a string, an RGB object, or an HSV object.
t.speed The drawing speed of this Turtle. Must be an int 1 (slowest) to 10 (fastest), or 0
t.visible Whether the Turtle icon is visible. Must be a bool
t.drawmode Whether the Turtle should draw anything when it moves; if
False, nothing is drawn. Must be a bool
To create a Turtle, you use the constructor Turtle() which takes a single argument: the Window that you want to draw on.
Assuming that you made a Window object w in the previous section, try the following at the interactive prompt:
>>> t = cornell.Turtle(w)
You should now see a (red) Turtle on your Window! The Turtle will always start at coordinate (0,0), which means it is centered in
the window.
The fact that Turtle and Window are separate allows you to have as many Turtles as you like so that you can draw different things
with them. If at any time you have too many Turtles, use the method w.clear(). This removes all Turtles from the Window
(which means that attempts to do anything with any old Turtles will fail), so you will need to add a brand new Turtle to start
drawing again.
Position and Orientation
The position and heading of the Turtle are maintained using floating point numbers. This is needed
for accuracy. If integers were used, errors would be introduced after only a few calculations.
However, whenever a point is to be drawn in the window, its x- and y-coordinates are rounded to
the nearest integer because the pixel coordinates are represented as integers.
The direction of the Turtle is called its heading. It is a number representing the angle in degrees
counterclockwise from east (to the right). Thus east is 0 degrees, north is 90 degrees, west is 180
degrees, and south is 270 degrees. Negative angles and angles greater than 360 are allowed; the
remainder modulo 360 is used.
While the heading attribute can be modified, the x and y attributes cannot. You can only control the Turtle’s position via the
methods listed below.
Important Methods
In addition to its attributes, a Turtle object t has several important methods:
Moves the Turtle dist pixels in the direction of its current heading. If the drawmode is True, a line is drawn; otherwise, no
line is drawn.
Moves the Turtle dist pixels in the opposite direction of its current heading. If the drawmode is True, a line is drawn;
otherwise, no line is drawn.
Rotates the Turtle in place a degrees counterclockwise.
12/21/2018 CS 1110: Assignment 4 4/10
Rotates the Turtle in place a degrees clockwise.
Moves the Turtle t to pixel (x,y) without drawing anything.
Note that most of these methods are used to move the Turtle about the screen. This is why the attributes x and y cannot be altered
directly (e.g. you cannot assign values to them). You should use these methods instead.
To change the Turtle color, you assign a new value to the color attribute. You can use the RGB and HSV objects from the last
assignment. You cannot use a CMYK object with a Turtle; that color model is designed for printing, and not for displaying on your
The Turtle also supports strings as colors. Just put the name of the color that you want in quotes; make sure the name is all lower
case. For example, to make your Turtle blue, try
>>> t.color = ‘blue’
As you will discover with this assignment, the turtle can be quite slow. You can control the speed of the Turtle by setting is speed
attribute. It is a number in the range 1 ≤ speed ≤ 10, with 1 slowest and 10 fastest. You can also set the speed to 0, which causes
shapes to be drawn with no animation. However, even when the speed is set to 0, you will see the the Turtle draw each line
individually, so sometimes shapes can take a while to draw (this is an unfortunate issue with the way the Turtle is implemented in
Drawing with the Turtle
Throughout this assignment, you will be asked to draw shapes with a Turtle. There are three ways to do this. The first is to type
Turtle commands directly in the Python interactive shell. You should do this right now to familiarize yourself with the Turtle
class and its methods. For example, try these commands:
>>> import cornell
>>> w = cornell.Window()
>>> t = cornell.Turtle(w)
>>> t.color = ‘green’
>>> t.forward(100)
>>> t.color = ‘red’
>>> t.right(90)
>>> t.forward(150)
As you type the lines up to and including t = cornell.Turtle(w), you will see a window appear with a Turtle at the center
facing west. As you type the other commands, the Turtle will change color, move, and draw lines.
The second way to draw is to add new procedures to the module and call them from the interactive prompt. If you look at
the file, you will notice that it contains a procedure draw_two_lines. We gave you this procedure to show you how to write a
graphics procedure. Note that it takes the Window object as an argument, so it does not create a new window. It also does not
clear the Window, though we might want our other functions to do that. All it does is create a Turtle, and use that Turtle to draw
two lines.
To try out this function, navigate to the directory containing the file and start up the interactive prompt. Then type:
>>> import cornell
>>> w = cornell.Window()
>>> import a4
>>> a4.draw_two_lines(w,2)
This will draw two lines in the window w, at speed 2. Study the body of draw_two_lines, as it will help you with all of the tasks
in this assignment.
For the remainder of this assignment, you will be writing procedures that draw shapes, much like draw_two_lines. As you write
a procedure, refer constantly to the specification. Follow it carefully. If you have to call another procedure, look at its specification
and make sure you follow it. A huge number of programming errors arise from not following specifications carefully.
Objects of type Pen are very similar to Turtle objects, except that they draw a bit differently. Creating a Pen is similar to creating a
Turtle. At the interactive prompt try
12/21/2018 CS 1110: Assignment 4 5/10
>>> import cornell
>>> w = cornell.Window()
>>> p = cornell.Pen(w)
The pen icon does not look like a turtle. Instead, it looks like a triangle on its side. This Pen object has a lot of attributes in common
with Turtle. It is colored with the current drawing color, and it draws from the tip on the right.
However, the Pen does not have a heading attribute. Instead, for a Pen object p, you draw with the following methods.
Draws a line starting from the current Pen position with distance dx pixels along the x-axis and dy pixels along the y-axis.
Draws a circle of radius r (in pixels) centered at the current Pen position.
Moves the Pen p to pixel (x,y) without drawing anything.
Solid Shapes
The Pen also does not have a drawmode attribute. The three methods listed above either always draw (drawLine, drawCircle)
or never draw (move). What the Pen has is a fill attribute. When this attribute is True, the Pen will enter into a “fill mode”.
Anything that is drawn between now and when the attribute becomes False (or when a call to move is made) will result in a solid
For example, to draw a solid square, try the following sequence of commands with your Pen.
>>> p.fillcolor = ‘blue’
>>> p.fill = True
>>> p.drawLine(0,50)
>>> p.drawLine(50,0)
>>> p.drawLine(0,-50)
>>> p.drawLine(-50,0)
>>> p.fill = False
When you finish, the pen will fill the insides of the square with the color blue.
Because the pen can draw solid shapes, it actually has two color attributes: fillcolor and pencolor (there is no simple color
attribute in Pen). The fillcolor is the color it uses inside a solid shape, and pencolor is the color for hollow shapes as well as
the border of solid shapes.
Assignment Instructions
This assignment is broken up into five tasks. Each task corresponds to a procedure stub (or collection of stubs) in You will
find this assignment to be a lot easier if you complete and fully test one task before moving on to the next.
We do not require that you make a test module this time. We have provided the test procedure main() which calls the various
drawing functions. It is the procedure called when you run the module as a script. Feel free to make any changes that you wish to
this function. We will not look a the body of this function when we grade your assignment.
Asserting Preconditions
As we saw in class, it is very helpful to assert your preconditions when you are using recursion or iteration. This keeps you from
being caught in an (effectively) infinite loop.
Through out the code in, we have placed assert statements in the various function stubs. However, we do not guarantee
that they are enough. When you complete a function, we expect that you fully check your precondition with assert statements. If
the provided assert statements do not fully check your precondition, then you must add more.
To help you with this process, we have provided you with several helper functions at the very top of All of these helper
functions return a boolean value: True or False. These helper functions are to be used inside of an assert to check part of a
precondition, as shown throughout the code.
As we saw in class, it is quite common to use helper functions to check preconditions. Some of the preconditions in this assignment
can be quite complex. In particular, look at the function for is_valid_color(). This allows us to simplify our assert statements
a lot.
You will also notice that we have a helper function called report_error. In the past, we discovered that students are quite prone
to make coding mistakes in their assert error messages (particularly adding a non-string to a string). This function is a nice way to
make error messages that is fairly foolproof.
Task 1. Triangles
12/21/2018 CS 1110: Assignment 4 6/10
Complete the procedure draw_triangle(t,s,c). This procedure is given a Turtle as a parameter. You do not need to make a
new Turtle, nor a new Window.
This procedure should draw an equilateral triangle of side length s and color c using Turtle t. It should draw the triangle using t’s
current position and orientation. The Turtle should end its drawing at the same position and orientation as when it started. Do not
save the Turtle’s position and orientation at the beginning and then restore them at the end. If you draw the triangle correctly,
following the instructions in the procedure specification, then this should happen automatically.
To try out the procedure, type the following in interactive mode.

>>> import cornell
>>> import a4
>>> w = cornell.Window()
>>> t = cornell.Turtle(w)
>>> a4.draw_triangle(t,200,’green’)
Task 2. Hexagons
Complete the procedure draw_hex(t,s). This method should draw six equilateral triangles using color
‘orange’ with side lengths s. This triangles should form a hexagon, as illustrated to the right. Follow
the specification and hints carefully. In particular, be sure to use the helper function suggested. Do not
try to repeat code already written.
For both draw_triangle and draw_hex, it is very important that you follow the specifications. If you
do not follow the specifications exactly, we will deduct points. In particular, pay close attention what we
say about the state of the Turtle. Did you make any changes to Turtle attributes that need to be changed
back to what they were orginally?
Task 3. Radial Shapes
Choose two (and only two!) from the following three activities: spirals, polygons, or radiating lines. Once you have done two of
these, you are free (but not required) to do the remaining one. These are pretty fun assignments. If you decide to do all three, we
will grade you on the best two (though there is no extra credit beyond that).
Each of these tasks involves creating a helper procedure. In each case, the main procedure does not have a Turtle as parameter, but
its helper procedure does. The main procedure clears the Window, creates a Turtle, calls the helper procedure to do the work, then
hides the Turtle. Note that some of these procedures are very particular about which way that the newly created Turtle should start
out facing. Remember that you can control the facing of your Turtle via the heading attribute.
When writing these procedures, write the main procedure first, then the helper, and finally test both by calling the first one in
python. If the main procedure is foo, its associated helper is called foo_helper. We have created stubs for all of these procedures
in Do not change the headers (either the names or the parameters), as our grading software will be calling them by those
names. Just fill in the bodies.
Once again, it is very important that you follow the specifications for all three procedures below. If you do not follow the
specifications exactly, we will deduct points. Pay close attention what we say about the state of the Turtle. Did you make any
changes to Turtle attributes that need to be changed back to what they were orginally?
The first picture to the right is done by drawing 10 lines. The lines have length 10,
20, 30, … . After each line, the Turtle turns left 90 degrees. The second diagram to
the right shows a similar spiral but with the Turtle turning left 75 degrees after each
Complete the procedures draw_spiral and draw_spiral_helper. Pay close
attention to how the lines grow at each step. Also pay close attention to how these
change color. These are all import parts of the specification.
When you first test these function, use 10 for the initial side length. Try different
angles, like 90 degrees, 92 degrees, 88 degrees, and so on. You will be amazed at
what these procedures do. Find out by trying these calls (after creating the Window w):
draw_spiral(w, 8, 90, 300, 10)
draw_spiral(w, 8, 135, 400, 10)
draw_spiral(w, 9, 60, 100, 10)
draw_spiral(w, 9, 121, 500, 10)
draw_spiral(w, 10, 89, 400, 10)
draw_spiral(w, 10, 150, 300, 10)
draw_spiral(w, 10,-144, 500, 10)
12/21/2018 CS 1110: Assignment 4 7/10
The first image to the right is a 10-sided polygon. The second image to the right is
a series of 100 10-sided polygons, the first started at angle 90, the second at an
angle of 90 + 360.0/100, the third at an angle of 90 + 2*360.0/100, and so on. This
demonstrates the kind of cool pictures you can draw just with polygons.
Complete the procedures multi_polygons and multi_polygons_helper so
that your program can draw such designs. You should use the procedure
draw_polygon, which we have provided, as a helper function (do not modify this
You should also pay attention to the color alternation. As you can see in the 100 polygon picture, we alternate the color red and
green. When your are finished, experiment to see what neat designs come out. For example, try the following (after creating the
Window w):
multi_polygons(w, 45, 3, 100, 10)
multi_polygons(w, 60, 30, 20, 10)
Radiating Lines
The picture on the left consists of 16 lines of the same length radiating out from the
initial Turtle position. The angle between the lines is the same. The second picture
has 300 lines. If n lines are drawn, the angle between them is 360.0/n.
Furthermore, the color of each line depends on the angle (i.e. the direction) of each
Note that the Turtle color attribute will accept HSV objects. A line drawn at angle
ang uses the color HSV(ang, 1.0, 1.0). Just assign the object to the attribute
and start drawing. This should make this part of the assignment fairly
straightforward. Remember the invariants for an HSV object when you are
Complete the procedures radiate and radiate_helper. When finished, test them with small values of n, like 4 or 8. After the
procedures are completely tested, try them with 360 lines of length 200. Also, try 2000 lines and Turtle speed 0 (which still takes a
while because of how the Turtle draws), and notice how much more filled in the disk becomes.
Task 4. Sierpinski Shapes
In the next two tasks you will draw some fractals. A fractal is a shape that has parts which (when you zoom in) look like the whole
shape. This suggests that you will need to use recursion to draw them. The number of recursive steps (or depth) determines the
resolution of the fractal drawn. Wikipedia has a wealth of information about these and other fractals.
There are a lot of fractals named after Sierpinski. Some of you may have seen examples of this in your Calculus class, like the
Sierpinski Carpet. In these fractals you start with a basic shape (such as a rectangle) and recursively punch holes in the middle. In
this task you are to choose one (and only one) from the following two shapes: the Sierpinski Triangle or the Sierpinski snowflake.
Once again you are free (but not required) to complete them both. If you do both of them, we will grade the best one.
Throughout both of these tasks, we ask that you use a Pen instead of a Turtle because (1) there is no need to maintain the
direction and (2) Pen methods can draw solid shapes. See the overview of the Pen above for more information.
As with the radial shapes, for each of these recursive tasks, you will implement two procedures, a main procedure and a helper. The
main procedure clears the Window and creates a new Pen. It also calls the helper to do the drawing, then cleans up afterward. The
main procedure does not have a Pen as a parameter (though it does have the Window as a parameter), while the helper does.
The helper is the function that does all the real drawing. It is the function that is supposed to call itself recursively. The main
procedure is not recursive.
Once again, it is very important that you follow the specifications for all the procedures below. If you do not follow the
specifications exactly, we will deduct points. Pay attention to when the Pen should and should not be visible.
Sierpinski Triangles
Below are the triangles for depths 0, 1, 2, and 3 respectively. In depth 0, there is no recursive call and so it is just an equilateral
triangle whose sides are length side. In depth 1, there is a single recursive call and so break up that triangle into four smaller
triangles and remove the middle one. At depth 2, we break up the remaining triangles, and so on.
12/21/2018 CS 1110: Assignment 4 8/10
Depth 0 Depth 1 Depth 2 Depth 3
We have stubbed in the procedures triangle and triangle_helper for you to complete. We have provided a procedure
fill_triangle, which you can use to draw a solid triangle. You should not modify fill_triangle. Pay close attention to the
specification of triangle_helper, particularly the fact that we anchor the triangle at the lower left corner.
When drawing your shape, do not “remove” the center triangle (e.g. draw a white triangle to erase it). Instead, you should just
refuse to draw it. Except in the base case, only draw in the outer three triangles. Those triangles should be Sierpinski triangles of
one less depth. This is illustrated below.
Sierpinski Snowflakes
Below are the snowflakes for depths 0, 1, 2, and 3 respectively. In depth 0, there is no recursive call and so it is just a hexagon
whose sides are length s (we use the parameter side in the module In depth 1, there is a single recursive call and so break
up that hexagon into six smaller hexagons and remove the middle one. At depth 2, we break up the remaining hexagons, and so on.
Depth 0 Depth 1 Depth 2 Depth 3
We have stubbed in the procedures snowflake and snowflake_helper for you to complete. We have provided a procedure
fill_hex, which you can use to draw a solid hexagon. You should not modify fill_hex (even though it is missing asserts).
This fractal is a little trickier to understand. What does it mean to break up a hexagon into smaller hexagons? Look at the picture
below. The dotted blue border is an outer blue hexagon. The green hexagons are all inside of it, and all have side length s/3. The
center hexagon shares the same center as the outer hexagon. The centers of the other hexagons are all distance 2*s/3 away from it.
Looking at this picture, you should be able to compute the centers of the six hexagons, which is all you need to call fill_hex
12/21/2018 CS 1110: Assignment 4 9/10
When drawing your snowflake, do not “remove” the center hexagon (e.g. draw a white hexagon to erase it). Instead, you should
just refuse to draw it. Except in the base case, only draw in the outer six hexagons. Those hexagons should be Sierpinski
snowflakes of one less depth.
As a word of warning, a depth-3 Sierpinski snowflake appears to take up to 30 seconds to draw, even with animation speed set to
the fastest possible. This is an unfortunate issue with the way Turtles and Pens work in Python, and we are still working on a
solution to this problem (four years later).
Task 5. H-Trees
H-trees are a very useful shape in designing microchips. The lines represent wires that connect circuit components in a tree of
interconnections without wires crossing. The 3-branches tree is different from the shapes in Part 4 in that it is a line drawing and
not a solid shape. The basic shape is a single vertical line. Later shapes branch to the west, east and north half-way up the vertical
line. These branches are themselves 3-branches trees of one less depth.
Depth 0 Depth 1 Depth 2 Depth 3
Even though this is a line drawing, you will still draw this with a Pen instead of a Turtle. However, we have separated this task
from Task 4 because there are a few differences in how you structure the function for this task. Once again, we have stubbed in the
procedures htree and htree_helper for you to complete. There is also procedure draw_h, which is supposed to draw an H
shape. This function is not complete and you will have to implement it as well. We recommend that you look at fill_triangle
and fill_hex for how to complete this function (though it does not produce a solid shape).
To draw an H-tree, you first draw an H will all three sides of the given length (this is what the function draw_h does). In addition,
if d > 0, you draw four H-trees of size side/2.0 and depth d-1. The centers of the the four H-trees are at the top and bottom of
the two vertical lines drawn in the previous step. This is illustrated in the diagram below.
Once you complete the functions for this fractal, you are done with the assignment.
Finishing the Assignment
Before you submit this assignment, you should be sure that everything is working and polished. Unlike the first assignment, you
only get one submission for this assignment. If you make a mistake, you will not get an opportunity to correct it. With that said,
you may submit multiple times before the due date. We will grade the most recent version submitted.
Once you have everything working you should go back and make sure that your program meets the class coding conventions. In
particular, you should check that the following are all true:
1. There are no tabs in the file, only spaces (this is not an issue if you used Komodo Edit).
2. Functions are each separated by two blank lines.
3. Lines are short enough (80 chars) that horizontal scrolling is not necessary.
4. The specifications for all of the functions are complete and are docstrings.
5. Specifications are immediately after the function header and indented.
At the top of you should have three single line comments with (1) the module name, (2) your name(s) and netid(s), and (3)
the date you finished the assignment. Upload this file to CMS by the due date: Thursday, October 26th at 11:59 pm.
12/21/2018 CS 1110: Assignment 4 10/10
In addition to turning in the assignment, we ask that you complete the survey posted in CMS. Once again, the surveys will ask
about things such as how long you spent on the assignment, your impression of the difficulty, and what could be done to improve
it. Please try to complete the survey within a day of turning in this assignment. Remember that participation in surveys comprise
1% of your final grade.


There are no reviews yet.

Be the first to review “Assignment 4: Turtles”

Your email address will not be published.