fall 20151 week 3 csci-141 scott c. johnson. say we want to draw the following figure ◦ how would...
TRANSCRIPT
Tail Recursion, Assignment, Iteration, and Fruitful
FunctionsFall 20151 Week 3
CSCI-141Scott C. Johnson
Consider the case were we want zero segments◦ What would it look like?
def draw_spiral0(): pass
Tail Recursion
Consider the case were we want one segment◦ We want just one line◦ What would it look like?
def draw_spiral1(): forward(1)
Tail Recursion
Consider the case were we want two segments◦ In addition to going forward 2 units we must turn
and go forward 1 unit◦ Note: going forward one is the same as calling
draw_spiral1()◦ What would it look like?
def draw_spiral2(): forward(2) right(90) draw_spiral1()
Tail Recursion
Consider the case were we want three segments◦ In addition to going forward 3 units we must turn,
go forward 2 units, turn, and go forward 1 unit◦ Note: going forward 2 units, turning, and going
forward 1 unit is the same as calling draw_spiral1()
◦ What would it look like? def draw_spiral2():
forward(3) right(90) draw_spiral2()
Tail Recursion
The Algorithm◦ Cases 0 and 1 look different than cases 2 and 3
But we can make case 1 look like 2 and 3 def draw_spiral1():
forward(1) right(90) draw_spiral0()
◦ Have you noticed a pattern yet?
Tail Recursion
The Algorithm◦ draw_spiralX
go forward x rotate 90 call function draw_spiral(X-1)
◦ How can we use this to make a recursive function?◦ def draw_spiral(segments):
if segments == 0: pass else: forward(segments) right(90) draw_spiral(segments - 1)
Tail Recursion
Notice in the pattern in the execution diagram◦ There is nothing more to execute after the
recursive call◦ We are basically executing the same code over
and over again In general when there is nothing more to do
after a call it is called a “tail-call”◦ If such a tail-call is a recursive call the function is
considered tail-recursive
Tail Recursion
Lets look at the sudo code for our draw spiral◦ draw_sprial(segments):
repeatedly execute until we are done if segments == 0: we are done else: Move the turtle forward segments turn right 90 degrees change segments to the value of segments -1
Tail Recursion
Tail-recursion can also be understood as:◦ Iteration◦ Repetition
Tail Recursion
Some of you have been waiting for
this! But not yet!
The sudo code for the spiral function leaves us with a puzzle◦ How do we can the value of a parameter?◦ What does it mean to change the value?
The statement “change segments to the value of segments – 1”◦ In Python this is writen as:
segments = segments -1
Assignment
This can be
confusing!
Lets break down “segments = segments – 1”◦ If we think of it in math terms
When segments = 0: segments = segments – 1
0 = 0 – 1 0 = -1 Which is false!
◦ We have always thought of segments and other variables as numbers… that’s not always true When segments = “Hello”:
segments = segments – 1“Hello” = “Hello” – 1
What is a variable then?
Assignment
Do not think of it as math!
Assignment is the process of giving a value to a variable◦ A variable refers to an address◦ An address is a name for a location in computer
memory◦ Python has a table that maps variable name to
the address◦ Computer memory is also considered a table
Assignment
Recall in our sudo code the statement “repeatedly execute until we are done”◦ This can be translated in Python as “while true”◦ “we are done” becomes “break”
while True◦ Will run forever until you tell it to “break”
An Iteration Construct
With this we can rewrite our recursive sprial function!◦ def draw_spiral(segments):
while True: if segments == 0: break else: forward(segments) right(90) segments = segments - 1
An Iteration Construct
Notice no recursive
call!
Let’s look at while True in more depth◦ If is actually:
while (condition)
We just happen to give it a True condition! Will never stop What if we want it to stop?
Do we always have to use a break?
An Iteration Construct
Think back to the if statement◦ It had a condition to determine what block of code
it executes: if (x > 0): do something else: do something else
An Iteration Construct
while is the same thing
while (x > 0): do some stuff go back to beginning of while
An Iteration Construct
With this we can rewrite our recursive sprial function again!◦ def draw_spiral(segments):
while (segments > 0): forward(segments) right(90) segments = segments - 1
An Iteration Construct
Notice the function got
a lot smaller!
Lets try this with segments of 3◦ def draw_spiral(segments):
while (segments > 0): forward(segments) right(90) segments = segments - 1
An Iteration Construct
With this we can rewrite our recursive sprial function again!◦ def draw_spiral(segments):
while not(segments == 0): forward(segments) right(90) segments = segments - 1
An Iteration Construct
Notice this will handle negative segments! Is this
okay?
Up to this point functions have been “commands”◦ Turtle.left(90)◦ Turtle.forward(10)◦ Turtle.pendown()
They did something we told them to do.
How ever there is more than just telling them to do something!
Fruitful Functions
Without the turtle drawing, how would we know if our function did something?◦ We can have our function yield a result that we
can check! ◦ These are known as fruitful functions
Consider the following◦ Turtle.forward(100) # moves the turtle ◦ Math.sqrt(2) # does the squareroot of 2
Where do we see this? Is it moving a turtle?
Fruitful Functions
To see what a fruitful function does we must see what it yields◦ Also know as what it “returns”◦ Using the keyword “return” you can yield a value
from a function
◦ Example: def addOne(x):
return x + 1 When I call addOne(2) it will return 3
Basically the function call will get replaced with the return value!
Fruitful Functions
How does that translate to code?◦ def fact(n):
if n == 0: return 1 else: return n * fact(n - 1)
def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n – 1) + fib(n – 2)
Classic Fruitful Function Examples
Execution traces are good, but:◦ Can be long◦ Can contain more detail than we need
Substitution trace can be simpler!◦ Substitution tracing is a generalization of
arithmetic expressions evaluation.◦ Very similar how you solve a math expression!
Substitution Trace
Fruitful functions can be tail-recursive, or not◦ The examples above are not!
For fact(n) there is work after the recursive call Multiple n by the result of the recursive call
For fib(n) we have to add the two recursive calls!◦ The is a way to write them as tail recursive.
Doing so involves creating an “accumulation parameter”
Coming up with the formulation of a accumulative parameter is tricky!
Tail-Recursive Fruitful Functions and Iteration
Here is the modified code for fact(n) using an accumulation parameter
How Did we come up with this?
Tail-Recursive Fruitful Functions and Iteration
Here is the modified code for fact(n) using an accumulation parameter
How Did we come up with this?
Tail-Recursive Fruitful Functions and Iteration
Iterative Formulation◦ Since tail-recursion can be iteration◦ Can we make these also iteratively?
Note we do not need break since return exits the function
Note we must be careful how we change the variables
Tail-Recursive Fruitful Functions and Iteration
Iterative Formulation with while condition and assignment
Tail-Recursive Fruitful Functions and Iteration
Iterative Formulation with while condition and assignment
Tail-Recursive Fruitful Functions and Iteration