Sie sind auf Seite 1von 4

4-27-17 Csc 306 3! = 3 * 2!

Object oriented programming makes code 2! = 2 * 1


reusable, but does not mean program will run
faster Replacing the calculated values gives us the
following expression
Object has important property to change and
continues methods to change 4! = 4 * 3 * 2 * 1

Gps object-> should contain coordinates, when Generally, Recursion is a method where the
location change happens, should update people solution to a problem is based on solving
who needs to read info. Interface/core idea of smaller instances of the same problem.
gps
Powerful approach for complicated problems
Button->want to contain some text to label,
Ex: factorial=fact(n)
know if button got clicked (click event), once
clicked way to arrange action(behavior) 5! Is 5x4x3x2x1
Action=Behavior/status in object fact(n)=n x fact(n-1)
Recursion (ch15) could write for loop
Recursion is a way of programming or coding a but more complicated topics could be used with
problem, in which a function calls itself one or recursion
more times in its body
for loop faster, but some concepts not possible
Usually, it is returning the return value of this to solve without recursion
function call
recursion should finish at some point
If a function definition fulfils the condition of
recursion, we call this function a recursive if write function:
function
def factorial(n):
Termination condition: if n == 1:
return 1
A recursive function has to terminate to be used else:
in a program return n*factorial(n-1)
A recursive function terminates, if with every
before call function, need to make sure n is
recursive call the solution of the problem is
positive integer, don’t want to start a negative
downsized and moves towards a base case
integer
A base case is a case, where the problem can be trust factorial will take care of problem
solved without further recursion
factorial(4) goes to else and will return n times
A recursion can lead to an infinite loop, if the factorial (4-1)
base case is not met in the calls. returns 4 x factorial (3)

Example: then factorial(3) returns 3 x factorial (2)


4! = 4 * 3!
then factorial (2) returns 2 x factorial (1)
then factorial (1) returns 1 x factorial (0) Fibonacci numbers are the numbers of the
following sequence of integer values:
end result will return 24 0,1,1,2,3,5,8,13,21,34,55,89, ...

Recursive Functions in Python The Fibonacci numbers are defined by:


