Little Building Blocks¶
We have figured out how to enable the user to input one parameter of our simulation and also how to make sure that the input value is a positive number. If we now want to do this for the other parameters as well, we might think of copying the code and adapting it a bit. This is however not a good idea.
Dangers of Copy & Paste-Code
Code that is repeated bears the risk of making your program harder to read and maintain. Some common issues that come along with duplicating code are:
- Forgetting to adapt a part of the copied code
- Finding all copied segments can be tricky, especially when they need to be updated to changed requirements
- If the copied code has a subtle bug, the same bug will be replicated multiple times in your code and you need to make sure find all occurences
To circumvent the issues that arise from copying code and to create smaller, self-contained segments, that can be re-used, a
function is the way to go.
You already encountered functions like
Now it is time to write our own.
We will start by providing a function definition. This will explain to our computer what this function is about, what its function name is and which parameters have to be provided, so it has all required information to do its work. The function definition must be processed by Python can use the function, so very often functions either are defined at the beginning of a file or even in a separate module that gets imported at the beginning.
Let’s begin by writing a function that can request the
starting population from the user.
We can put this at the beginning of the
def input_positive_integer(): # See note (1)(2)(3)(4)
input_is_valid = None
while not input_is_valid:
user_input = input("Please input the size of the starting population: ")
input_as_int = int(user_input)
input_is_valid = input_as_int > 0
if not input_is_valid:
print("Sorry,", input_as_int, "is not a valid input, please try again")
return input_as_int # See note (5)
Let’s take a closer look at the notes:
def-keyword tells Python that the following is a function definition.
- The function name is given as
- The parameters are listed in parenthesis
). Even if there are no parameters given in this case, the parenthesis must be there.
def+ function name + parameters form the so-called function head, which is concluded by a colon
- After the function has finished, all variables used inside are lost. To get a result out of the function, the
return-keyword allows to hand back a value that can be assigned to a variable again. Using the
return-keyword stops the function right then and there and hands back the value of whatever you return.
What does this do?¶
Within pairs of three quotes (
""" … """) we can add a documentation comment (also known as docstring) to give the reader of the code an idea what this function is about.
Code is more often read than written and thus should be easy to grasp and well-documented. The docstring may be omitted in very trivial and obvious cases. If in any doubt: Add a documentation.
This current function always asks for the starting population, which is a bit unlucky. We would like to be able to customize the function a bit so it can ask for different things. For this purpose we cann add a parameter to the function.
def input_positive_integer(ask_for_what): # see note (1)(2)
"""Query the user to input a positive number.
If the given number was negative or 0, the user is prompted to try again.
A text indicating what the user should input the value for.
It will be used for constructing the prompt that the user
sees when asked for the input.
A positive number as given by user input.
prompt = "Please input the " + ask_for_what + ": " # See note (3)
… # Loop as before
user_input = input(prompt) # See note (3)
… # Rest as before
- We added a parameter called
ask_for_whatwhich we can use later to specify the text that should be included when asking for input.
- Note that when we add a new parameter to the function it also has to be documented.
- To make the line for the input request a bit less convoluted we also introduced a variable
promptin which we store the full text of the request that the user gets to see.
Time to Shine!¶
With our function defined, we can use it. To do so we write down its name, followed by parenthesis. In the parenthesis we provide the values for the parameters.
Instead of providing a fixed value, we can now use the function to get the parameters right in the
from parameters import input_positive_integer # See note (1)
# Note that we do an assignment here to capture the values returned by the function in the respective variables
starting_population = input_positive_integer("starting population") # See note (2)
food_per_day = input_positive_integer("amount of food per day")
- When importing a function you need only its name, no parenthesis or parameters are required in this case.
- If not specified otherwise, Python will assign the values to the parameters in the order they are given.
The fine print
Using a function is referred to as calling a function. A function must be defined before it can be used. You very often find function definitions at the start of files or in separate files (we will talk about how to do this later).
- Functions can be used to split a program into smaller, independent chunks
- Functions have a function name and parameters in parenthesis
- Functions must be defined before they can be called
This is the code that we have so far: