Functions
In this section, you’ll learn to write functions, which are named blocks of code that are designed to do one specific task. If you need to perform that task multiple times throughout your program, you don’t need to type all the code for the same task again and again; you just call the function dedicated to handling that task. By defining functions, your programs will get easier to write, read, test, and fix.
Defining a function
Here’s a simple function named greet_user()
that prints a greeting:
This example shows the simplest structure of a function. With the keyword
def
we define a function, followed by the name of our function.
Within the parentheses we can (optionally) specify any information the function
needs to do its job. This information is defined in the form of parameters
(more on that later).
Any indented lines that follow def greet_user():
make up the body of
the function. The line print("Hello!")
is the only line of actual
code in the body of this function, so greet_user()
has just one job:
print("Hello!")
.
When you want to use a function, you have to call it. To do so, simply write the function name, followed by any required information in parentheses.
Detour: docstrings
As previously discussed, it is always good practice to add comments to your
code in order to improve readability. That applies to functions as well. In
case of functions, one can add a docstring, which is essentially a longer
comment that describes the function. A docstring is written in triple quotes
"""..."""
and is placed directly after the function definition.
Now, you can display the docstring by calling the built-in help()
function with the function name as an argument:
Docstrings facilitate the proper documentation of your code. Most of all, they will help you in the long run to remember what your code does.
Parameters
After some modification, the function greet_user()
should not only
tell the user "Hello!" but also greet them by name. Therefore, we have to
define a parameter called user_name
. Now, each time you call the function,
you need to pass a user_name
such as "admin"
to the function.
def greet_user(user_name):
"""
Display a simple greeting.
Pass a string with the user's name.
"""
print(f"Hello, {user_name}!")
greet_user("admin")
Info
As you can see in the example above, a docstring can span multiple lines!
Up until now, the functions had no parameters at all or just a single
parameter. However, you can define as many parameters as you like, seperated
by a comma (,
):
Break-even point
Remember the task to calculate the break-even point? Now, you'll wrap following formula within a function: $$ \text{BEP (units)} = \frac{\text{Fixed Costs}}{\text{Price per Unit} - \text{Variable Cost per Unit}} $$
Write a function called calculate_bep()
that takes the following
parameters:
fixed_costs
price_per_unit
variable_cost_per_unit
Print the calculation result (break-even point) within the function. Call the function with following arguments:
Terminology
parameter vs. argument
A parameter is the variable inside the parentheses of the function definition -
def greet_user(user_name):
. Here user_name
is the parameter. When
you call the function with, for example greet_user("admin")
, the
value "admin"
is referred to as an argument. You can think of the parameter
as a placeholder and the argument as the actual value.
Positional arguments
When you call a function, Python
must match each argument in the function
call with a parameter in the function definition. The simplest way to do this
is based on the order of the arguments provided which is referred to as
positional arguments.
Order matters!
You can get unexpected results, if you mix up the order of the arguments in a function call when using positional arguments:
def perform_calculation(a, b):
"""Calculate something."""
print(a + b**b)
a = 12
b = 5
# correct order
perform_calculation(a, b)
# incorrect order (produces a different result)
perform_calculation(b, a)
Next up, we'll introduce keyword arguments to avoid such mistakes.
Keyword arguments
A keyword argument is a name-value pair that you pass to a function. You directly associate the name and the value within the argument, so when you pass the argument to the function, there’s no confusion.
perform_calculation(a=12, b=5)
# you can switch the order of the named keyword arguments
perform_calculation(b=5, a=12)
No matter the order, the result is the same!
Default values
When writing a function, you can optionally define a default value for each parameter. If
an argument for a parameter is provided in the function call, Python
uses the
argument value. If not, the parameter’s default value is used. Using default values can
simplify your function calls and clarify the ways in which your functions are
typically used. Let's look at an example.
def describe_lab(lab_name, lab_supervisor="Miriam"):
print(f"{lab_name} is supervised by {lab_supervisor}")
# use the default value for lab_supervisor
describe_lab(lab_name="Chemistry")
# provide a value for lab_supervisor
describe_lab(lab_name="IT", lab_supervisor="Alex")
Return values
A function doesn’t have to display its output directly with print()
.
Instead, usually a function executes a task and returns the result. The result,
the return value can be of any type. To return a value, use the return
statement.
When you call the function, you can assign the result to a variable.
Password check
Write a function to check if a user is able to log-in.
You have to determine if the given username and password (in
plain text) are within the database. The database is a dict
with IDs as keys and another dict
as value, containing
username and hashed password.
Given 'database':
very_secure_db = {
0: {
"username": "SwiftShark22",
"password": "ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f",
},
1: {
"username": "FierceFalcon66",
"password": "07ac6e7d83aa285293fc325fecd04a51e933ab94d43dbc6434ddca652718fb95",
},
2: {
"username": "admin",
"password": "6feb4c700de1982f91ee7a1b40ca4ded05d155af3987597cb179f430dd60da0b",
},
3: {
"username": "BraveWolf11",
"password": "c430e4368aff7c1bc75c3865343730500d7c1a5f65758ade56026b08e94686cc",
},
}
Use following function to convert a password to its hash:
Now, write a function that takes at least two arguments, username
and
password
(in plain text!). Check if the given username and hashed
password are within the very_secure_db
. Return True
if the
user is able to log-in, otherwise False
.
Call your function for following users:
Info
As you have seen in the above example, functions help you to structure your
code. For instance, the function hash_password()
was reused multiple
times (to generate the very_secure_db
and within your own function).
Functions also help you to break down complex problems. You can write a function for each subtask and then combine them to solve the problem as a whole.
Recap
This section introduced the concept of functions to better structure your code, make it more readable and reusable. We have covered:
- How to define a function
- Docstrings as a tool to document your functions
- Parameters vs arguments
- Positional and keyword arguments
- Defining default values for parameters
- The
return
statement - How to use functions to solve smaller subtasks and structure your code