Functions#

One of the important principles of programming is: Don’t Repeat Yourself (DRY). This means that we should avoid repeating the same code with only small modifications.

We have seen that loops are one way to make the computer do the work, instead of writing a lot of repetitive code. Another way to reuse code is making functions. Functions are pieces of code that perform a specific task.

A function contains a (short) block of code/program statements. These statements are executed when we call the function. This way, we can perform a common operation many times without having to rewrite the code each time.

We can make more modular programs with functions.

Defining Functions#

Here is a simple function to print a greeting:

def greet():
    print('Hello class')
    print('Nice to meet you!')

We define a new function with the statement def, short for define. def is followed by the function name, and a set of parentheses. The function body follows on the next lines, and must be indented, like for loops. The function ends when there are more no more indented lines.

We can also define parameters to the function. If the function has parameters, we list those inside the parentheses. The parameters are also known as parameter variables.

def greet(name):
    print('Hello', name)
    print('Nice to meet you!')

Now we can call the function, giving it one argument:

greet('class')
greet('JUS5080')
Hello class
Nice to meet you!
Hello JUS5080
Nice to meet you!

The value of the argument is bound to the parameter variable when the function executes.

Functions can’t modify their arguments#

The argument value is copied to the parameter variable in the function. The parameter exists only inside the function. Therefore, if the function modifies the parameter variable, this does not affect the argument.

def normalize_name(name):
    name = name.strip()
    name = name.title()
    print('name in the function:', name)

my_name = '  bart von   simpson  '
normalize_name(my_name)
print('name after function call:', my_name)
name in the function: Bart Von   Simpson
name after function call:   bart von   simpson  

Return values#

Since functions can’t modify their arguments, we need some other way to pass information back to the caller. We do this with the return statement.

def normalize_name(name):
    name = name.strip()  # remove leading and trailing white space
    name = name.title()
    return name
my_name = '  bart von   simpson  '
new_name = normalize_name(my_name)
print('name after function call:', new_name)
name after function call: Bart Von   Simpson

Documenting Functions#

To help the reader we should start each function with a short comment that explains the purpose of the function and its parameters. The reader might be yourself at some point in the future.

def normalize_name(name):
    '''
    Removes whitespace and capitalizes initials.
    
    Params:
        name - string containing a name
    '''
    name = name.strip()
    name = name.title()
    return name
    
print(normalize_name('  bart  von  simpson  '))
Bart  Von  Simpson

Variable Scope#

Above, we saw that functions can modify their arguments. This is a consequence of variable scope. The scope of a variable is the region of code where it is defined, i.e. valid.

Local variables#

Variables that are defined inside a function are called local variables. Their scope starts at the line where the variable is declared and ends when the function ends. Parameter variables have the whole function as their scope.

Global variables#

Variables that are defined outside of any function, are called global variables, and have the rest of the file as their scope.

Main function#

Because global variables have so large scope, it can be difficult to reason about their behavior. Therefore, we should avoid global variables if possible. Write as much code as possible in functions. By convention, the main body of the program is in the main() function. Call main() to start the program.

def main():
    print('Testing normalize_name')
    print(normalize_name('  sir  robin  '))
    print(normalize_name('  King  arthur  '))

main()
Testing normalize_name
Sir  Robin
King  Arthur