In the context of programming, a function is a named sequence of statements that performs a computation. When you define a function, you specify the name and the sequence of statements. Later, you can “call” the function by name. We have already seen one example of a function call:
In [1]:
type(32)
Out[1]:
The name of the function is type. The expression in parentheses is called the argument of the function. The result, for this function, is the type of the argument.
It is common to say that a function “takes” an argument and “returns” a result. The result is called the return value.
In [2]:
int('32')
Out[2]:
In [3]:
int("hello")
The int()
can convert floating-point values to integers, but it doesn’t round off; it chops off the fraction part:
In [4]:
int(3.99999)
Out[4]:
In [5]:
int(-2.3)
Out[5]:
the float()
converts integers and strings to floating-point numbers:
In [6]:
float(32)
Out[6]:
In [7]:
float('34.89')
Out[7]:
Finally, str()
converts its argument to a string:
In [8]:
str(32)
Out[8]:
In [9]:
str(8.90)
Out[9]:
Python has a math module that provides most of the familiar mathematical functions. A module is a file that contains a collection of related functions.
Before we can use the module, we have to import it:
import math
This statement creates a module object named math. If you print the module object, you get some information about it:
In [10]:
import math
print(math)
The module object contains the functions and variables defined in the module. To access one of the functions, you have to specify the name of the module and the name of the function, separated by a dot (also known as a period). This format is called dot notation.
In [13]:
ratio = 70 / 100
decibels = 10 * math.log10(ratio)
decibels
Out[13]:
In [14]:
radians = 0.7
height = math.sin(radians)
height
Out[14]:
The expression math.pi
gets the variable pi from the math module. The value of this variable is an approximation of $\pi$, accurate to about 15 digits.
So far, we have looked at the elements of a program—variables, expressions, and statements—in isolation, without talking about how to combine them.
One of the most useful features of programming languages is their ability to take small building blocks and compose them.
In [21]:
degree = 180.0
x = math.sin(degree / 360.0 * 2 * math.pi)
x
Out[21]:
In [22]:
math.exp(math.log(x+1))
Out[22]:
In [23]:
def print_lyrics():
print("I'm a lumberjack, and I'm okay.")
print("I sleep all night and I work all day.")
In [24]:
print_lyrics()
The def
is a keyword that indicates that this is a function definition. The name of the function is print_lyrics
.
In [25]:
print(print_lyrics)
In [26]:
type(print_lyrics)
Out[26]:
Once you have defined a function, you can use it inside another function. For example:
In [27]:
def repeat_lyrics():
print_lyrics()
print_lyrics()
In [28]:
repeat_lyrics()
The statements inside the function do not get executed until the function is called, and the function definition generates no output. Another thing is that you have to create the function before using it :)
Knowing the order of statements are executed is called the flow of execution.
Execution always begins at the first statement of the program. Statements are executed one at a time, in order from top to bottom.
Some of the built-in functions we have seen require arguments. For example, when you call math.sin
you pass a number as an argument. Some functions take more than one argument: math.pow
takes two, the base and the exponent.
Inside the function, the arguments are assigned to variables called parameters. Here is an example of a user-defined function that takes an argument:
In [30]:
def print_twice(bruce):
print(bruce)
print(bruce)
print_twice("Kemal")
This function assigns the argument to a parameter named bruce
. When the function is called, it prints the value of the parameter (whatever it is) twice.
This function works with any value that can be printed, in our case "kemal"
.
In [31]:
print_twice(math.pi)
In [32]:
print_twice(16)
In [33]:
print_twice(math.cos(math.pi))
In [34]:
michael = 'Eric, the half a bee.'
print_twice(michael)
The name of the variable we pass as an argument (michael
) has nothing to do with the name of the parameter (bruce
). It doesn’t matter what the value was called back home (in the caller); here in print_twice
, we call everybody bruce
.
When you create a variable inside a function, it is local, which means that it only exists inside the function. For example:
In [35]:
def cat_twice(part1, part2):
cat = part1 + part2
print_twice(cat)
This function takes two arguments, concatenates them, and prints the result twice. Here is an example that uses it:
In [36]:
line1 = 'Bing tiddle '
line2 = 'tiddle bang.'
cat_twice(line1, line2)
When cat_twice
terminates, the variable cat
is destroyed. If we try to print it, we get an exception:
In [37]:
print(cat)
Some of the functions we are using, such as the math functions, yield results; for lack of a better name, I call them fruitful functions. Other functions, like print_twice
, perform an action but don’t return a value. They are called void functions.
When you call a fruitful function, you almost always want to do something with the result; for example, you might assign it to a variable or use it as part of an expression:
In [40]:
x = math.cos(10)
print(x)
golden = (math.sqrt(5) + 1) / 2
print(golden)
When you call a function in interactive mode, Python displays the result:
But in a script, if you call a fruitful function all by itself, the return value is lost forever!
Void functions might display something on the screen or have some other effect, but they don’t have a return value. If you try to assign the result to a variable, you get a special value called None
.
In [41]:
result = print_twice('Bing')
In [42]:
print(result)
It may not be clear why it is worth the trouble to divide a program into functions. There are several reasons:
from
Python provides two ways to import modules; we have already seen one:
In [44]:
import math
print(math)
print(math.pi)
If you import math
, you get a module object named math
. The module object contains constants like pi
and functions like sin
and exp
.
But if you try to access pi
directly, you get an error.
As an alternative, you can import an object from a module like this:
In [45]:
from math import pi
In [46]:
pi
Out[46]:
Now you can access pi
directly, without dot notation.
Or you can use the star operator to import everything from the module.
The advantage of importing everything from the math module is that your code can be more concise. The disadvantage is that there might be conflicts between names defined in different modules, or between a name from a module and one of your variables.
In [47]:
from math import *
In [48]:
sin(cos(pi))
Out[48]:
Exercise 1: Python provides a built-in function called len
that returns the length of a string, so the value of len('allen')
is 5.
Write a function named right_justify
that takes a string named s as a parameter and prints the string with enough leading spaces so that the last letter of the string is in column 70 of the display.
In [ ]:
Exercise 2: A function object is a value you can assign to a variable or pass as an argument. For example, do_twice
is a function that takes a function object as an argument and calls it twice:
def do_twice(f):
f()
f()
Here’s an example that uses do_twice
to call a function named print_spam
twice.
def print_spam():
print('spam')
do_twice(print_spam)
do_twice
so that it takes two arguments, a function object and a value, and calls the function twice, passing the value as an argument.print_spam
, called print_twice
, that takes a string as a parameter and prints it twice.do_twice
to call print_twice twice, passing 'spam'
as an argument.do_four
that takes a function object and a value and calls the function four times, passing the value as a parameter. There should be only two statements in the body of this function, not four.
In [ ]: