Chapter 3
Functions in Python allow you to break a task down into appropriate subtasks. They are one of the powerful tools of abstraction that higher-level programming languages provide. Ideally, every function has a single, well-defined purpose.
Consider this example, which uses the sqrt() function from the math module to implement hypot(), also in the math module.
Listing 3.1: Hypotenuse
1 # hypot.py
2
3 from math import sqrt
4
5 def myhypot(x, y):
6 return sqrt(x ** 2 + y ** 2)
7
8 def main():
9 a = float(input("a: "))
10 b = float(input("b: "))
11 print("Hypotenuse:", myhypot(a, b))
12
13 main()
Each chapter, as we begin with a new example, type the program in to your programming environment (such as IDLE), save it with the indicated name, and run it a few times before you continue. Try to determine how the program works, even though it may use new features that you have not seen before.
For our purposes, a Python program can be thought of as a collection of function definitions with one main function call. Listing 3.1 defines and calls two functions: myhypot() and main(). A function cannot be called unless it has been defined. The function myhypot() is defined in lines 5–6 and called in line 11. The function main() is defined in lines 8–11 and called in line 13. The order of function definitions is not important: as long as myhypot() is defined somewhere in this file, the definition of main() could have come first.
Code that is outside all function definitions (like all of Listings 1.1 and 2.1) is directly executed when the program is run. In Listing 3.1, only the function call in line 13 is outside all function definitions, and so it will be executed when the program is run. In a sense, it “drives” execution of the whole program. Because of this, the main() function is known as the driver. Usually, the driver definition and call are put at the end of a Python program.
A function definition specifies the code that will be executed when the function is called. The syntax of a function definition looks like this:
def <function>(<parameters>):
<body>
The def line must end with a colon. The colon signals the beginning of an indented block of code, in this case called the body of the function. The body is the code that will be executed when the function is called and may consist of any number of lines. In Listing 3.1, line 6 is the entire body of the myhypot() function.
Parameters are used to send additional information to a function so that it can do its job. The <parameters> in a function definition are optional. In Listing 3.1, the myhypot() function has two parameters named x and y.
Usually, function definitions appear near the top of Python programs, after any import statements, but before any directly executable code.
Once a function has been defined, it may be called, meaning that it will be executed with particular arguments passed as the values for its parameters. The syntax for a function call is:
<function>(<arguments>)
When this expression appears in a program statement that is being executed, the function body executes, using the argument values as the values of the parameters.
In Listing 3.1, the function myhypot() is called in line 11. The arguments being passed or sent to myhypot() are the values of a and b at the time the program runs, after the input() expressions. The value of a will be used as the value of x in myhypot(), and the value of b will be used as y. For example, if you enter 4 and 7 in response to the input() expressions, then x will get the value 4 (the value of a) and y will get 7 (the value of b) when myhypot() is called on line 11.
Note: the name of an argument does not have to be the same as its corresponding parameter.
Function calls may be nested as in lines 9 and 10 of Listing 3.1. The inner function (in these cases, input()) runs first, and then the output of that function is immediately sent as the argument to the outer function (float()).
A return statement may optionally appear anywhere in the body of a function, and looks like this:
return <expression>
When this statement is executed inside of a function, it immediately terminates the function and returns the value of its <expression> as the value of the function call. In fact, the <expression> is also optional: if no expression is given, the value returned is the special value None.
In Listing 3.1, the return statement in line 6 computes and returns the length of the hypotenuse. The two steps of computing and returning could be separated:
def myhypot(x, y):
hyp = sqrt(x ** 2 + y ** 2)
return hyp
This version will work exactly the same as the original.
If a function does not contain a return statement, the function returns the value None when the last executable statement of its body finishes.
Variables used for the first time inside of a function definition are called local because their use is limited to within the definition of that function. In other words, attempts to access that variable from outside the function definition will fail. The scope of a variable is the part of the program in which the variable may be accessed, so the scope of a local variable in Python is the function definition in which it is used. Variables defined outside of all function definitions are called global; we will rarely use global variables in this text.
Parameters in a function definition have the same scope as local variables: they may not be accessed outside of the function definition.
In Listing 3.1, a and b are local variables in the main() function, whereas myhypot() does not have any local variables.
The input() function always returns user input as a string. In order to process numeric input, we need to convert the string to either an integer or float. Python has the following built-in functions to convert the types we have seen so far:
int(x) |
Convert x to an integer, truncating floats towards 0. |
int(x, b) |
Convert x given in base b to an integer. |
float(x) |
Convert x to a floating-point value. |
str(x) |
Convert x to a string. |
For the input of numeric data, choose between int() and float() depending on the context. Truncation means that any non-integer fraction is dropped, so, for example, int(3.975) returns 3, and int(−3.975) is −3.
An important part of writing functions (and programs in general) is testing them to make sure that they compute exactly what you intend. Some basic principles of testing are:
Test all important families of inputs. For example, include both positive and negative input values if they are appropriate. Test with both integers and floating point values.
Test known cases. Use input values that give outputs you can predict.
Test boundaries. For example, be sure your function behaves correctly at minimum and maximum input values (when appropriate).
Testing is probably the most important tool we have to improve software quality.
Explain the behavior you observe.
Enter interest rates as decimals: for example, a rate of 4% should be entered as 0.04. Use your program to determine the number of years it takes a principal to double with interest rate 1.5%.
Use your program to determine the difference over 20 years on a $1000 balance between compounding yearly and compounding monthly at 8% interest.
Use appropriate functions. Use your program to estimate the temperature at which the vapor pressure is approximately 10 mb.
3.22.61.30