Ex: Fn = Fn-1 + Fn-2
with F0 = 0 and F1 = 1
def factorial(n):
if n == 1: The Fibonacci numbers are the result of an
return 1 artificial rabbit population, satisfying the
else: following conditions:
return n * factorial(n-1) a newly born pair of rabbits, one male, one
We can track how the function works by adding female, build the initial population
two print() function to the previous function these rabbits are able to mate at the age of one
definition: month so that at the end of its second month a
def factorial(n): female can bring forth another pair of rabbits
print("factorial has been called with n = " + these rabbits are immortal
str(n)) a mating pair always produces one new pair
if n == 1: (one male, one female) every month from the
return 1 second month onwards
else:
res = n * factorial(n-1) The Fibonacci numbers are the numbers of
print("intermediate result for ", n, " * rabbit pairs after n months, i.e. after 10 months
factorial(" ,n-1, "): ",res) we will have F10 rabbits.
return res
The Fibonacci numbers are easy to write as a
print(factorial(5)) Python function. It's more or less a one to one
mapping from the mathematical definition:
This Python script outputs the following results: def fib(n):
factorial has been called with n = 5 if n == 0:
factorial has been called with n = 4 return 0
factorial has been called with n = 3 elif n == 1:
factorial has been called with n = 2 return 1
factorial has been called with n = 1 else:
intermediate result for 2 * factorial( 1 ): 2 return fib(n-1) + fib(n-2)
intermediate result for 3 * factorial( 2 ): 6
intermediate result for 4 * factorial( 3 ): 24 An iterative solution for the problem looks
intermediate result for 5 * factorial( 4 ): 120 more like the mathematical definition:
120 def fibi(n):
a, b = 0, 1
Let's have a look at an iterative version of the for i in range(n):
factorial function. a, b = b, a + b
def iterative_factorial(n): return a
result = 1 If you check the functions fib() and fibi(), you
for i in range(2,n+1): will find out that the iterative version fibi() is a
result *= i lot faster than the recursive version fib(). To get
return result an idea of how much this "a lot faster" can be,
we have written a script where we you the
timeit module to measure the calls:

from timeit import Timer


from fibo import fib

t1 = Timer("fib(10)","from fibo import fib")


We can see that the subtree f(2) appears 3
for i in range(1,41): times and the subtree for the calculation of f(3)
s = "fib(" + str(i) + ")" two times.
t1 = Timer(s,"from fibo import fib") If you imagine extending this tree for f(6), you
time1 = t1.timeit(3) will understand that f(4) will be called two
s = "fibi(" + str(i) + ")" times, f(3) three times and so on
t2 = Timer(s,"from fibo import fibi")
time2 = t2.timeit(3) recursion doesn't remember previously
print("n=%2d, fib: %8.6f, fibi: %7.6f, calculated values
percent: %10.2f" % (i, time1, time2,
time1/time2)) We can implement a "memory" for our
time1 is the time in seconds it takes for 3 calls recursive version by using a dictionary to save
to fib(n) and time2 respectively the time for the previously calculated values.
fibi(). If we look at the results, we can see that memo = {0:0, 1:1}
calling fib(20) three times needs about 14 def fibm(n):
milliseconds. fibi(20) needs just 0.011 if not n in memo:
milliseconds for 3 calls. So fibi(20) is about 1300 memo[n] = fibm(n-1) + fibm(n-2)
times faster then fib(20). return memo[n]
fib(40) needs already 215 seconds for three We time it again to compare it with fibi():
calls, while fibi(40) can do it in 0.016 from timeit import Timer
milliseconds. fibi(40) is more than 13 millions from fibo import fib
times faster than fib(40).
t1 = Timer("fib(10)","from fibo import fib")
n= 1, fib: 0.000004, fibi: 0.000005, percent:
0.81 for i in range(1,41):
n= 2, fib: 0.000005, fibi: 0.000005, percent: s = "fibm(" + str(i) + ")"
1.00 t1 = Timer(s,"from fibo import fibm")
n= 3, fib: 0.000006, fibi: 0.000006, percent: time1 = t1.timeit(3)
1.00 s = "fibi(" + str(i) + ")"
t2 = Timer(s,"from fibo import fibi")
What's wrong with our recursive time2 = t2.timeit(3)
implementation? print("n=%2d, fib: %8.6f, fibi: %7.6f,
percent: %10.2f" % (i, time1, time2,
Let's have a look at the calculation tree, i.e. the time1/time2))
order in which the functions are called. fib() is
substituted by fib(). We can see that it is even faster than the
iterative version. Of course, the larger the
arguments the greater the benefit of our
memorization:
n= 1, fib: 0.000011, fibi: 0.000015, percent:
0.73
n= 2, fib: 0.000011, fibi: 0.000013, percent: line.insert(0,1)
0.85 line.append(1)
n= 3, fib: 0.000012, fibi: 0.000014, percent: return line
0.86
print(pascal(6))
Solution to our first exercise on recursion:
Mathematically, we can write it like this:
f(1) = 3,
f(n+1) = f(n) + 3

A Python function can be written like this:


def mult3(n):
if n == 1:
return 3
else:
return mult3(n-1) + 3

for i in range(1,10):
print(mult3(i))
Solution to our second exercise:
def sum_n(n):
if n== 0:
return 0
else:
return n + sum_n(n-1)
Solution for creating the Pacal triangle:
def pascal(n):
if n == 1:
return [1]
else:
line = [1]
previous_line = pascal(n-1)
for i in range(len(previous_line)-1):
line.append(previous_line[i] +
previous_line[i+1])
line += [1]
return line

print(pascal(6))
Alternatively, we can write a function using list
comprehension:
def pascal(n):
if n == 1:
return [1]
else:
p_line = pascal(n-1)
line = [ p_line[i]+p_line[i+1] for i in
range(len(p_line)-1)]

Das könnte Ihnen auch gefallen