You are on page 1of 49

!

1
Chapter 3 2

Graphics and Functions 2

Graphics 2

Turtle Geometry 3

Functions 6

Loops 11

Turtle Methods 13

Developing The Computer Solution 16

Top Down Design 16

Bottom Up Construction 16

Main Program 17

Exercises 34

Solutions to Exercises 38

Footnotes 46

How to Write Functions 47


!2

Chapter 3
Graphics and Functions
The algorithmic notation we learned in the Chapter 2 is a proper subset of the Python
language and contains only the essential constructs needed for writing workable algorithms
for a wide variety of problems. By restricting the pseudocode to a few basic instructions with
which to build technical specifications that can be implemented on a computer, we aim to
emphasize the concepts and the competency with these basic constructs.

As we have seen, a principal part of the solving problem process is describing and analyzing
the problem to formulate a solution. We do this in plain language, but it needs to be clear,
concise, and well organized in logical steps. In this phase we propose the strategy to solve
the problem; the design that contains the solution. The next phase is to transcribe this design,
to a technical specification that will facilitate the implementation of the solution on the
computer, which requires writing the algorithm. This is a difficult step for we have to
transform a plan, or design expressed in general terms to an algorithm in specific technical
terms. It requires a good dose of computational thinking and knowledge of the algorithmic
notation; the ability to turn a plain language description into variables, sequences,
expressions, conditionals and loops. Only when done correctly is the solution implemented
on the computer.

In this chapter we will add more functionality to the algorithmic notation, to allow the
solution for a wider range of problems, building on the basic constructions and concepts
with which we are now familiar, and exploring other applications that will enhance our
ability to write correct algorithms.

Graphics
Solving problems requires that we think a little different, in a more “problem oriented” way,
in small steps but without losing sight of the broad picture. Thinking computationally in
terms of decomposition, abstractions, patterns and of the concepts and constructs used by the
algorithms.

To learn this in a proper way, we need to explore. Explore the computational world, and the
mathematics that lies behind it. The most important thing about exploring is for you to do it
rather than just passively read what is written about it. So it is best that you follow in your
computer the examples and exercises that are presented, trying various alternatives on your
own so as to become proficient with the algorithmic notation and the concepts that it uses.
!3

Turtle Geometry
This is a new kind of geometry that exists only in the virtual world. Imagine that you have
control of a little object that we choose to call a “turtle”, that can move at your command on a
computer display screen, and leave a trail (that we see as a drawing) as it moves around. The
tradition of calling the display objects that make the drawings “turtles” goes back to the
1960s and we shall adopt this terminology. To activate the turtle type the following command
in the Python Shell (in the IDLE environment) at the prompt:

>>> from turtle import *

Nothing seems to happen, but all the computer code (instructions) needed for the turtle to
work is downloaded to your working space and the turtle is ready to accept your
instructions.

Let’s first look at the drawing space, or window. In the Shell, type the following:

>>> home()

You will see a window open, titled ‘Python Turtle Graphics’ with a black arrow head in the
center, pointing to the right. It represents the turtle. This window can be seen as a Cartesian
plane, with the center at coordinates (0,0), a horizontal x-axis at (x,0), and a vertical y-axis at
(0,y). The approximate dimensions are about 600 units on from top to bottom and from left to
right. We shall look at the exact dimension later in the chapter.

The turtle can respond to a few simple commands. Type forward(100) and you will see
the turtle move, in the direction it faces, 100 units.

>>> forward(100)

Now turn the turtle 90 degrees, to have it face north (or the top of window):

>>> left(90)

You will now have the turtle at the position shown on the drawing canvass:
!4

A back(distance) and right(angle) commands cause the opposite movements. As you can
see, forward and back change the turtle’s position, while left and right change the turtle’s
heading; that is, the direction in which the turtle points. When changing position, the turtle
may (or may not) leave a trace as we have seen; this is a line that appears on the screen. You
can control this by instructing the turtle to have the pendown() or the penup(); to draw or
not to draw.

When the drawing is finished, we want to release the window and close it. The command,

>>> done()

will release the window so you can close it.

Notice that all commands are followed by a set of parentheses, which may optionally include
a value or a variable.

The remarkable thing is that with just these commands we can make some pretty drawings.
Here is an example:

Example 3.1
Draw a square with sides 100 units.

Analysis
A square is made by drawing a side of length x, changing direction of the turtle 90 degrees,
and repeating these two steps four times. Here is an algorithm to do it:

Algorithm

# example 3.1 - Draw a square

from turtle import *

for x in [100,100,100,100]:
forward(x)
left(90)
done()
Here is the result:
!5

Notice that you could have used a while loop to draw the algorithm, or no loop at all and
simply repeat the two basic instructions (the invariant) four times. Either case would have
given the same result.

Another example that requires a little more analysis.

Example 3.2
Draw a pythagorean triangle using the turtle.

Analysis
In a pythagorean triangle the lengths of the sides are given by a pythagorean triple, three
integers which satisfy the Pythagorean Theorem, a2 + b2 = c2. The best known case is the 3, 4,
5 triangle. So, let’s draw a triangle with sides 3, 4 and 5. However, a move of less than 10 is
very small on the drawing canvass, so we will scale up the side lengths by a factor of 10: we
will draw a 30, 40, 50 triangle.

Algorithm

# example 3.2
# first activate the turtle
from turtle import *

# start at home. Draw the base.


forward(30)
# you need to make a right triangle. Go up 90 degrees.
left(90)
# draw the opposite side.
forward(40)
# now you need to draw the hypotenuse. There are two options:
# 1. calculate the angle of rotation (left) and then move 50 units.
# This calculation requires trigonometry to get the angle.
# 2. The other option is to move the turtle home(), where it
started.
home()
done()
Here is the result:
!6

How does this work? When the order to go home() is given, the turtle moves and, since the
pen is down, it will draw the line from the vertice to the center of the plane.

Functions
Turtle geometry would be boring if the turtle was restricted to only change position and
direction, but it so happens that we can teach the turtle new tricks. With a set of commands
that it already knows, it can draw a figure, learn the procedure and replicate it at will at any
time later.

For example, let’s take the set of statements from Example 3.1 that draws a square. As it is, to
have the turtle draw the same square again, we have to repeat the same set of commands:

from turtle import *

for x in [100,100,100,100]:
forward(x)
left(90)
done()

