Return Return Statements A return statement completes the - - PowerPoint PPT Presentation

return return statements
SMART_READER_LITE
LIVE PREVIEW

Return Return Statements A return statement completes the - - PowerPoint PPT Presentation

Return Return Statements A return statement completes the evaluation of a call expression and provides its value f(x) for user-defined function f : switch to a new environment; execute f's body return statement within f : switch back to the


slide-1
SLIDE 1

Return

slide-2
SLIDE 2

Return Statements

A return statement completes the evaluation of a call expression and provides its value

2

f(x) for user-defined function f: switch to a new environment; execute f's body return statement within f: switch back to the previous environment; f(x) now has a value Only one return statement is ever executed while executing the body of a function def end(n, d): """Print the final digits of N in reverse order until D is found. >>> end(34567, 5) 7 6 5 """ while n > 0: last, n = n % 10, n // 10 print(last) if d == last: return None (Demo)

slide-3
SLIDE 3

Recursive Functions

slide-4
SLIDE 4

Recursive Functions

Definition: A function is called recursive if the body of that function calls itself, either directly or indirectly Implication: Executing the body of a recursive function may require applying that function

Drawing Hands, by M. C. Escher (lithograph, 1948)

4

slide-5
SLIDE 5

Digit Sums

  • If a number a is divisible by 9, then sum_digits(a) is also divisible by 9
  • Useful for typo detection!

5

The Bank of 61A 1234 5678 9098 7658

OSKI THE BEAR

A checksum digit is a function of all the other digits; It can be computed to detect typos

  • Credit cards actually use the Luhn algorithm, which we'll implement after sum_digits

2+0+1+8 = 11

slide-6
SLIDE 6

The sum of the digits of 6 is 6. Likewise for any one-digit (non-negative) number (i.e., < 10). The sum of the digits of 2019 is

6

201 9

Sum of these digits + This digit That is, we can break the problem of summing the digits of 2019 into a smaller instance of the same problem, plus some extra stuff. We call this recursion

The Problem Within the Problem

slide-7
SLIDE 7

Sum Digits Without a While Statement

7

def split(n): """Split positive n into all but its last digit and its last digit.""" return n // 10, n % 10 def sum_digits(n): """Return the sum of the digits of positive integer n.""" if n < 10: return n else: all_but_last, last = split(n) return sum_digits(all_but_last) + last

slide-8
SLIDE 8

The Anatomy of a Recursive Function

  • The def statement header is similar to other functions
  • Conditional statements check for base cases
  • Base cases are evaluated without recursive calls
  • Recursive cases are evaluated with recursive calls

(Demo1)

8

def sum_digits(n): """Return the sum of the digits of positive integer n.""" if n < 10: return n else: all_but_last, last = split(n) return sum_digits(all_but_last) + last

slide-9
SLIDE 9

Recursion in Environment Diagrams

slide-10
SLIDE 10

Recursion in Environment Diagrams

  • The same function fact is called

multiple times

  • Different frames keep track of the

different arguments in each call

  • What n evaluates to depends upon

the current environment

  • Each call to fact solves a simpler

problem than the last: smaller n

10

(Demo2 pythontutor)

http://pythontutor.com/composingprograms.html#code=def%20fact%28n%29%3A%0A%20%20%20%20if%20n%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20return%201%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20return%20n%20*%20fact%28n%20-%201%29%0A%20%20%20%20%20%20%20%20%0Afact%283%29&cumulative=true&curInstr=0&mode=display&origin=composingprograms.js&py=3&rawInputLstJSON=%5B%5D

slide-11
SLIDE 11

Iteration vs Recursion

Iteration is a special case of recursion def fact_iter(n): total, k = 1, 1 while k <= n: total, k = total*k, k+1 return total def fact(n): if n == 0: return 1 else: return n * fact(n-1) Using while: Using recursion:

n, total, k, fact_iter

Math: Names:

n, fact

11

(Demo3 trace!)

slide-12
SLIDE 12

Verifying Recursive Functions

slide-13
SLIDE 13

The Recursive Leap of Faith

Is fact implemented correctly? 1. Verify the base case 2. Treat fact as a functional abstraction! 3. Assume that fact(n-1) is correct 4. Verify that fact(n) is correct

Photo by Kevin Lee, Preikestolen, Norway

def fact(n): if n == 0: return 1 else: return n * fact(n-1)

13

slide-14
SLIDE 14

Mutual Recursion

slide-15
SLIDE 15

The Luhn Algorithm

Used to verify credit card numbers From Wikipedia: http://en.wikipedia.org/wiki/Luhn_algorithm

  • First: From the rightmost digit, which is the check digit, moving left, double the value
  • f every second digit; if product of this doubling operation is greater than 9 (e.g., 7 *

2 = 14), then sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5)

  • Second: Take the sum of all the digits

15

1 3 8 7 4 3 2 3 1+6=7 7 8 3 The Luhn sum of a valid credit card number is a multiple of 10 = 30 (Demo4)

slide-16
SLIDE 16

Recursion and Iteration

slide-17
SLIDE 17

def sum_digits(n): """Return the sum of the digits of positive integer n.""" if n < 10: return n else: all_but_last, last = split(n) return sum_digits(all_but_last) + last

Converting Recursion to Iteration

Can be tricky: Iteration is a special case of recursion. Idea: Figure out what state must be maintained by the iterative function. A partial sum

17

(Demo5) What's left to sum

slide-18
SLIDE 18

Converting Iteration to Recursion

