# Introduction to Turtle and Graphical Recursion¶

Turtle is a graphics module first introduced in the 1960s by South African-born computer scientist Seymour Papert. It uses a programmable cursor, fondly referred to as the “turtle” to draw on a Cartesian plane (x and y axis.) Helpful documentation on the built-in Python module for turtle can be found here. Below, we cover the basics that are essential for the course.

Note: you may need to re-run some cells a couple times for the Jupyter notebook to properly clear the Turtle window.

```from turtle import *
```
```# set up a 400x400 turtle window
setup(400, 400)
reset()

# move the turtle forward 100 pixels
fd(100)

# turn the turtle 90 degrees to the left
lt(90)

# move forward another 100 pixels
fd(100)

# complete a square
lt(90)
fd(100)
lt(90)
fd(100)
done()
```
```# we can use this for the following examples to set up the basic environment for our turtle
def initializeTurtle():
setup(500, 500)
reset()
# shift the turtle slightly to get a centered figure
up()
goto(-40, -40)
down()
shape("turtle")
```

## Drawing basic shapes with turtle¶

Rather than manually writing the steps to draw a square each time, we can write a function that takes as input the length of the square and draws it for us.

```def drawSquare(length):
# a loop that runs 4 times
# and draws each side of the square
for i in range(4):
fd(length)
lt(90)
done()
```
```setup(400, 400)
reset()
drawSquare(150)
```
```---------------------------------------------------------------------------
Terminator                                Traceback (most recent call last)
Input In , in <cell line: 1>()
----> 1 setup(400, 400)
2 reset()
3 drawSquare(150)

File <string>:5, in setup(width, height, startx, starty)

Terminator:
```

Here’s a more general function to draw arbtitrary polygons instead of squares.

```def drawPolygon(length, numSides):
for i in range(numSides):
fd(length)
lt(360/numSides)
done()
```
```initializeTurtle()
drawPolygon(80, 8)
```

Here’s how we can add some color to our shapes in turtle!

```def drawPolygonColor(length, numSides, color):
# set the color we want to fill the shape with
# color is a string
fillcolor(color)

begin_fill()
for i in range(numSides):
fd(length)
lt(360/numSides)
end_fill()
done()
```
```initializeTurtle()
drawPolygonColor(80, 8, "blue")
```
```---------------------------------------------------------------------------
Terminator                                Traceback (most recent call last)
Input In , in <cell line: 1>()
----> 1 initializeTurtle()
2 drawPolygonColor(80, 8, "blue")

Input In , in initializeTurtle()
2 def initializeTurtle():
----> 3     setup(500, 500)
4     reset()
5     # shift the turtle slightly to get a centered figure

File <string>:5, in setup(width, height, startx, starty)

Terminator:
```

## Concentric Circles¶

```def initializeTurtleForCircles():
setup(1200, 1200)
reset()
speed(10)
up()
goto(0, -300)
down()
shape("turtle")
```
```def concentricCirclesWrong(radius, gap):
# base case, don't draw anything, return 0
return 0
else:
# tell the turtle draw a circle

# recursive function call; draw smaller circles

# we drew one circle in this step, plus however many we
# drew recursively, so return 1 + num
return 1 + num
```
```initializeTurtleForCircles()
print("Num Circles:", concentricCirclesWrong(300, 30))
#hideturtle()
done()
```
```Num Circles: 10
```

We need to move the turtle’s starting point to draw the concentric circles correctly.

```def concentricCircles(radius, gap):
# base case, don't draw anything, return 0
return 0
else:
# pen down, draw circle
down()

# pen up, ensure the turtle doesn't draw while repositioning
up()

# reposition the turtle for the next circle
lt(90)
fd(gap)
rt(90)

# recursive function call; draw smaller circles

# we drew one circle in this step, plus however many we
# drew recursively, so return 1 + num
return 1 + num
```
```initializeTurtleForCircles()
print("Num Circles:", concentricCircles(300, 30))
hideturtle()
done()
```
```---------------------------------------------------------------------------
Terminator                                Traceback (most recent call last)
Input In , in <cell line: 1>()
----> 1 initializeTurtleForCircles()
2 print("Num Circles:", concentricCircles(300, 30))
3 hideturtle()

Input In , in initializeTurtleForCircles()
1 def initializeTurtleForCircles():
----> 2     setup(1200, 1200)
3     reset()
4     speed(10)

File <string>:5, in setup(width, height, startx, starty)

Terminator:
```

```def drawDisc(radius, color):
"""
Draw circle of a given radius and fill it with color
"""

# put the pen down
down()

# set the color
fillcolor(color)

# draw the circle
begin_fill()
end_fill()

# put the pen up
up()
```
```def concentricCirclesColor(radius, gap, colorOuter, colorInner):
"""
Recursive function to draw concentric circles with
alternating colors
"""
# base case, don't draw anything, return 0
return 0
else:
lt(90)
fd(gap)
rt(90)
num = concentricCirclesColor(radius-gap, gap, colorInner, colorOuter)
return 1 + num
```
```initializeTurtleForCircles()
print("Num circles:", concentricCirclesColor(300, 30, "gold", "purple"))
hideturtle()
done()
```
```Num circles: 10
```

Finally, let’s write a version that maintains the function’s invariance.

```def concentricCirclesInvariant(radius, gap, colorOuter, colorInner):
"""
Recursive function to draw concentric circles with alternating
color
"""
# base case, don't draw anything, return 0
return 0
else:
lt(90)
fd(gap)
rt(90)
num = concentricCirclesInvariant(radius-gap, gap, colorInner, colorOuter)
# move turtle back to starting position
lt(90)
bk(gap)
rt(90)

return 1 + num
```
```initializeTurtleForCircles()
print("Num circles:", concentricCirclesInvariant(300, 30, "gold", "purple", 2))
hideturtle()
done()
```
```---------------------------------------------------------------------------
Terminator                                Traceback (most recent call last)
Input In , in <cell line: 1>()
----> 1 initializeTurtleForCircles()
2 print("Num circles:", concentricCirclesInvariant(300, 30, "gold", "purple", 2))
3 hideturtle()

Input In , in initializeTurtleForCircles()
1 def initializeTurtleForCircles():
----> 2     setup(1200, 1200)
3     reset()
4     speed(10)

File <string>:5, in setup(width, height, startx, starty)

Terminator:
```

## Nested Circles¶

```def nestedCircles(radius, minRadius, colorOut, colorAlt):
return 0
else:
# contribute to the solution

# position the turtle to draw right subcircle

# draw right subcircle recursively

# position turtle for left subcircle

# draw left subcircle recursively

# bring turtle back to start position
```initializeTurtleForCircles()
```Num circles: 15