However, by naming this procedure the turtle can remember it, and the next time we need to
draw a similar square we just call its name, as the next example shows.

Example 3.3
from turtle import *
# define a procedure to draw a square of side 100
def square():
for x in [100,100,100,100]:
forward(x)
left(90)

square()
done()
!7
To draw a square of side 100 we only have to write square() and the turtle will draw it.
But, of course, you have to define the procedure (with the def statement) before using it.

Pay close attentioin to how the procedure is named:

• To name the procedure we use the reserved word def with this syntax:

def <name of the procedure>():

• The definition gives the name of the procedure followed by parentheses (), and a
colon :

• Remember that any statement ending with a colon : is always followed by a set of
indented statements.

• We place the three statements that actually draw the square inside the definition,
properly indented to indicate that they are to be executed as a block.

• Other statements, before or after the definition, are not part of the procedure and
therefore are not indented. They are placed at the same left margin position as the
definition statement def. In this case this are the from turtle import * , the
procedure call square(), an the the done() statements.

• The purpose of the def statement, and the set of statements it contains, is only to
define the procedure, or function (as we prefer to call any command that is followed by
a pair of parentheses). It does not perform any visible action. To be effective, the set of
instructions that constitute the algorithm must included within the definition of the
function, before using it.

• This summarizes the definition of a function:

def <name>():
<body of the function>
<other statements in the algorithm>

• Once defined, the function can be invoked anywhere, as any instruction, and as often
as needed, because the turtle has learned to use it. A function is called or invoked by
its name, function_name().

Function Arguments
The function square(), as defined above, will make the turtle draw a square with sides 100
units in length. But if we want to draw a square with a different side length we have to
redefine the function. To deal with this situation a function definition allows the possibility of
passing data to the algorithm within the function, resulting in functions with greater
versatility. For example if we can pass to square(), the length of the side, then we have a
!8
function that can draw any size square, and all we need to do is specify the specific length
when the function is called.

To use this capability, when the function is defined we include in the definition the value (or
values) that we want to pass to the function: these are called arguments and are included
within the parentheses of the name, separated by commas if there is more than one. In the
case of square(), to pass the length of the side (of the square) that we want the turtle to
draw, we use a variable name (e.g. side), and include the variable name in the definition,
like this:

Example 3.4
Draw a square of any size

def square(side):
i = 0
while i < 4:
forward(side)
left(90)
i += 0
square(75)
done()

Inside the function, the instruction that actually draws the side with a specific number of
units was changed from 100 to the variable side. When the function is called we specify the
value for side, passed it to the function, and the forward(side) instruction is executed
with the value that the variable references. In the example we pass the value as a constant (it
can be passed as either a variable, or an absolute constant), and a square of side 75 units will
be drawn. We could have passed the value as any name. Suppose x = 37.5, then we invoke
the function as:

square(x)

and a square of side 37.5 will be drawn by the turtle. The name of the argument is assigned
when the function is first defined, and that specific name is used by the code within the
function. But at call time any variable, of the same type, with a valid value can be used to
pass the data.

The following example illustrates the use of arguments.

Example 3.5
Write a function to draw a regular polygon of n sides.

Analysis
!9
A regular polygon is a closed geometric figure in which all of its sides and angles are equal.
To draw any regular polygon we need to define the number of sides and, optionally, the
length of a side if we want the function to draw polygons of varying size. Since it is a closed
figure, to draw the polygon the turtle will rotate 360 degrees; n equal rotations, which means
that any angle will be 360/n degrees. With this information we can proceed to write the
algorithm.

Algorithm
We first write the algorithm to draw a polygon of n sides:

from turtle import *

n_sides = int(input("How many sides? "))


angle = 360 / n_sides
i = 0
while i < 360: # i is an angle. 360 to draw the closed figure
forward(100) # we only need to draw one side, and
left(angle) # make one rotation
i += angle # increment by angle
done()

We want to teach the turtle to draw regular polygons, but we need to give it the number of
sides so that it can draw any regular polygon. We do this by giving it the number of sides as
an argument inside the parentheses in the definition of the function. The argument (or
arguments, because there can be several) is a written as a variable in the definition. Inside the
function, this variable name is used as an input variable, by one or several statements below
the definition.

The algorithm above is converted to a function that passes one argument, the number of
sides n_sides, to the code inside the function.

from turtle import *


def regular_polygon(n_sides): # n_sides is an argument
angle = 360 / n_sides
i = 0
while i < 360: # i is an angle.
forward(100) # we only need to draw one side, and
left(angle) # make one rotation
i += angle # increment by angle

# ----- call the function with a value for the argument ----
regular_polygon(5)

done()
!10
Notice how the argument n_sides is defined, and how it is used to calculate the angle. In
this case the function is called with an argument = 5 to draw a pentagon.

Here is the output:

—————————————

Be aware that you have to define the function first, and then invoke it with an argument of
the same type. The argument must be passed (if not, it will raise an error), and it can be a
variable or a specific value, as in this case. When calling the function the name of the variable
used is not important; any value or variable name (the same n_sides used in the definition
or any other name) may be used. The function, by the position of the argument, will assume it
is the n_sides of the original definition.

The function regular_polygon(), as it is, will draw all polygons with side 100. We would
like to make the side a variable so the turtle can draw polygons of various sizes. To do this
we need to add another argument to our function definition.

Here is how we modify the previous function to take two arguments, n_sides and length,
representing the number of sides and the length of each side, respectively. We then ask turtle
to draw two different polygons, changing the arguments. Notice how in the second polygon
we use different variable names. The function definition takes these names, and by their
position, assigns them to n_sides and length, respectively.

Example 3.6
Draw a regular polygon of any size with variable side length

from turtle import *


def regular_polygon(n_sides, length):
angle = 360 / n_sides
i = 0
while i < 360: # i is an angle. 360 to draw the closed figure
forward(length) # we only need to draw one side, and
left(angle) # make one rotation
i += angle # increment by angle

# ----- call the function with a value for the argument ----
regular_polygon(7, 100)
sides = 6
size = 50
regular_polygon(sides,size)
!11

done()
Here is the output:

Loops
Turtle graphics uses loops, while and for, regularly and provides an effective mechanism
for practicing repetition commands. A useful complement to the for loop iterator is the
range() function.

