44
Tail Recursion, Assignment, Iteration, and Fruitful Functions Fall 20151 Week 3 CSCI-141 Scott C. Johnson

Fall 20151 Week 3 CSCI-141 Scott C. Johnson. Say we want to draw the following figure ◦ How would we go about doing this?

Embed Size (px)

Citation preview

Tail Recursion, Assignment, Iteration, and Fruitful

FunctionsFall 20151 Week 3

CSCI-141Scott C. Johnson

Say we want to draw the following figure◦ How would we

go about doingthis?

Tail Recursion

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

To the code: hypnotized.py

Tail Recursion

Execution Diagram

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

So what happens when we do in Python:

x = 15y = 18z = 20

Assignment

So what happens when we do in Python:

x = 15y = 18z = 20

then we call:

x = x + z

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

The nth Fibonacci◦ Mathematical definition:

Classic Fruitful Function Examples

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

Example for the fact(n) function

Substitution Trace

Example for the fib(n) function

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

Substitution Trace

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

Tail-Recursive Fruitful Functions and Iteration

Iterative Formulation with while condition and assignment

Tail-Recursive Fruitful Functions and Iteration

Iterative Formulation

Tail-Recursive Fruitful Functions and Iteration

Iterative Formulation with while condition and assignment

Tail-Recursive Fruitful Functions and Iteration

Timelines can be used instead of substitution traces◦ Substitution traces are not really good for iteration

tracing◦ Timelines trace variable changes from one iteration to the

next◦ Timeline example for fib(5)

Timelines