08: Functions

Introduction

We’ve used Python for an array of applications so far. You should by now be familiar with loops, lists, strings, mathematical operations, and how they all work together. We’ve also used a lot of Python’s built in functions to help us get the job done! Here’s a few examples:

import math 

myRange = range(0, 10) 

mySqr = math.sqrt(2) 

newList = myList.append(newElement)

It’s clear to see how these functions simplify our code. Imagine having to write the range out every time, or to have to create a new list every time you wanted to add a new element! Functions make our lives easier, and help us follow the DRY method discussed briefly in our FOR loop tutorial.

Sometimes, we want to create our own functions. This allows us to simplify complicated parts of code, and allows us to break our program into modules. The importance of modules is also good to know, and I’ll discuss that a bit later.

Function Definition

So, you want to make a function. Sometimes it can be difficult to think about where to start! In programming, it’s always good to start out with “skeleton code”. This is code that gives us the structure we need, then we can fill it in with more code.

One function you’re already probably familiar with defining is the main() function. This usually contains the bulk of our program, and is defined like this:

def main(): 
    print "Hello World" 

main()

We can see how simple this definition is. Let this be our skeleton code.

Breaking it down, we can see the skeleton code has three parts. The first is the declaration. We tell Python that our function’s name is “main”, and that it takes zero arguments, which we can see since the parentheses “( )” are empty.

The second part of the function is the code, or definition. This tells us exactly what the function does. Here, our main() function prints “Hello World” to the Shell.

The last part is our function call. This is when we tell the interpreter that we actually want to run the code inside main. When the interpreter first goes through our code, it notes the definition of main. As it continues down, it sees that we then call on main() to perform its duties. That is why it’s important to always define functions at the top of your code!

A Simple Function

A simple example of a function would be one that prints a few values to the screen. This is a common task, and is a little bit redundant because Python has the “print” function available. Regardless, let’s use a function to print a String.

def printMyStuff(message): 
    print message 

def main(): 
    printThis = "Hello World" 
    printMyStuff(printThis) 

main()

Run this code from a new document. You can see that the message is printed, but not by our main() function. Instead, our main() function passes some information to another function called printMyStuff, which waits to receive some argument (in this case, message) before it runs.

If this is still unclear, picture each function as the member of your 1P03 team. Each member has a duty that must be fulfilled, but requires some information to complete that duty. Thus, each member waits until they receive the data necessary. Then, they process it, and hand it back. This cycle continues until the project is complete and you receive an A.

More Complex Functions

We’ve seen a simple function above. However, it is usually necessary to create functions that do a little more than just print a message. Let’s do a slightly more complicated example.

Let’s write a function that performs a complex mathematical equation on a number.

def complexMathEquation(number): 
    result = (number*6371^7)/10000 - number^2 + 1/number - 1    
    print result 

def main(): 
    myNumber = 10 
    complexMathEquation(myNumber) 

main()

You can see how this code could become complicated without the use of functions, especially if we had to use this equation many times.

Let’s try something else!

Create a function that takes a list of numbers as an argument, and prints the sum of those numbers. Remember to create the list of numbers and call your function inside your main(). When you’re done, check it with the code I’ve written below.

# This function computes the sum of all elements in a list 
def listSum(myList): 
    # Initialize sum 
    mySum = 0 
    # Perform summation 
    for i in range(len(myList)): 
        mySum = mySum + myList[i] 
        print mySum 

def main(): 
    # Define a list to test with 
    myList = [1, 5, 10, 25, 100, 4, 88, 21] 
    # Call the function on this list 
    listSum(myList) 

main()

Awesome! Let’s learn how to pass values back now.

Returning

Single Returns

In the previous examples, we were only printing from inside our functions. Most often, this is simply not enough. Like in the 1P03 example, information needs to be passed into functions, but also has to be passed back out. Take a look at this common function:

import math 
sqrtOfTwo = math.sqrt(2)

Let’s analyze the parts of this code:

  • math is a library, which contains a bunch of functions we can use.
  • sqrt() is one of the functions included in math. We access it with the syntax library.function(argument).
  • two (2) is our argument. In this case, a constant, but it can be a variable as well.
  • sqrtOfTwo is a variable that stores the result returned by math.sqrt().

When we call the function, it takes the ARGUMENT of 2, and RETURNS our value, which is equal to the square root of two. Returning is very important. We can change the functions above to return values to work with further, or even to send to even more functions.

Let’s look at our example from before:

def listSum(myList): 
    # Initialize sum 
    mySum = 0 
    # Perform summation 
    for i in range(len(myList)): 
        mySum = mySum + myList[i] 
    print mySum 

def main(): 
    myList = [1, 5, 10, 25, 100, 4, 88, 21] 
    listSum(myList) 

main()

How can we change this so that the printing can be done inside main()? We need to tell listSum() to return the sum it calculates. In Python, this is easy. We simply use the return command. Then, we add a variable in main() that will store the value returned by listSum(). Then, we simply print that new variable, inside main().

def listSum(myList): 
    mySum = 0 
    for i in range(len(myList)): 
        mySum = mySum + myList[i] 
    # Return our value 
    return mySum 

def main(): 
    myList = [1, 5, 10, 25, 100, 4, 88, 21] 
    # Call function and save returned value 
    result = listSum(myList) 
    print result 

main()

You’ll see the results are the same. However, know that the second method is better. Why?

Multiple Returns

We can also return more than one value at a time. We do this by separating the values we want to return by a comma, and saving them the same way to our target variables outside the function. This is simple:

def returnTwoNumbers(a, b): 
    num1 = a - 1 
    num2 = b - 1 
    # Return two numbers at the same time 
    return num1, num2 

def main(): 
    a = 5 
    b = 6 
    # Save the two returned numbers to n1 and n2 
    # in the same order they are returned. 
    n1, n2 = returnTwoNumbers(a, b) 

main()

Modular Programming

Functions can be used if we need to perform some process several times in our program. It can also be used to separate the duty of our code into modules. For example, we may have one function that sets up a list, one that performs our mathematical formula, and one that formats and prints the output. The reason we use three functions for this is simple. If we ever wanted to change the way that we perform the mathematical function, the only code we need to modify is that inside the appropriate function. The rest remains unchanged and works just as expected.

The math library is a sort of module. We can use it without knowing exactly how it works on the inside, and changes can be made to it without our knowledge, so long as the results are still correct.

Lab Notes

When writing labs that require functions, pay close attention to the lab manual. This will describe what functions you need, and what they are supposed to do. For example, the minor lab last week asked that the graphic window was created inside the GUI function. Many students created it and passed it in as a variable, and would lose marks on a major lab for that. Basically, as always, read the document given to you!

Secondly, some labs will require you to write a module or library. This basically means that it wants you to write a suite of functions that can be used elsewhere. So, you are to write something similar to (but less complex than) the math library. What this means is that the program does not necessarily have a main() program, and that you MUST NOT run main() at the bottom of your code like we have been doing. Basically, the code you submit should not do anything when run. Just write the functions so that someone else could use them, just like you use the functions from math. You can use a main() to test your code, but make sure you remove it before submitting it! Again, read the requirements carefully.