Range
Now that we have had some experience with for loops using only sequences, we can
appreciate better the range function. A for loop is controlled by a sequence of elements;
more specifically by the number of elements in the sequence. That is what determines how
many iterations the for loop will make. In many instances we require a large number of
iterations, and sometimes consecutive integer values for the iterator variable. This means that
we have to create the appropriate sequence before using the for loop. The range function is
most convenient for creating such sequences. In it more general form, the function can take
three argumentes, and this is its syntax:

range(start, stop, step)

All arguments must be integers. The first argument start is the first value in the sequence,
and is optional. If not give, it is assumed to be cero (we say, 0 by default). The next argument
is required and gives the value where the sequence will stop, but it is not included in the
sequence. That is, the sequence generated will contain integers from the start number up to,
but not including, the stop number. The last argument is the step in which the sequence of
integers will be generated, it is optional, and its value is assumed to be 1 by default, if not
specified. Here are some examples:

Example 3.7
The range() function
!12

range(9) # generates sequence [0,1,2,3,4,5,6,7,8] 9 elements


range(10000) # generates sequence [0,…,9999] 10000 elements
ranage(-5) # generates an empty sequence []
range(5,12) # [5,6,7,8,9,10,11] 7 elements
range(1,10,2) # [1,3,5,7,9] 5 elements
range(4,-5,-1) # [4, 3, 2, 1, 0, -1, -2, -3, -4] 9 elements

Although range() returns an inmutable sequence of integers, it is not exactly a sequence, as


we can see from the following dialogue:

>>> range(5) == [0, 1, 2, 3, 4]


False

Why is it False? If we ask the Interpreter about range(), this is how it sees it:

>>> range(5)
range(0, 5)

It sees range(5) not as a sequence [0, 1, 2, 3, 4], but as a function that generates a
sequence on demand. Range does not create the sequence in memory when it is called. It
generates the elements of the sequence as they are needed. This is important with large
sequences because it does not store the whole sequence in memory, but only the code for
generating the integers.

If we do need the sequence as such, it can be generated with range() and then converted to a
sequence with list(), as shown below:

>>> a_sequence = list(range(10))


>>> a_sequence
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Exercises 3.1 will reinforce your understanding of functions and loops. Study the figure
carefully before writing the algorithm, and test your work often. It is better to detect mistakes
as soon as they are made, rather than wait until the whole algorithm is coded. Testing is a
fundamental skill that you must learn.

Here are some additional commands for the turtle that you can apply in the Exercises that
follow.

>>> setheading(angle)

setheading(angle) will set the orientation or heading of the turtle to the specified angle in
degrees. For example, setheading(90)will set the turtle to point north (upwards, or top of
!13
the window). Angles of 0, 180, 270, etc. will set the orientation to west, east, or south,
respectively.

>>> reset()

reset() will delete the turtle drawings from the screen, and place it at home() (at the center
position (0,0)), facing west (to the right of the screen), with the pen down.

>>> clear()

clear() is similar for it will delete all turtle drawings from the screen, but it does not move
the turtle and it does not change any of the current properties of the turtle, nor affects
drawings made by other turtles.

At any time, while drawing or when finished drawing, the turtle icon may be hidden from
view. To make the turtle invisible include the command,

>>> hideturtle()

When hidden, the turtle will still leave a trace if pendown() is active. To make the turtle
visible again use,

>>> showturtle()

Turtle Methods
We have seen that with a few commands we can instruct turtle to make interesting and
didactic drawings. These commands are technically known as methods. In general, a method
performs some action when invoked (much like a function), we do not know how it does it,
and usually do not care. The complete inventory of the methods and attributes available to
the turtle can be found in the documentation on line. You can access it by querying the
browser for “turtle graphics py 3” which will show the link “turtle — Turtle graphics —
Python 3.7.4 documentation".

Here is a partial list of turtle methods and attributes, including those we already know and
several new ones.

• forward(distance) moves the turtle in the direction it is facing, a distance units. The
line will be drawn even if the turtle is not visible (hidden).
!14
• backward(distance) moves the turtle backwards a “distance” in pixels, tracing a
straight line in the opposite direction at which the turtle is pointing. The line will be
drawn even if the turtle is not visible (hidden).

• left(angle) turns the turtle anticlockwise (right) by “angle”. Angles are measured in
degrees, by default.

• To change the measure to radians invoke radians(). It will remain in effect


until you change it back to degrees by calling degrees().

• right(angle) turns the turtle clockwise (right) by “angle”. Angles are in degrees, by
default.

• penup() or up() raises the pen, that the turtle uses to draw, from the canvas. The
drawing turtle is a metaphor (an abstraction) in which a tiny robotic turtle holds a
“pen” (could be its tail), with which it draws by holding it down against the canvas. Of
course, if it raises it will not draw, but the turtle can still move about. By default, the
turtle starts with the pen down, using black ink.

• pendown() or down() lowers the pen so that drawing resumes when the pen is up.
If the pen is already down it has no effect.

• pensize() or width() returns the “size” or width of the pen in use if called without
an argument. When used, the argument is a positive number, and determines the
thickness of the line drawn. For example, pensize(3.5), or width(5).

• color(options) or pencolor(options) returns the color of the pen if no argument is


used, or changes the color of the pen appropriately. There are several options and
formats to change the color (refer to the documentation); we shall use a string format
with the names of the most common colors[2] for our exercises. For example, ‘black’,
‘white’, ‘blue’, ‘red’, ‘yellow’, ‘green’, ‘darkgreen’, ‘violet’, ‘orange’, etc..

• heading() returns the current heading (direction) of the turtle, in degrees


counterclockwise from horizontal 0˚ (pointing to the right).

• setheading(angle) sets the heading of the turtle to ‘angle’, measured in the current
setting of degrees or radians.

• position() returns the position of the turtle as a pair of coordinates (x, y) on the
cartesian plane. The coordinates are relative to the origin, which by default is at the
center of the canvas (the plane)

• goto(x, y=None), or setposition(x, y=None), or setpos(…), moves the


turtle from the current position, in a straight line, to the point (x, y) on the plane. If the
pen is down, it will trace the line. The movement is relative to the origin, not the
!15
current position of the turtle, and the turtle’s heading is not changed. x is a number,
integer or real. y is a number or None, by default.

• home() moves the turtle to the origin (coordinates (0, 0)) and sets the heading of
the turtle to the default value (pointing right). As with goto(0,0), it will trace a line
on the canvas if the pen is down. To move the turtle to another position without
drawing a line the pen must be up.

