CH3 Functions

calling a function: function_name(parameters)

Basic function


In [1]:
def hello(a,b):
    return a+b

In [2]:
print hello(1,2)


3

In [3]:
print hello('a','b')


ab

Remember indentation is important


In [4]:
def hello1(a,b):
    return a+b

Use a tap or specific amount of white space. Use one of it for the whole script, not both.

Recursive function

recursive function is an easy way to solve some mathemtical problems but performance varies. The following is an example of a recursive function calculating the nth number in the Fibonacci Sequence.


In [5]:
def Fibonacci(n):
    if n < 2: 
        return n
    else: 
        return Fibonacci(n-1)+Fibonacci(n-2)
print Fibonacci(10)


55

In [6]:
def Fibonacci(n):
    return n if n < 2 else Fibonacci(n-1)+Fibonacci(n-2)
print Fibonacci(10)


55

Very important: "call-by-value" or "call-by-reference"?

It is not a simple question, it often confused many people..We now try to do some testing..


In [7]:
a = 'Alice'
print a
def change_my_name(my_name):
    my_name = 'Bob'
change_my_name(a)
print a


Alice
Alice

In [8]:
a = 'Alice'
print a
def change_my_name(my_name):
    my_name = 'Bob'
    return my_name
b = change_my_name(a)
print b


Alice
Bob

So is it "call-by-value"? The value does not changed?

But Try this:


In [9]:
a_list_of_names = ['Alice','Bob','Christ','Dora']
print a_list_of_names

def change_a_value(something):
    something[0] = 'Not Alice'
    
change_a_value(a_list_of_names)
print a_list_of_names


['Alice', 'Bob', 'Christ', 'Dora']
['Not Alice', 'Bob', 'Christ', 'Dora']

Confused? Why the list is changeable but the string is not?


In [10]:
a_list_of_names = ['Alice','Bob','Christ','Dora']
print a_list_of_names
a_new_list_of_names = a_list_of_names
print a_new_list_of_names

def change_a_value(something):
    something[0] = 'Not Alice'
change_a_value(a_list_of_names)

print "After change_a_value:"
print a_list_of_names
print a_new_list_of_names

print "Is 'a_new_list_of_names' same as 'a_list_of_names' ?"
print a_new_list_of_names is a_list_of_names


['Alice', 'Bob', 'Christ', 'Dora']
['Alice', 'Bob', 'Christ', 'Dora']
After change_a_value:
['Not Alice', 'Bob', 'Christ', 'Dora']
['Not Alice', 'Bob', 'Christ', 'Dora']
Is 'a_new_list_of_names' same as 'a_list_of_names' ?
True

More Confused? Why the function return the same object, is it say that it is call-by-reference?


In [11]:
some_guy = 'Alice'
a_list_of_names = []
a_list_of_names.append(some_guy)
print "Is 'some_guy' same as the first element in a_list_of_names ?"
print (some_guy is a_list_of_names[0])


Is 'some_guy' same as the first element in a_list_of_names ?
True

In [12]:
another_list_of_names = a_list_of_names
print "Is 'a_list_of_names' same as the 'another_list_of_names' ?"
print (a_list_of_names is another_list_of_names)


Is 'a_list_of_names' same as the 'another_list_of_names' ?
True

In [13]:
some_guy = 'Bob'
another_list_of_names.append(some_guy)
print "We have added Bob to the list, now is 'a_list_of_names' same as the 'another_list_of_names' ? "
print (a_list_of_names is another_list_of_names)


We have added Bob to the list, now is 'a_list_of_names' same as the 'another_list_of_names' ? 
True

In [14]:
print (some_guy,a_list_of_names,another_list_of_names)
some_guy = 'Christ'
print (some_guy,a_list_of_names,another_list_of_names)


('Bob', ['Alice', 'Bob'], ['Alice', 'Bob'])
('Christ', ['Alice', 'Bob'], ['Alice', 'Bob'])

You can see how the list element and the string object changing.

It turns out that there is two kind of object, mutable and immutable.


In [ ]: