CS 110 Fall 09
Lab 9: Mindbending with Recursion
Due: Wednesday, November 18th at class time
In this lab we'll investigate an algorithmic technique that occurs when functions call themselves. This is called recursion.
Part 1 -
Consider the following two functions:
def weird(x):
if x == 1: def strange(x):
if x == 0: def odd(y, z):
if z == 0: def main():
y = weird(3) For this example, draw the function call stack starting from main(). Next, do the same for the odd() function, where the invocation in main() is given by y = odd(2,3). These call stack diagrams may be written by hand and turned in on the due date of the lab. Also, in a file named rec.rtf, describe what all three of the functions do. A couple things to note: First, there are parameters for which these functions do not make recursive calls. In particular, weird(1), strange(0), strange(1), and odd(<val>, 0) all return integers without making another recursive function call. If we didn’t have cases like this, there is no way the function calls would ever stop. So in creating recursive functions, we need to make sure that eventually, the recursive calls stop. These cases are often called base cases or termination conditions.
Define recsum(n) so that it computes the sum of the first n integers. Use the definition of weird() as a template. Similarly, create a recursive function tribonacci(n) to compute the nth Tribonacci number. The Tribonacci numbers are a sequence T(i), where T(0) = T(1) = 0, T(2) = 1 and T(i) = T(i-1) + T(i-2) + T(i-3) for any i > 2. Your functions should still be recursive, and can follow the definition of strange() as a template. Place both functions in a program that prompts the user to enter a single integer. Then print the result of both function calls on that same integer. Call this program BasicRec.py.
Part 2 - Snowflake
Now we’ll use recursion to draw some neat patterns. To do this, we need a graphics package that excels at "relative position"-based graphics. In other words, when we draw, the graphics systems knows where we last left off, and each operation is relative to some "current position". Although we could get the same effect by using the graphics module, we would have to add a lot of code to keep track of this position, and so it will be easier to use a different graphics library. The library we will use is called 'turtle', and the drawing metaphor is that we have a virtual "turtle" that we can command to move around the drawing area. The turtle has a "pen" attached to its tail that can be in the up or down position. The pen has attributes of its width and its color. The turtle starts in the center of the graphics window at coordinate (0, 0)
from turtle import *
def main(): main() Create a new program called Snowflake.py. In the main function, set up for an 800 x 600 turtle screen. Create a Turtle object and set the pen width to 2, and the pen position to (-380, -100).
Create a function called snow which returns nothing but is given a turtle object and two ints called iteration and length.
This function should do one of two things. First, if iteration is 0, all you should do is use the forward function on the turtle that was passed in, drawing forward the distance given by length.
The more complicated case is if iteration is greater than 0. In that case, you will have 7 instructions. Instructions 1, 3, 5 and 7 all make calls to the function snow. Each call will be identical, and will be passed the turtle, iteration-1, and length/3. That is, if we aren’t down to iteration 0 yet, our function will call the snow function four times with a lower iteration value and shorter lengths.
Between each of these recursive calls, we’ll change the direction of our pen. To do this, you’ll use the functions <turtle>.setHeading(x) and <turtle>.heading(). You’ll need to get the current direction because we don’t want to set the pen to a fixed angle, but rather want to turn the pen relative to its current facing. The three rotations should be 60, -120 and 60 degrees respectively.
Once you’ve got this, we can test it out. Try calling the function snow in your main function with parameters (pic, 0, 729). (I picked 729 just because it is a power of 3, so when we do integer division by 3 repeatedly, we’ll still have the right integer). Display the picture. You should see a black line drawn across most of the image. Try this again, but this time change the iteration to 1. This should add a kink to the middle of the line. Once you have this working, change your main function to make 6 calls to snow, where you start with snow(pic, 0, 729) and go up to snow(pic, 5, 729), incrementing iteration by 1 each time. Between each call, reset the pen position to its starting position, and change the pen color so you can distinguish the lines. Part 3 - Dragon and Serpent
Like the previous example, you’ll implement two more patterns created recursively. The basic pattern is as follows:
draw forward rotate 90 draw forward rotate –90 draw forward rotate –90 draw forward draw forward rotate 90 draw forward rotate 90 draw forward rotate –90 draw forward The length of a line at any given iteration should be 1/4 the length of the previous iteration. Write a program called Dragon.py that demonstrates the resulting pattern.
Do the same for the basic pattern below: draw forward rotate 60 draw forward rotate 60 draw forward rotate -60 draw forward rotate -60 draw forward rotate -60 draw forward rotate -60 draw forward rotate 60 draw forward rotate 60 draw forward Write a program called Serpent.py that demonstrates the resulting pattern.
Part 4 - Sierpinski’s carpet
Sierpinski’s carpet is defined as follows. Start with an uncolored square. Split it into 9 equal-sized squares. Color in the middle square. Draw Sierpinski’s carpet in the remaining 8 squares. Here is what you should get: Write a program called Carpet.py that creates this pattern. Your function will probably need to take in a bunch of parameters: the Turtle object, the current iteration, the current width, and the current x and y coordinates.
Part 5 - Xander’s bubbles
Xander’s bubbles are defined as follows. Start with an uncolored square. Draw a circle in the middle of the square with radius one quarter the length of the square. Then split the square into 4 equal pieces, and draw Xander’s bubbles in each quadrant. You should get something like this: Write a program called Bubbles.py that creates this pattern. Again, your function will probably need to take in a bunch of parameters: the Turtle object, the current iteration, the current width, and the current x and y coordinates.
Part 6 - Uploading your lab
Lab09 should contain:
· rec.rtf · BasicRec.py
· Snowflake.py
· Dragon.py
· Serpent.py
· Carpet.py
· Bubbles.py
plus the Function Call Stack drawn by hand and turned into me. |