• shape(name=None) set the turtle shape to a form with the given name, or return the
current shape name if None is given. The valid names for turtle shapes are ‘arrow’,
‘turtle’, ‘circle’, ‘square’, ‘triangle’, and ‘classic’. New shapes can be created by we are
not going to do that. See the documentation for further details.

• speed(value=None) returns the current speed of the turtle if invoked with no


parameters. The default speed is 1, the ‘slowest’. The speed value can be any number
from 0 to 10; 1 is ‘slowest’, 3 is ‘slow’, 6 is ‘normal’, ’10’ is ‘fast’, and 0 is ‘fastest’. At 0
there is no animation for the turtle turns instantly.

• window_width() returns the width of the current canvas (or window), in pixels.

• window_height() returns the height of the current canvas, in pixels.

• stamp() stamps (i.e. prints) a copy of the turtle shape onto the canvas at its current
position, and returns its id (identification number). The stamp can later be deleted by
calling clearstamp(id).

• clear() deletes the turtle drawings from the canvas, without moving the turtle or
changing any of its attributes. It does not affect the drawings of other turtles.

• reset() deletes the turtle drawings from the screen, and places it at the home()
position, with all default attributes.

• dot(size, color) draws a circular dot with diameter size and color (a color name, in
quotes)

• circle(radius, arc) draws a circle with radius. If arc is not give, draws a full circle,
otherwise only part of the circle. arc is an angle.

• begin_fill() call this method just before drawing a shape that you want filled.

• end_fill() call the method when shape is drawn, and after calling begin_fill().
It fills the shape with the second color given in color(pen_color, fill_color), or
fillcolor().

• write(‘text’), writes text at the current turtle position. For other arguments see the
documentation.
!16
These methods are related to the Turtle Screen, so if using dot notation to invoke the
methods, they are applied to the screen name (e.g. ‘canvas’), not to the turtle name (e.g. ‘tyr’).

• bgcolor(options) returns the current background color of the Turtle Screen if called
without options. Otherwise changes the background color of the screen to the option
given. The options are the same as those used in the method color().

• title(‘title_string’) sets the title of the turtle window (or ‘canvas’) to ‘title_string’.

Try these methods and become familiar with their operation so that you can use them in your
programs. If you need addtional explanation on any of the methods, use the online help from
the Shell as in this example,

>>> help(turtle.window_height)

Developing The Computer Solution


At this point you have the necessary tools for writing interesting computer programs, and
some knowledge of the methods required for solving problems using the computer. You need
to consider problems with several components in which you must apply decomposition (to
break down the problem in functions), abstraction to isolate and analyze the functions that
make each component and pattern recognition to identify the invariant in the iterations and
functions.

The dominant strategy for dealing with such computer problems is a two-phase strategy,
known as top down (analysis and) design, and bottom up construction.

Top Down Design


In top down design you take a bird’s view approach to the problem. You observe from “a
distance” to have a full perspective of the problem at hand: what it contains, what is the goal,
what are its parts, how do they relate to each other, and how are they assembled. Most
important, what are the inputs and output.

In terms of the algorithm(s) that lead to the solution, you want to identify parts that can be
coded as functions and their arguments (input data), the action performed by the function
and/or the data returned (output). How are these functions related to one another, how are
they called, and when are they called.

These connections are specified in a main code (or driver code) that assembles the parts,
initializing variables, making the necessary function calls and displaying the results.

Bottom Up Construction
!17
The bottom up construction is applied to each component of the problem and usually refers to
a specific function. Functions have arguments and return (optionally) a result (data). They
always perform a specific action.

Functions are built better from the bottom up. This means that you begin by writing the basic
algorithm, probably for a specific case. The algorithm is tested, if it contains iterations (for
or while loops) the invariant is identified. Recall that the invariant is the group of statements
that execute the action that needs to be repeated. Once tested, the algorithm is converted to a
function, adding the definition, a name with arguments when these are required. The
arguments are the input data that allow the function to perform its action for various
instances. Each function is built, documented, and tested separately.

Main Program
The main program is an assemblage of the parts that constitute the solution to the problem. It
is the code that produces the final results. Necessary data is captured (if necessary), variables
are initialized, and functions are called in order, and results are shown.

The best way to illustrate the method described is with some examples.

Example 3.8
The Fibonacci Spiral
Write a computer solution to draw a Fibonacci Spiral, similar to the figure shown below.

Top Down Analysis and Design


We begin by studying the figure. The spiral is drawn over an assembly of squares of sides
[1,1,2,3,5,8,13,21]. This happens to be a Fibonacci sequence with the first element, 0,
removed (a square of size 0 is not drawn). We can make the following assertions:

(1) We need the sequence of fibonacci numbers, [1,1,2,3,5,8,13,21].


!18
(2) We also need squares, of size corresponding to the the fibonnacci sequence, properly
tiled.

(3) Each square contains a 90 degree arc (part of a circle of radius equal to the side of the
square), which when connected together result in the fibonacci spiral.

Bottom Up Construction
The Fibonacci Sequence

Follow carefully as we construct a function to generate the fibonacci sequence, from the
ground up, step by step.

(1) We can write directly the list of fibonacci numbers, or write a short function to generate
the sequence. We choose to write the function.

• The first two number of the fibonacci sequence (the seeds) are i and n, where i is the
initial number, 0, and n is the next number, 1.

i, n = 0, 1

• We want to generate a sequence, so start with a sequence fs that contains the first
element of the sequence we want:

fs = [1]

• To obtain any fibonacci number n we add the previous two fibonacci numbers. In
algorithmic notation this can be written as:

i, n = n, i + n

The above expression can be read as follows. Starting with the right-hand side of the
assignment:
• n is a fibonacci number, and i + n is the sum of the initial fibonacci number and
the next fibonacci number.
• These values are assigned to the left-hand side of the expression as follows: n is
assigned to i (the next fibonacci number), and the sum i + n is assigned to the next
fibonacci number n.
• The expression is equivalent to writing two separate assignment statements,
i = n
n = i + n
• To generate the sequence, we append (add to the end) the new fibonacci number n.
This can be done either with the statement fs.append(n), or using concatenation,
fs = fs + [n].

