Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Fall 20151 Week 3 CSCI-141 Scott C. Johnson.  Say we want to draw the following figure ◦ How would we go about doing this?"— Presentation transcript:

1 Fall 20151 Week 3 CSCI-141 Scott C. Johnson

2  Say we want to draw the following figure ◦ How would we go about doing this?

3  Consider the case were we want zero segments ◦ What would it look like?  def draw_spiral0(): pass

4  Consider the case were we want one segment ◦ We want just one line ◦ What would it look like?  def draw_spiral1(): forward(1)

5  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()

6  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()

7  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?

8  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)

9  To the code: hypnotized.py

10  Execution Diagram

11  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

12  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

13  Tail-recursion can also be understood as: ◦ Iteration ◦ Repetition Some of you have been waiting for this! But not yet!

14  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 This can be confusing!

15  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? Do not think of it as math!

16  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

17  So what happens when we do in Python: x = 15 y = 18 z = 20

18  So what happens when we do in Python: x = 15 y = 18 z = 20 then we call: x = x + z

19  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”

20  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 Notice no recursive call!

21  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?

22  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

23  while is the same thing while (x > 0): do some stuff go back to beginning of while

24  With this we can rewrite our recursive sprial function again! ◦ def draw_spiral(segments): while (segments > 0): forward(segments) right(90) segments = segments - 1 Notice the function got a lot smaller!

25  Lets try this with segments of 3 ◦ def draw_spiral(segments): while (segments > 0): forward(segments) right(90) segments = segments - 1

26  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 Notice this will handle negative segments! Is this okay?

27  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!

28  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?

29  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!

30  The n th Fibonacci ◦ Mathematical definition:

31  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)

32  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!

33  Example for the fact(n) function

34  Example for the fib(n) function

35  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!

36  Here is the modified code for fact(n) using an accumulation parameter How Did we come up with this?

37

38  Substitution Trace

39  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

40  Iterative Formulation

41  Iterative Formulation with while condition and assignment

42  Iterative Formulation

43  Iterative Formulation with while condition and assignment

44  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)


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

Similar presentations


Ads by Google