Functions

A function, also called a method or subroutine, is a portion of code that performs a specific task.

The purpose of creating a function is to help organize your code. By creating a function for each task that you will use more than once within your program, you avoid duplicating code. The result of this is smaller, easier to understand programs.

Creating a Function in Python
In order to create a function, they must first be defined. This is similar to initializing a variable, except the variable name is now the function name and the value of the variable is the code run by the function.

To define a function, you define it with a function header and body of the form: def function_name(function_parameter1, function_parameter2, ...): #body #put your function code here #    #as many lines of code as you like return some_variable; Let's breakdown what each of these parts mean:
 * def
 * ​This is just a identifier that tells Python that the upcoming code is a function header
 * It is required for defining a function and can not be changed
 * function_name
 * This is the name you give the function in order to indentify it.
 * The name should be all lower case, with underscores for spaces, and only the letters a-z.
 * function_parameter1, 2, etc. (also known as function "arguments")
 * ​These are variables that you must "send" or "pass" to a function so that it may read them.
 * Variables must be "sent" or "passed" because of a concept in programming called scope, which will be explained in a later section.
 * These function parameters are referenced in the body of the function with the variable name given to them in the function header. This variable name does not have to be the same as the variable that was passed to the function.
 * Function parameters are optional. You can have from 0 to 255 parameters for a function. However, it is suggested that you use as small an amount of parameters as you can to make code readable and efficient.
 * The Function Body
 * ​This is the code that is executed everytime your function is run.
 * The code within the function body should be indented one tab in order for Python to recognize that it is code within the function. (Note: If blocks and loop blocks should be indented even further if they are within the function.
 * You may have as many lines of code as you'd like in a function but, like parameters, you should only use as many lines as you need to accomplish your task.
 * return
 * The return statement is used to pass a variable from the function back to the code that called the function. An example will be shown later in this section.
 * You can have as many return statements as you'd like in your function in order to end the function prematurely and pass back the variable at that point. However, in most case this makes function code harder for others to read because they have to be conscious of all the exit points of the function. Try to limit yourself to only returning a variable at the end of a function.
 * Return statements are optional, but you should note that if you do not return anything from a function, it still returns "None" implicitly.

Calling a Function
Functions are called using the function name you declared it with. Conceptually, you can think of a function just as code that you are inserting into where you call the function. For example: def print_hello_twice: print "Hello" print "Hello" print_hello_twice Will output: Hello Hello This is exactly the same as if you just typed the code within the function body outside of the function.

Usually functions have variables that they return back to the caller using its return statement: def is_name_jim(name): return name == "Jim" # True if name is Jim, False otherwise check_john = is_name_jim("John") # check_john now equals False check_jim = is_name_jim("Jim") # check_jim now equals True This is an extremely simple example that you probably will not see in real-world use. However, it shows how variables are returned from the scope of a function are given back to the caller of the function.

Let's use a more practical example to combine what we just talked about: def find_sum(list): # Finds the sum of all values in a list sum = 0 for (x in list): sum += list[x] return sum a = [4,5,6] print find_sum(a) #prints 15 print find_sum([1,1,1,1]) #prints 4 print find_sum([70,30,20,10]) #prints 130 Now the use of a function is more apparent -- instead of rewriting the loop within the function over and over again, you just write it once in the function and then call it every time you need it.

It is also important that you understand how the return statement works in the previous example. The function calculates the sum and the returns it. Because the "print" function called the find_sum function, the returned result (i.e. the variable "sum") of find_sum is passed to print. This is called chaining functions. This is a useful concept because it can keep code short.

To contrast function chaining, let's use an example that does not chain functions, using our find_sum example above: a = [4,5,6] the_sum_i_want = find_sum(a) print the_sum_i_want # prints 15 Had we used function chaining, it would just look like this: print find_sum([4,5,6]) # prints 15 You should think about the initialization of a list using "[4,5,6]" as just another function, that creates a list inline with the values 4, 5, and 6.

Another Note: Function code is not run until it is called, no matter where it is included in the file. If the only code in your script is: def say_hello_to(name): return "Hello, " + name What is the result of your program? Nothing. This is because a function must be called in order to run: def say_hello_to(name): return "Hello, " + name print say_hello_to("Jim") # prints "Hello, Jim"

Scope
Scope is the context in which a variable can be referenced within a computer program. In other words, sections of programs that have variables declared within them might not allow these variables to be accessed in other parts of the program.

Knowing how scope works in regard to Python functions is important for preventing frustration and also realizing the importance of functions.

Any variables declared in a Python function, including the function's parameters, are accessible only within that function. If you think about the code that is just sitting in your file and not wrapped in a "def" block as a function as well, this still holds true. For example: some_var = 10 def my_function: # declare a function with no parameters inside_var = "Can't touch this!" some_var = some_var + 5 # Throws an error when my_function is called! print inside_var # Also throws an error! As you can see, variables in the scope of the file can not be accessed inside the function. Also, variables within the scope of the function can not be accessed outside of that function in the rest of the file.

This is where parameters come in. If you want to pass a variable from one scope to another, you must allow the function to accept a variable and then pass it when you call a function. You already saw how to use functions to pass a list in the previous section.

Also note -- If a function accepts variables, you must pass them: def i_need_arguments(arg1, arg2, arg3): print "Hello, " + arg1 + ", " + arg2 + ", and " + arg3 i_need_arguments #Error i_need_arguments("Bill", "Jane") #Also an error -- you need 3 arguments! i_need_arguments("Jim", "Jack", "John", "Jose") #Another error -- too many arguments! i_need_arguments("Athos", "Porthos", "Aramis") #Prints 'Hello, Athos, Porthos, and Aramis' If parameters are how variables are passed from one scope into a function's scope, then the return statement is the opposite -- it passes a variable from the function's scope back to the scope of the caller: def add_py_extension(filename) filename_with_extension = filename + ".py" return filename_with_extension changed_filename = add_py_extension("my_file") # changed_filename now equals "my_file.py" What if I need to return more than one variable from a function? Python makes this easy by returning your values as a tuple: def add_offset_to_points(x, y, offset): return (x + offset, y + offset) (new_x, new_y) = add_offset_to_points(7, 15, 10) print new_x #prints 17 print new_y #prints 25