• In summary, we now have the invariant (the instructions that calculate one fibonacci
number and add it to the end of the list.
!19
i, n = n, i + n
fs.append(n)

• To generate a list of f elements, we have to iterate the invariant f times:

for k in range(f):
i, n = n, i + n
fs.append(n)

• We want to use this algorithm as a function, so define the function with argument f to
create a list of f elements.
Example 3.8.1
Fibonacci sequence

def fibonacci_seq(f):
‘’’
Create list of f fibonacci numbers. Does not
include 0.
f is type int
returns list of fibonacci numbers, type list
‘’’
fs = [1]
i, n = 0, 1
for k in range(f):
i, n = n, i + n
fs.append(n)
return fs

• Test the function:


fibonacci_seq(10)

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

(2) The next part we need is a function to draw squares of any size.
For this task we already have a function , developed in Example 3.4 which we reproduce
below for convenience, modified to use a for loop instead of a while loop.

Example 3.8.2
Draws a square of any size using a for loop

def square(side):
# i = 0
# while i < 4:
for i in range(4):
forward(side)
left(90)
#i += 0
!20
Test the function with the fibonacci sequence generated in Example 3.8.1. We increase the
length of the sides by a scale of 3.

Example 3.8.3
Test Example 3.8.2 with fibonacci sequence.

from turtle import *

def fibonacci_seq(f):
'''
Create list of f fibonacci numbers. Does not include 0.
f is type int
returns list of fibonacci numbers, type list
'''
fs = [1]
i, n = 0, 1
for k in range(f):
i, n = n, i + n
fs.append(n)
return fs

def square(side):
''' draw a square with length side '''
for i in range(4):
forward(side)
left(90)
# -------- test functions ----
seq = fibonacci_seq(8)
for side in seq:
square(side*3)
done()

This is the result of the test:

We have the fibonacci squares drawn, but we need to place them side by side in a tile
arrangement. Let’s see how we can do that.

Draw the first square, of size 1 (scaled by 10), and pay attention to the position and direction
of the turtle:
!21

Examining the spiral we observe that the next square, also of size 1, is drawn to the right,
starting at the top right corner of the first square, like this:

The figure shows the position of the turtle after drawing the second square of size 1. To draw
the next square, size 2, with the same function and the same starting orientation of the turtle
(positioned to draw counterclockwise), we need to place the turtle at the right lower corner
of the drawing, facing to the left, like this:

The square that follows is of size 2. When finished we want the turtle on the lower left hand
corner facing north (up), ready to draw the square of size 3.

Writing the detailed steps required to draw these squares and position the turtle with the
correct orientation we have the following code:

square(1*50)
penup()
goto(50, 50)
pendown()
right(90)
!22
square(1*50)
penup()
goto(100, 0)
pendown()
right(90)
square(2*50)
penup()
goto(0, -100)
pendown()
right(90)

Notice that the drawing follows a sequence, which is repeated for each square:

• draw a square of side x (x is a fibonacci number from the fibonacci sequence)

• position the turtle at the opposite vertex of the starting position and rotate 90 degrees
to the right (an instance of this opertion is highlighted above).

These two steps are the invariant in the algorithm. They have the same five statements, and
only some parameters change. The goto() statement has the coordinates of the turtle at the
“opposite vertex of the starting position”. We find these coordinates with the position()
function which returns the coordintes of the turtle at a particular position. When drawing
the square, call postion() when the turtle is at the opposite vertex of the starting position.
You need to modify the code of the square() function:

Example 3.8.4
Modified square() function that returns the position of the vertex on the diagonal

def square(side):
‘’’ draws a square and captures the position of the diagonal
vertex.
returns the coordinates of the diagonal vertex.
‘’’
for i in range(4):
forward(side)
if i == 1:
vertex = position() # store the position of the turtle
left(90)
return vertex

Test the modified function:

pos = square(40)
print(pos)
print(square(55))
done()
!23
It draws two squares and prints these coordinates:

(40.00,40.00)
(55.00,55.00)
which are the correct values.

We are ready to draw the fibonacci squares in a tiled arrangement, following the reasoning
given above. Since the first elements of the fibonacci sequence are small numbers, use a
‘scale’ to increase the dimensions of the drawing.

Example 3.8.5
Fibonacci squares in a tiled arrangement

def fibonacci_squares(fib_seq,scale):
"""
Draws a sequence of fibonacci squares from a list of
fibonacci numbers, fib_seq.
"""
for f in fib_seq:
vertex = square(f,scale)
penup()
goto(vertex)
pendown()
right(90)

Again, we test the function to verify that it tiles the squares correctly. Note the use of ‘scale’.

fib_seq = fibonacci_seq(7)
scale = 5 # scale for the drawing
# draw squares
fibonacci_squares(fib_seq,scale)
hideturtle()
done()

It draws this arrangement of squares, which is correct.

Finally, to draw the spiral we start at the origin and draw an arc
of a circle with the same radius as the fibonacci square, curving in a clockwise direction. We
use the circle() function (a tutle method), with the radius taken from the fibonacci sequence,
and the arc -90 degrees to get the right curvature. As a last detail, write the square size next
to each square when it is drawn, by including the following statement,

write(f, align="right", font=("Arial", 10, “normal"))

when the turtle is positioned at the diagonal vertex.


!24
Here is the full script:

Example 3.8.6
The Fibonacci Spiral

from turtle import *


def fibonacci_seq(f):
"""
Generates the fibonacci sequence as a list of f numbers.
input: f an integer
returns list of fibonacci numbers, type list.
"""
fs = [1] # list containing fibonacci sequence
i, n = 0, 1 # first two fibonacci numbers
for k in range(f):
i, n = n, i + n
fs.append(n)
return fs

def square(f,scale):
"""Draws a fibonacci square of side f with scale, where f is a
fibonacci number. f is type int, and scale is a number.
It captures the position of the vertex of the square
from where a segment of the spiral is drawn.
"""
for i in range(4):
forward(scale * f)
if i == 1:
vertex = position()
write(f, align="right", font=("Arial", 10, "normal"))
left(90)
return vertex

def fibonacci_squares(fib_seq,scale):
"""
Draws a sequence of fibonacci squares from a list of
fibonacci numbers fib_seq.
"""
for f in fib_seq:
# vertex has the coordinates of the vertex at the
# diagonal point
vertex = square(f,scale)
penup()
goto(vertex)
pendown()
right(90)

def fibonacci_spiral(fib_seq):
!25

"""
Draw a fibonacci spiral over the fibonacci squares.
input: fib_seq, the same fibonacci sequence used by
fibonacci_squares(...).
"""
for fn in fib_seq:
circle(scale * fn, -90)

To draw the spiral, we shall use a scale of 20 and place the origin at (145, 145):

Another example to illustrate the Top Down - Bottom Up strategy is this case of a random
walk.

Example 3.9
Turtle Random Walk
In this example we will draw a squared lined paper pattern
on the canvas and then, starting at the origin (0,0), will
make the turtle walk over the grid lines in a random way
until it touches one of the edges of the lined paper. The
figure on the right shows an example of the turtle’s random
walk on the squared lined paper:. When the walk ends,
print 1) the number of steps taken, and 2) the final position
of the turtle.
!26

Top Down Analysis


The problem can be decomposed into the following parts:

(1) Drawing the graph paper.

(2) Moving the turtle one square in a random direction of 0, 90, 180 or 270 degrees, until
it touches a border of the graph paper.

• add up the distance moved and record the final position of the turtle when it
touches.

(3) Print total total distance walked and final position of the turtle.

Bottom Up Construction
(1) Start with the graph paper. This short function will draw n_lines of a specified
length, with a fixed space between lines.

def lines(length,space,n_lines):
for i in range(n_lines):
angle = 90 * (-1)**(i % 2)
forward(length)
penup()
left(angle)
forward(space)
pendown()
left(angle)

We test it with with these parameters:

k = 250
s = 10
n = 20
speed(0)
hideturtle()
lines(k, s, n)
done()

To draw the graph paper we call lines()twice, the first call is to draw the horizontal lines
and the second call to draw the vertical lines. The function grid(lenght, space,
n_lines, start) draws a square grid, with same n_lines of the same length and
space between them. The starting point for the grid is at start.
!27

Example 3.9.1
Draw the grid

def grid(lenght, space, n_lines, start):


'''
Draws a square grid with n_lines of equal lenght and space
between the lines.
start is the starting point of the grid, with coordinates x,y
Calls lines(length, space, n_lines)
'''
lines(lenght, space, n_lines)
penup()
x,y = start # x,y coordinates of the starting point
goto(x,-y)
pendown()
left(90)
lines(lenght, space, n_lines)

When finished move the turtle to the center and place a red dot at the starting position.

title("Random Walk")
pencolor("lightgray")
hideturtle()
speed(0)
hideturtle()
# draw grid
k = 500 # grid width and length
n = 51 # number of lines
s = 10 # space between lines
start = (-250, -250) # starting point of the grid
penup()
goto(start) # lower left-hand corner of grid
pendown()
grid(k, s, n, start)
penup()
home()
pendown()
pencolor("red")
dot(10,)
done()

(2) The random walk is formed by the turtle moving


in any one of these four directions,
[0,90,180,270], a fixed distance s (the space
between lines in the graph paper), until the turtle
touches a border of the graph paper. This means
!28
that:

-m/2 ≤ x ≤ m/2

and

-n/2 ≤ y ≤ n/2

where x, y are the coordinates of the position of the turtle at any time during the walk. The
following function will make the random walk, compute the distance walked and records the
position of the turtle.

Example 3.9.2
Random Walk

import random
def random_walk(m, n, s):
"""
Do a random walk over the grid.
m and n are the dimensions of the grid (m is horizontal width,
and n is the vertical height), both type int.
s is the space between the lines of the grid, type int.
returns the position of the turtle (the coordinates), and the
distance travelled.
"""
x = y = dist = 0
while abs(x) < m//2 and abs(y) < n//2:
# choose a random direction
setheading(random.choice([0, 90, 180, 270]))
forward(s)
dist += s
x, y = position()
pos = position()
return (pos, dist)
The final result is obtained with the following code that uses the functions defined above:

# -------------- main program -----------------


title("Random Walk")
pencolor("gray")
hideturtle()
speed(0)
hideturtle()
# draw grid
k = 500 # grid width and length
n = 51 # number of lines
s = 10 # space between lines
start = (-250, -250) # starting point of the grid
penup()
!29
goto(start) # lower left-hand corner of grid
pendown()
grid(k, s, n, start)
penup()
home()
pendown()
pencolor("red")
dot(10,)
# start random walk
pensize(3)
showturtle()
(pos, dist) = random_walk(k, k, s)
dot(7, "black")
# finish walk
penup()
goto(-k // 2, -k // 2 - s * 2)
pencolor("black")
pensize(1)
hideturtle()
write("Position: ",True)
write(pos,True)
write("; Distance traveled: ",True)
write(dist,False)
done()
!30
A final example on this topic of Top Down Analysis and Bottom Up
Construction involves a simple drawing of a bunch of flowers, similar
to those in the figure to the side.

Example 3.10
Draw at least three flowers of different colors, as shown in the figure.

Top Down Analysis


The problem can be decomposed into the following parts:

(1) Draw a flower.

• draw a petal

• draw the flower with color and central dot

• draw stem

(2) Main program to draw bunch of flowers

Bottom Up Construction
(1) Start with the petals

Example 3.10.1
The petals

from turtle import *

def petal(r, angle):


"""
Draw a petal using two arcs with radius (r) and
an angle.
"""
for i in range(2):
circle(r, angle)
left(180 - angle)

Test the code to confirm that the code is correct.

Next, draw a flower with n petals.

Example 3.10.2
A flower with n petals

def flower_with_petals(n, r, angle):


"""
Draw a flower with (n) petals, each with a radius (r)
and an angle, and filled with color.
Calls petal()
!31

"""
for i in range(n):
begin_fill()
petal(r, angle)
end_fill()
left(360 / n)

The color is specified before calling the flower_with_petals() function. Test it.

The finished flower has a color and red dot in the center.

Example 3.10.3
The finished flower

def flower(n, r, angle):


"""
Draw a flower, with a 'DarkRed' dot in the center.
The fill color is set before calling the function.
Leaves the pen up.
"""
pensize(2)
flower_with_petals(n, r, angle)
dot(int(r * .25), 'DarkRed')
penup()

Test the function. The fill color is defined before calling the function.

To draw the flower stem, begin at a position at the bottom of the screen, for example (0,-200).
Stems are drawn “DarkGreen” color as a circle(radius, arc) with long radius and small arc.
The following functions draw the stem and the flower at the end of the stem. The code is self
explanatory.

Example 3.10.4
The flower on a stem

def move(x, y):


"""
Move turtle to coordinates x,y without leaving a trail.
"""
penup()
goto(x,y)
pendown()

def stem(radius, angle, thick):


"""
Draw dark green stem, an arc of radius (radius)
units, length (angle) degrees, and thickness
!32

(thick).
Leaves the pen up
"""
color('DarkGreen')
pensize(thick)
setheading(90)
circle(radius, angle)
penup()

def flower_on_stem(radius, angle, thick, c):


"""
Draws stem with flower at its end.
Stems are drawn upward from position(0,-200).
Calls functions move() to position turtle,
define the color and call
flower() to draw the flower with color c.
"""
home()
move(0,-200)
stem(radius, angle, thick)
pendown()
color('gold', c) # draw yellow flower
flower(n, r, a)

Test the code to verify its correctness.

For the complete solution we connect the previous functions in a main program as follows:

# ---------- main ----------

# initial settings
bgcolor('black')
n = 7 # number of petals in a flower
r = 50 # radius of petal
a = 90 # angle of petal
speed(0)
# Draw flowers with stem
flower_on_stem(1200, 20, 7, "magenta")
flower_on_stem(-700, 30, 5, "blue")
flower_on_stem(-1500, 10, 6, “yellow")
flower_on_stem(500, 30, 5, "blue")
hideturtle()
mainloop()

The final result,


!33
!34

Exercises
Exercise #3.1
Draw an arrangement of 8 squares (of side 100) by rotating the turtle 45 degrees to the left
after drawing a square. The composite drawing is shown in the figure below.

Exercise 3.2 [1]


2. Draw the figure on the right. Start at the center of the plane. The first
vertical line, in the upward direction is 100 pixels long. The next line to the
right is the same length. The larger square is 50 pixels on each side, and the
smaller square is 25 pixels each side.

3. Define a function with the figure drawn in (1).

4. Using the function defined in (2) draw the figure shown


on the right.

5. Draw the last figure. The basis for this drawing is the
figure in (1), followed by right(10) and
forward(50). Repeat as many times as necessary to
make the closed figure.
!35

Exercise 3.3
Open the file xxx.py and run the script. You will see a set of nine dots on the screen. The
center dot is at the center of the screen, (0,0). The corner dots are at positions (50,50) , (-50,50),
(-50,50) and (-50,50). The other dots are 50 units from the center.

The object of the puzzle is to connect the dots using only four straight lines, without lifting
the pen. Describe first the solution in words (plain language), and then write the algorithm in
algorithmic notation to draw the solution with the turtle.

Exercise 3.4
1. Write an algorithm to draw the figure below. The drawing should be very much like the
one shown, in the center of the screen, with the same inclination, and a small separation
between lines.

2. Making a small variation to the algorithm in part (1), draw the spiral below.
!36
3. Convert the algorithm in part (2) to a function that can draw either figure, from part (1)
or part (2). Test the function.

4. Modify the function in part (3) to take a new argument that will add color to the figures it
draws. Test the function.

Exercise 3.5
Draw the following figures.

Exercise 3.6
Write functions to do basic linear algebra operations:

(1) Multiply a vector by a scalar


!37
(2) Multiply a matrix by a scalar

(3) Algebraic sum of two matrices

(4) Scalar product of two vectors. Also called dot product.

(5) Matrix multiplication.



!38

Solutions to Exercises
Exercise #3.1
Draw the figure shown:

Solution
The figure is a composite drawing of 8 square made by drawing a base square from the
center, rotating 45 degrees (left or right) and drawing the same square, and repeating the
pattern 8 times. We use a function for the basic square, and for loops with range iterator.

Algorithm

from turtle import *

def square():
'''draw a square of side 100'''
for i in range(4):
forward(100)
left(90)

# ----------------- draw 8 squares --------------


for j in range(8): # draw figure from squares
square()
left(45)
hideturtle()
done()

Exercise 3.2 [1]


1. Draw the figure on the right. Start at the center of the plane. The first
vertical line, in the upward direction is 100 pixels long. The next line to the
right is the same length. The larger square is 50 pixels on each side, and the
smaller square is 25 pixels each side. Define a function that draws the
!39
figure.

Algorithm

from turtle import *


def thing():
'''draw a thing'''
forward(100)
right(90)
forward(100)
right(90)
forward(50)
right(90)
forward(50)
right(90)
forward(100)
right(90)
forward(25)
right(90)
forward(25)
right(90)
forward(50)

2. Using the function defined in (1) draw the figure shown on the
right.

Algorithm

def four_things():
'''link four things in a closed figure'''
for i in range(4):
thing()

3. Draw the last figure. The basis for this drawing is the
figure in (1), followed by right(10) and
forward(50).
!40

Algorithm

setheading(90)
for i in range(9):
thing()
right(10)
forward(50)
hideturtle()
done()

The code below will draw the three figures, one at a


time. After each drawing respond to the prompt in the
Shell by pressing enter to draw the next figure.

from turtle import *

def thing():
'''draw a thing'''
forward(100)
right(90)
forward(100)
right(90)
forward(50)
right(90)
forward(50)
right(90)
forward(100)
right(90)
forward(25)
right(90)
forward(25)
right(90)
forward(50)

def four_things():
'''link four things in a closed figure'''
for i in range(4):
thing()

# --------------- driver code ----------


# part 2
setheading(90)
!41

thing()
input("press enter to continue ...")
# part 3
reset()
setheading(90)
four_things()
input("press enter to continue ...")
# part 4
reset()
setheading(90)
for i in range(9):
thing()
right(10)
forward(50)
hideturtle()
done()

Notice the use of setheading() to set the direction of the turtle before starting a drawing,
of input() to interrupt the execution before drawing the next figure, and reset() to clear
the screen and place the turtle at the starting point, before the next drawing.

Exercise 3.3
To connect the dots you have to use lateral thinking. It is impossible to do it with four lines if
the lines are drawn within the perimeter of the square suggested by the dots, but nothing
says that the lines must be within that square. Below is the algorithm that draws the four
lines. The functions draw the dots on the screen. The code below the functions draws the
lines.

Algorithm

from turtle import *

def a_dot(x, y):


'''
Draw a dot on the screen at coordinates (x,y)
'''
penup()
goto(x, y)
pendown()
dot()

def nine_dots():
'''
Draw nine dots on a square centered at (0,0)
'''
for x in [-50, 0, 50]:
!42

for y in [-50, 0, 50]:


a_dot(x, y)
penup()
home()
hideturtle()

# ------------- write you code below ----------


nine_dots()

showturtle()
penup()
goto(100, -100)
pendown()
pencolor('blue')
goto(-50, 50)
goto(-50, -100)
goto(100, 50)
goto(-50, 50)
hideturtle()
done()

Here is the answer.

Exercise #3.10
(1) Write the algorithm for the selection sort.
(2) Implement the algorithm in pseudocode.
(3) Test the algorithm by sorting in ascending order the sequence 6, 2, 9, 5, 7, 1, 8, 4, 3, 0.

Solution
(1) Analysis and description of how to do a selection sort:
!43
A selection sort repeatedly finds the smallest number in the unsorted part of the sequence
and places it at the beginning. To do this you need two sequences: 1) the unsorted
sequence, and 2) a sequence which holds the sorted elements. In each iteration, the
smallest number (considering the sort is in ascending order) is moved from the unsorted
sequence (1) to the other sequence (2).

Let’s suppose the input sequence is [3, 2, 5, 1]. The objective is to arrange the sequence in
ascending order → [1, 2, 3, 5]

Step 0. Start with two sequences, seq = [3, 2, 5, 1], and sorted_seq = [].

Step 1. Iterate over seq and find smallest element, call it min (min = 1)

Step 2. Append (i.e., move to the end of the sequence) min to sorted_seq ! [1]

Step 3. Remove min from seq: now seq ! [3, 2, 5]

Step 4. Iterate over seq and find the smallest element, min = 2

Step 5. Concatenate min to sorted_seq ! [1, 2]

Step 6. Remove min from seq: now seq ! [3, 5]

Step 7. Iterate over seq and find the smallest element, min = 3

Step 8. Append min to sorted_seq ! [1, 2, 3]

Step 9. Remove min from seq: now seq ! [5]

Step 10. Iterate over seq and find the smallest element, min = 5

Step 11. Append min to sorted_seq ! [1, 2, 3, 5]

Step 12. Remove min from seq: now seq ! []

Step 13. seq has no more elements. Procedure terminates. The sorted sequence is
sorted_seq ! [1, 2, 3, 5]

Notice that the above steps can be summarized as:

1) Initialize sequences, seq and sorted_seq

