Functions - basics
Contents
23. Functions - basics#
Author: Tue Nguyen
23.1. Outline#
Overview
Define and call a function
Parameters vs. arguments
Default arguments
23.2. Overview#
Roughly speaking, a function takes some inputs, does something with them, and spits out an output
Benefits
We define the logic once and reuse it as many times as we want
Easier to maintain and improve because the logic is in a single place
All lower-level details are abstracted away, making code more succinct and readable
Example
Suppose you have to frequently extract numbers from text strings
Instead of duplicating your code (potentially many lines) every time you do such a task, you can wrap your code into a function
When you need to extract numbers from a text string, you just need to call the function (one line)
Or when you need to improve your code, you have to make changes in one place (where the function is defined)
23.3. Define and call a function#
A function must be defined before being used
We use
def
to define a function as followsdef function_name(params): # Function body here
Parameters (or params) are the inputs to the function
Parameters are optional (a function might have no parameter)
The function name follows the rules and conventions introduced in the earlier lessons
The function body contains statements that handle some logic
A function might explicitly return a value to where it is called using the keyword
return
Otherwise,
None
will be returned by defaultDefining a function means writing code that specify
its name
parameters that it possibly take
what it does to the parameters
what value it returns
Calling a function means evoke the function to do something
Defining vs. calling
We define a function only once, but we can call it as many times as we want
We use
def
when define a function, but not when we call itWe cannot call a function that has not been defined yet
When defining a function, the inputs in the parentheses are called parameters
When calling a function, the inputs are called arguments
A function can
take no param, one params, or many params
explicitly return a value using return or implicitly return
None
23.3.1. No param, no return#
A function can have no params and returns nothing
a) Ex 1: define a function
# Define a function that prints out "Hi user"
def say_hi():
print("Hi user")
Comments
The function name is
say_hi
It takes has no params (empty parentheses)
It also returns nothing (no keyword
return
). Thus aNone
will be return by defaultWhat it does is just prints out the line
"Hi user"
b) Ex 2: call a function
# Now we call say_hi function defined above
say_hi()
Hi user
Comments
We see
"Hi user"
printed out as expectedHowever, do not confuse this printed text with the returned value
This function return
None
by defaultTo see this, try to assign this function call to a variable
# You see, the text "Hi user" is still printed out
x = say_hi()
Hi user
# Now verify that x is indeed None
print(x)
None
23.3.2. Has params, no return#
A function can have one or many params (separated by commas) and returns nothing
a) Ex 1: one param, no return
# Define a function that takes a name and say hi to that name
def say_hi(name):
print(f"Hi {name}")
# Call 1
say_hi("Anna")
Hi Anna
# Call 2
say_hi("Bob")
Hi Bob
b) Ex 2: many params, no return
# Define a function that takes first_name, last_name, and sex
# then print out a greeting
def say_hi(first_name, last_name, sex):
# Specify title
if sex == "M":
title = "Mr."
elif sex == "F":
title = "Ms."
else:
title = "Mr./Ms."
# Say hi
print(f"Hi {title} {first_name} {last_name}")
# Call 1
say_hi("Bob", "Dylan", "M")
Hi Mr. Bob Dylan
# Call 2
say_hi("Sia", "Kate", "F")
Hi Ms. Sia Kate
# Call 3
say_hi("Johan", "Smith", "N/A")
Hi Mr./Ms. Johan Smith
23.3.3. Has params, has return#
A function can have params and explicitly returns a value
a) Ex 1: add two numbers
# Define a function that takes 2 number and returns their sum
def add(a, b):
return a + b
# Call 1
add(2, 3)
5
# Call 2
add(-10, 20)
10
b) Ex 2: filter bad customer
# Define a function that take a list of customers (cust)
# another list of bad customers (bad_cust)
# and return those who are in cust but not in bad_cust
def filter_bad_cust(cust, bad_cust):
return [c for c in cust if c not in bad_cust]
# Init cust and bad_cust
cust = ["Jack", "Bob", "Anna", "Tom", "Andrew"]
bad_cust = ["Anna", "Bob"]
# Call the function
good_cust = filter_bad_cust(cust, bad_cust)
# Check the result
good_cust
['Jack', 'Tom', 'Andrew']
c) Ex 3: return more than one value
Python does NOT allow for returning multiple values
However, you can use wrap the values you want to return in a collection such as a list or tuple, and return that collection
# Define a function that return the perimeter and area of a rectangle
def compute_rect_peri_area(a, b):
peri = (a + b) * 2
area = a * b
return peri, area
# Call 1: get a tuple back
compute_rect_peri_area(2, 3)
(10, 6)
# Call 2: unpack the result
p, a = compute_rect_peri_area(2, 3)
print(p)
print(a)
10
6
23.4. Params vs. arguments#
Params are named variables appearing in the function’s signature when we define a function
They specify inputs that the function expects to receive when it is actually called
The function uses the params inside its body as regular variables
Arguments are actual values that are passed to the function when we call it
The order in which we pass the arguments must match that of the params
When we call a function and supply arguments, Python will assign the value of the arguments to the corresponding parameters and use those values to perform the logic inside the function body
For now, if a function has
N
params, we must supplyN
arguments when calling it
a) Ex 1: params
# Define a funtion
def say_hi(first_name, last_name):
print(f"Hi {first_name} {last_name}")
Comments
The
say_hi
function has 2 paramsfirst_name
andlast_name
These two params are used in the
print
statement inside the function body
b) Ex 2: argument
# Call 1
first = "John"
last = "Doe"
say_hi(first, last)
Hi John Doe
Comments
In the above function call, we pass two variables as the arguments to
say_hi
functionfirst
as the first argumentlast
as the second argument
Based on the order in the function’s signature in Ex 1, Python does the following
assign the value of
first
(which is"John"
) to paramfirst_name
assign the value of
last
(which is"Doe"
) to paramlast_name
then execute the body using those values
and we see
"Hi John Doe"
printed out
# Call 2
say_hi("John", "Doe")
Hi John Doe
Comments
Similar to Call 1, here we pass
"John"
and"Doe"
tosay_hi
directlyThe function uses those values inside its body and we see the same result printed out
c) Ex 3: not enough arguments
Try to
say_hi("John")
orsay_hi("Doe")
and you will get an errorThe error looks like this
say_hi() missing 1 required positional argument: 'last_name'
This means that
The function
say_hi
expects 2 arguments, but you supplied only oneBased on the order, this one will goes to the first param (
first_name
)Thus, you missed the argument for the second param (
last_name
)
23.5. Default arguments#
Parameters allow us to customize the behavior of a function
The more params, the more flexible we have
However, more parameters also cause more problems
Suppose the function has 10 params, then we have to supply 10 arguments in every call
We also have to remember the correct order when passing the arguments
One solution is to use default values for some parameters to avoid passing too many arguments in each call
The default values are set when we define the function
In a function call, if we don’t supply the corresponding argument, then the default values will be used instead
These default values are called default arguments
Note that all parameters that have default values must be specified to the rightmost of the param list in the function’s signature
a) Ex 1: greeting
Suppose we want to say hi to a user using his/her username
If the user has logged in, then we want to print out
"Hi {username}"
However, if the user has not logged in (we do not know the user name), then we want to print out
"Hi user"
A good convention: unlike in assignments, there is no space around
=
in the function signature
# Define the function
def say_hi(username="user"):
print(f"Hi {username}")
# Call 1: if we don't supply the argument for the username
# then say_hi will use the value "user"
# We will not get an error
say_hi()
Hi user
# Call 1: if we do supply the argument for username
# then say_hi will use the value we provided
say_hi("Tom")
Hi Tom
b) Ex 2: make a student record
Suppose we want to write a function that take the following information from a student
Name
ID
Level (BS, MS, or PhD)
Country (Italy, US, …)
The function will return those in a dictionary of 4 elements
Suppose that for some reason, most of the students are undergraduates (
level="BS"
) and from Italy (country="Italy"
)Thus, we can set default arguments for
level
andcountry
to reduce unnecessary manual work
# Define the function
def get_student_info(name, std_id, level="BS", country="Italy"):
return {
"name": name,
"id": std_id,
"level": level,
"country": country
}
# Call 1: Alessandro with ID 220001 from Italy studying BS
get_student_info("Alessandro", 220001)
{'name': 'Alessandro', 'id': 220001, 'level': 'BS', 'country': 'Italy'}
# Call 2: Giovanni with ID 220002 from Italy studying MS
get_student_info("Alessandro", 220002, "MS")
{'name': 'Alessandro', 'id': 220002, 'level': 'MS', 'country': 'Italy'}
# Call 3: John with ID 220003 from US studying BS
# This time, since country is specified after level,
# you have to pass "US" as a keyword argument using country="BS"
# If you pass ("Alessandro", 220001, "US")
# then Python will understand "US" is the value passed to level
get_student_info("Alessandro", 22003, country="US")
{'name': 'Alessandro', 'id': 22003, 'level': 'BS', 'country': 'US'}
# Call 4: Tue with ID 220004 from Vietnam studying MS
get_student_info("Tue", 22004, "MS", "Vietnam")
{'name': 'Tue', 'id': 22004, 'level': 'MS', 'country': 'Vietnam'}
# Call 5: if using keyword arguments
# you can swap the order of default arguments
get_student_info("Tue", 22004, country="Vietnam", level="MS")
{'name': 'Tue', 'id': 22004, 'level': 'MS', 'country': 'Vietnam'}
23.6. Summary#
Overview
Roughly speaking, a function takes some inputs, does something with them, and spits out an output
Benefits
We define the logic once and reuse it as many times as we want
Easier to maintain and improve because the logic is in a single place
All lower-level details are abstracted away, making code more succinct and readable
Define and call a function
A function must be defined before being used
We use
def
to define a function as followsdef function_name(params): # Function body here
Parameters (or params) are the inputs to the function
Parameters are optional (a function might have no parameter)
The function name follows the rules and conventions introduced in the earlier lessons
The function body contains statements that handle some logic
A function might explicitly return a value to where it is called using the keyword
return
Otherwise,
None
will be returned by defaultDefining a function means writing code that specify
its name
parameters that it possibly take
what it does to the parameters
what value it returns
Calling a function means evoking the function to do something
Defining vs. calling
We define a function only once, but we can call it as many times as we want
We use
def
when define a function, but not when we call itWe cannot call a function that has not been defined yet
When defining a function, the inputs in the parentheses are called parameters
When calling a function, the inputs are called arguments
A function can
take no param, one param, or many params
explicitly return a value using return or implicitly return
None
Params vs. arguments
Params are named variables appearing in the function’s signature when we define a function
Arguments are actual values that are passed to the function when we call it
When passing arguments and the number of arguments and the order they are passed must match that of parameters
Default arguments
We can set default values to some parameters to avoid passing unnecessary information
Syntax
def f(a1, a2, ...., b1=v1, b2=v2, ...): # Body
Params with default values must be specified to the rightmost of the param list
A good convention: there is no space around
=
in the function signatureYou can use keyword arguments to skip passing arguments for
b1
. Exf(a1, a2, ..., b2=v2)
When passing arguments using keyword arguments, you can swap the order of default arguments. Ex:
f(a1, a2, ..., b2=v2, b1=v1)