More formulaic: Iteration is a special case of recursion. Idea: The state of an iteration can be passed as arguments. def sum_digits_iter(n): digit_sum = 0 while n > 0: n, last = split(n) digit_sum = digit_sum + last return digit_sum def sum_digits_rec(n, digit_sum): if n == 0: return digit_sum else: n, last = split(n) return sum_digits_rec(n, digit_sum + last) Updates via assignment become... ...arguments to a recursive call

18

slide-19
SLIDE 19

Order of Recursive Calls

slide-20
SLIDE 20

The Cascade Function

  • Each cascade frame is from a

different call to cascade.

  • Until the Return value appears,

that call has not completed.

  • Any statement can appear before
  • r after the recursive call.

(OPT Demo)

20

=def%20cascade%28n%29%3A%20%20%20%20%0A%20%20%20%20if%20n%20%3C%2010%3A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20print%28n%29%20%20%20%20%0A%20%20%20%20else%3A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20print%28n%29%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20cascade%28n//10%29%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20print%28n%29%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%0Acascade%28123%29&cumulative=

slide-21
SLIDE 21

Two Definitions of Cascade

21

def cascade(n): if n < 10: print(n) else: print(n) cascade(n//10) print(n) def cascade(n): print(n) if n >= 10: cascade(n//10) print(n) (Demo, clean up cascade)

  • If two implementations are equally clear, then shorter is usually better
  • In this case, the longer implementation is more clear (at least to me)
  • When learning to write recursive functions, put the base cases first
  • Both are recursive functions, even though only the first has typical structure
slide-22
SLIDE 22

Example: Inverse Cascade

slide-23
SLIDE 23

1 12 123 1234 123 12 1

Inverse Cascade

Write a function that prints an inverse cascade:

23

grow = lambda n: f_then_g(grow, print, n//10) shrink = lambda n: f_then_g(print, shrink, n//10) def f_then_g(f, g, n): if n: f(n) g(n)

1 12 123 1234 123 12 1

def inverse_cascade(n): grow(n) print(n) shrink(n)

slide-24
SLIDE 24

Tree Recursion

slide-25
SLIDE 25

Tree Recursion

http://en.wikipedia.org/wiki/File:Fibonacci.jpg

0, 1, 2, 3, 4, 5, 6, 7, 8, n: 0, 1, 1, 2, 3, 5, 8, 13, 21, fib(n): ... , 9,227,465 ... , 35 def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-2) + fib(n-1) Tree-shaped processes arise whenever executing the body of a recursive function makes more than one recursive call

25

slide-26
SLIDE 26

A Tree-Recursive Process

The computational process of fib evolves into a tree structure

26

fib(5) fib(4) fib(3) fib(1) 1 fib(2) fib(0) fib(1) 1 fib(2) fib(0) fib(1) 1 fib(3) fib(1) 1 fib(2) fib(0) fib(1) 1 (Demo3)

slide-27
SLIDE 27

Repetition in Tree-Recursive Computation

fib(5) fib(3) fib(1) 1 fib(4) fib(2) fib(0) fib(1) 1 fib(2) fib(0) fib(1) 1 fib(3) fib(1) 1 fib(2) fib(0) fib(1) 1 This process is highly repetitive; fib is called on the same argument multiple times

27

(We will speed up this computation dramatically in a few weeks by remembering results)

slide-28
SLIDE 28

Example: Counting Partitions

slide-29
SLIDE 29

Counting Partitions

The number of partitions of a positive integer n, using parts up to size m, is the number

  • f ways in which n can be expressed as the sum of positive integer parts up to m in

increasing order.

29

count_partitions(6, 4) 3 + 3 = 6 1 + 1 + 2 + 2 = 6 2 + 4 = 6 1 + 1 + 4 = 6 1 + 2 + 3 = 6 1 + 1 + 1 + 3 = 6 2 + 2 + 2 = 6 1 + 1 + 1 + 1 + 2 = 6 1 + 1 + 1 + 1 + 1 + 1 = 6

slide-30
SLIDE 30

Counting Partitions

The number of partitions of a positive integer n, using parts up to size m, is the number

  • f ways in which n can be expressed as the sum of positive integer parts up to m in non-

decreasing order.

30

  • Recursive decomposition: finding

simpler instances of the problem.

  • Explore two possibilities:
  • Use at least one 4
  • Don't use any 4
  • Solve two simpler problems:
  • count_partitions(2, 4)
  • count_partitions(6, 3)
  • Tree recursion often involves

exploring different choices. count_partitions(6, 4)

slide-31
SLIDE 31

Counting Partitions

The number of partitions of a positive integer n, using parts up to size m, is the number

  • f ways in which n can be expressed as the sum of positive integer parts up to m in

increasing order.

31

  • Recursive decomposition: finding

simpler instances of the problem.

  • Explore two possibilities:
  • Use at least one 4
  • Don't use any 4
  • Solve two simpler problems:
  • count_partitions(2, 4)
  • count_partitions(6, 3)
  • Tree recursion often involves

exploring different choices. def count_partitions(n, m): if n == 0: return 1 elif n < 0: return 0 elif m == 0: return 0

else: with_m = count_partitions(n-m, m) without_m = count_partitions(n, m-1) return with_m + without_m

(Demo)

pythontutor.com/composingprograms.html#code=def%20count_partitions%28n,%20m%29%3A%0A%20%20%20%20if%20n%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20return%201%0A%20%20%20%20elif%20n%20<%200%3A%0A%20%20%20%20%20%20%20%20return%200%0A%20%20%20%20elif%20m%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20return%200%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20with_m%20%3D%20count_partitions%28n-

slide-32
SLIDE 32

Sierpinski Triangle

(1, 1) (0, 0) (1/2, sqrt(3)/2) (1/2, 0) (1/4, sqrt(3)/4)