2) Iterate over seq

3) Find min, smallest element in seq

4) Append min to sorted_seq


!44
5) Remove min from seq; Go to 2)

6) When finish iterations, output sequence is sorted_seq

(2) Write the procedure in algorithmic notation.

# selection sort
seq = [33, 21, 15, 17, 11, 44, 37, 50, 61, 18]
#seq = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print('starting sequence', seq)

# create a sequence of consecutive non negative integers,


# of len(seq) -------------------------------------------
series = []
i = 0
while i < len(seq):
series += [i]
i += 1
# ------------------------------------------------------
# sort algorithm
for i in series:
s = series
s_ = []
# ---- removes indx element from a sequence ----------
indx = i # make indx the number where the series begins
while True:
if indx < len(s):
s_ = s_ + [s[indx]]
indx += 1
else:
break
# -----------------------------------------------------
# for j in series[i + 1:]:
for j in s_:
if seq[i] > seq[j]:
seq[i], seq[j] = seq[j], seq[i]
print('sorted', seq)

(3) Test results:

starting sequence [33, 21, 15, 17, 11, 44, 37, 50, 61, 18]
sorted [11, 15, 17, 18, 21, 33, 37, 44, 50, 61]

—————————————————-
!45
!46

Footnotes
[1] Example from Turtle Geometry — The Computer as a Medium for Exploring Mathematics, by Harold Abelson and Andrea A.
diSessa, The MIT Press, Cambridge, Mass., 1980, p.9
[2] Use HTML color codes. Search with a browser for “HTML color codes”. 

!47

How to Write Functions


Functions should be designed from the top down, and be written from the bottom up. You
start with a design that takes into consideration the goal, are the major components required
to meet the objectives, the way these major components interact, and the order in which they
must be assembled. This is the top down design. Then you choose a simple specific case and
test it. You identify invariant and key data. Next you make the base case applicable to other
situations, and make it a function with arguments. This is the function written from the
bottom up. It is your stepping stone to other similar problems.

Let’s work out an example.

Example
Problem
Write a function that can draw any regular multicolor polygon.

Top Down Analysis


The basis for this function is a regular polygon. A regular polygon is a closed geometrical
figure in which all its sides are of the same length, and its angles are of the same size. The
difference between one regular polygon and another different regular polygon is caused
fundamentally by the number of sides. It is the important difference between regular
polygons. Combining two facts, that the turtle has to rotate 360 degrees to draw the closed
figure, and that all sides are equal, we deduce that any angle rotation is 360/number of sides.

Bottom Up Construction
(1) Let’s begin by drawing a simple square. The code that follows will do that.

from turtle import *


for n in range(4):
forward(100)
left(90)
done()

Modify the code to draw a pentagon. Since the turtle has to turn 360 to draw the whole
figure, it needs to rotate 360/5 degrees for each angle (five vertices, each on an angle of 360/5
degrees, give a total rotation of 5*360/5 = 360 degrees).

