<jupyter_start><jupyter_text>FunctionsFunctions are defined as```def function_name(parameters):```<jupyter_code>def hello(a,b):
    return a+b
hello(1,1)
hello('a','b')<jupyter_output><empty_output><jupyter_text>Recursive functionrecursive 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.<jupyter_code>def Fibonacci(n):
    if n < 2: 
        return n
    else: 
        return Fibonacci(n-1)+Fibonacci(n-2)
print Fibonacci(10)
def Fibonacci(n):
    return n if n < 2 else Fibonacci(n-1)+Fibonacci(n-2)
print Fibonacci(10)<jupyter_output>55<jupyter_text>Class Class is a blueprint defining the charactaristics and behaviors of an object. ```pythonclass MyClass:    ...    ...```For a simple class, one shall define an instance```python__init__()```to handle variable when it created. Let's try the following example:<jupyter_code>class Person:
    def __init__(self,age,salary):
        self.age = age
        self.salary = salary
    def out(self):
        print self.age
        print self.salary<jupyter_output><empty_output><jupyter_text>This is a basic class definition, the `age` and `salary` are needed when creating this object. The new class can be invoked like this:<jupyter_code>a = Person(30,10000)
a.out()<jupyter_output>30
10000<jupyter_text>The ``__init__`` initilaze the variables stored in the class. When they are called inside the class, we should add a ``self.`` in front of the variable. The ``out(Self)`` method are arbitary functions that can be used by calling Yourclass.yourfunction(). The input to the functions can be added after the self input.  Scope of variables 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..<jupyter_code>a = 'Alice'
print a
def change_my_name(my_name):
    my_name = 'Bob'
change_my_name(a)
print a
a = 'Alice'
print a
def change_my_name(my_name):
    my_name = 'Bob'
    return my_name
b = change_my_name(a)
print b<jupyter_output>Alice
Bob<jupyter_text>So is it "call-by-value"? The value does not changed? But Try this:<jupyter_code>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<jupyter_output>['Alice', 'Bob', 'Christ', 'Dora']
['Not Alice', 'Bob', 'Christ', 'Dora']<jupyter_text>Confused? Why the list is changeable but the string is not?<jupyter_code>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<jupyter_output>['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<jupyter_text>More Confused? Why the function return the same object, is it say that it is call-by-reference?<jupyter_code>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])
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)
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)
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)<jupyter_output>('Bob', ['Alice', 'Bob'], ['Alice', 'Bob'])
('Christ', ['Alice', 'Bob'], ['Alice', 'Bob'])
{'fraction_non_alphanumeric': 0.11453320500481232, 'fraction_numerical': 0.007459095283926853, 'mean_word_length': 6.057724957555179, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '207478', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1560, 'n_tokens_neox': 1486, 'n_words': 411, 'path': 'notebooks/Jan2018/python-functions-class.ipynb', 'repo_name': 'ryan-leung/2016-JAN_python_workshop', 'size': '4156'}