Study material generated by AI from this openly licensed book (CC BY-NC 3.0). Not affiliated with or endorsed by the publisher.
Think Python, 2nd Edition, by Allen B. Downey, Green Tea Press, licensed under CC BY-NC 3.0. Read the original free
Loading…
Chapter 3 · pp. 39–50
Functions
A function is a named chunk of code that you can run whenever you need it. In this chapter you will use functions that Python already provides, then write your own. You will also learn how Python keeps track of where it is while running them, and why variables inside a function stay private to it.
Calling functions and passing values
A function is a named sequence of statements that performs a computation. You define it once, giving it a name and some statements. Later you run it by calling its name (p. 39). For example, type(42) calls the function type and gives back <class 'int'>.
The value inside the parentheses is the argument. We say the function "takes" the argument and "returns" a result, which is called the return value (p. 39). In type(42), the argument is 42 and the return value is the type int. Some functions take more than one argument. For instance, math.pow takes a base and an exponent (p. 43).
Type conversion functions
Three built-in functions convert a value from one type to another (pp. 39–40):
int('32') gives 32. But int('Hello') raises a ValueError, because that text cannot be turned into an integer.
int does not round. It chops off the fraction, moving toward zero. So int(3.99999) is 3 and int(-2.3) is -2.
float(32) gives 32.0, and float('3.14159') gives 3.14159.
str(32) gives the string '32'.
A common mistake is to expect int(3.99999) to give 4. It does not.
Modules and math functions
A module is a file that holds a collection of related functions. To use one, first run an import statement such as import math. This creates a module object named math (p. 40). Then you call a function with dot notation: the module name, a dot, and the function name. Examples are math.sqrt(2) and math.log10(ratio) (p. 40). The module also holds variables, such as math.pi. That value approximates π and is accurate to about 15 digits (p. 40).
The trigonometric functions (sin, cos, tan) expect angles in radians, not degrees. To convert, divide the degrees by 180 and multiply by π (p. 40):
radians=180degrees×π
In code, radians = 45 / 180.0 * math.pi. Then math.sin(radians) is about 0.7071. You can check this against 2/2, which has the same value (p. 40).
Composition
Composition means using an expression as part of a larger expression or statement. A function argument can be any expression, including arithmetic or another function call (p. 41, p. 48). Two examples:
math.sin(degrees / 360.0 * 2 * math.pi)
math.exp(math.log(x+1))
Almost anywhere you can put a value, you can put an expression. The one exception is the left side of an assignment, which must be a variable name. So minutes = hours * 60 is fine, but hours * 60 = minutes is a SyntaxError (p. 41).
Defining your own functions
You define a function with the keyword def, then a name, parentheses, and a colon. The indented lines that follow are the body (p. 41):
def print_lyrics():
print("I'm a lumberjack, and I'm okay.")
print("I sleep all night and I work all day.")
The first line is the header. It must end with a colon.
The body must be indented. By convention the indent is four spaces. The body can hold any number of statements (p. 41).
Function names follow the rules for variable names. They may use letters, digits and underscores, but cannot start with a digit or be a keyword (p. 41).
The empty parentheses mean the function takes no arguments (p. 41).
A definition creates a function object of type function, but it does not run the body and prints nothing (p. 42). The body runs only when you call the function, for example print_lyrics(). One function can also call another. repeat_lyrics calls print_lyrics twice (p. 42).
Flow of execution
The flow of execution is the order in which statements run. Execution starts at the first statement and goes top to bottom. A definition only creates the function object. A function call acts like a detour: control jumps into the body, runs it, and then returns to the spot where the call was made (p. 43). If one function calls another, Python keeps track and returns to the right place each time.
A function must be defined before it is called. That means the def statement has to run first. If a call comes before its definition, the name does not exist yet and Python reports an error (pp. 42–43). A function body can mention another function that is defined later, as long as that definition has run before the call actually happens.
Parameters and arguments
A parameter is a variable inside a function that receives the value of the argument. In def print_twice(bruce):, bruce is the parameter. Calling print_twice('Spam') assigns 'Spam' to bruce, so the function prints it twice (p. 43).
The argument can be any expression. It is evaluated once, before the call. So print_twice('Spam '*4) builds the string one time and then prints it twice (p. 44). The name of a variable you pass has no connection to the parameter name. If you pass michael, the function still calls it bruce (p. 44).
Local variables and stack diagrams
A variable created inside a function is local. It exists only while the function runs. Parameters are local too. In cat_twice(part1, part2), the variable cat is destroyed when the function ends. Trying print(cat) afterward gives NameError: name 'cat' is not defined (pp. 44–45). Likewise, bruce does not exist outside print_twice.
A stack diagram shows which variables exist where. Each function call is a frame, a box with the function's name and its variables and parameters (p. 45). Frames are stacked in the order of the calls:
__main__ is the topmost frame. It holds variables created outside any function.
cat_twice was called by __main__.
print_twice was called by cat_twice.
Each parameter refers to the same value as its argument. For example, part1 matches line1, and bruce matches cat (p. 45).
When an error occurs, Python prints a traceback. It lists the functions in the same order as the frames, from __main__ down, with the currently running function last (pp. 45–46).
Fruitful and void functions
Fruitful functions return a value. math.sqrt(5) is one. You normally store or use the result, for example golden = (math.sqrt(5) + 1) / 2. In interactive mode Python displays the result. In a script, though, calling math.sqrt(5) alone loses the result (p. 46).
Void functions perform an action, such as printing, but return no useful value. print_twice is void. If you assign its result to a variable, that variable holds None (p. 46). None is a special value of type NoneType. It is not the string 'None' (p. 46).
Why use functions?
Functions are worth the effort for four reasons (pp. 46–47):
Naming a group of statements makes a program easier to read and debug.
Moving repeated code into one function means a change is made in only one place.
A long program can be split into functions, debugged one at a time, and then assembled.
A well-written function, like print_twice, can be reused in many programs.
Check yourself
What do int(-2.3) and int(3.99999) return, and why is this not rounding?
Write the line that finds the sine of 90 degrees using the math module. Why must you convert first?
A program calls a function on its first line, and the def for that function is on the last line. What goes wrong, and why?
After cat_twice finishes, why does print(cat) cause an error?
What is the difference between a fruitful function and a void function? What does a variable hold if you assign it the result of a void function?