for n in range(5):
forward(100)
left(360/5)
done()
!48
The two statements, forward() and left(), are the invariant which is repeated n times
to draw a polygon of n sides. The essential data is the number of sides, which determines the
angle at each vertex and the number of iterations.

(2) The second step is to convert the specific code above to a function that will draw any
regular polygon of n sides.

from turtle import *

def polygon(n):
''' draws a regular polygon of n sides '''
angle = 360 / n
for n in range(n):
forward(100)
left(angle)

# ------------ calling code --------


polygon(4)
polygon(5)
done()
The function is first defined and then called with one argument, the number of sides. The
test shows that it produces the same results as the algorithms in step (1).

This function will draw any regular polygon, from an equilateral triangle to an n-gon, where
n is a large integer. However, for n > 10 part of the drawing will be outside the screen. That is
because the side is 100 units, so if you want to draw a 17-gon figure, you need to scale down
the drawing. You can modify the function polygon() to take another argument, the scale of
the drawing, to “zoom out” (or in) and be able to fit the figure in the screen.

The scale is a positive real number (float). The code below is modified to take a scale.

from turtle import *

def polygon(n, scale):


''' draws a regular polygon of n sides.
n is the number of sides, type int
scale is the drawing scale, a positive real, type float.
'''
angle = 360 / n
for n in range(n):
forward(100*scale)
left(angle)

# ------------ calling code --------


polygon(4)
!49

polygon(5)
done()

You might also like