Functions

After you saw how to use loops, what do you use when you want to repeat the same code several times? Sure, a loop! But what if you want to run the same code, but only once every now and then? Just copy the code every time you want to run that code? Why not use a function?

What are functions?

A function can be seen as a mini program inside your program. They are very useful to avoid coping and pasting the same blocks of code over and over again. The difference to a loop is that a function is usually used to group some functionality together and repeat the same algorithms at different places inside your program instead of repeating it several times after each other like a loop does.

You probably know the concept of a mathematical function such as: f(x) = x². This kind of functions can also be used in programming:

```def f(x):
return x**2
```

The above function is representing the function f(x) = x². The key word def is used to indicate that there will be a new function definition. After the key word def, the name of the function is defined, in this case simply ‘f’. Inside the parentheses is the parameter that can be given to the function. This is a way to give your mini program some input. A function can have several input parameters, they are then separated by a comma. Then the definition ends with a colon and the next lines that are indented. Everything inside the same level of indentation is part of that function definition. The last element of the function is the return key word. The variable(s) after the return key word are given as an output of your function.

You can call the function as follows:

```y = f(3)
```

Now, the return value will be stored inside the variable y. Like this, a simple formula such as a²+b²=c² could be easily implemented as:

```a_squared = f(a)
b_squared = f(b)
c_squared = a_squared + b_squared
```

In case you as: Why using a function for such a simple thing? Well, you probably will not use it for such a thing. Most likely, you will use it for more complex calculations. Also, you will hopefully not call the function ‘f’ and the input parameter not ‘x’. Let’s have a look at another function. The following will calculate the surface area of a rectangle with two input parameters:

```def rectangle_surface_area(height, length):
return height * length
```

The above function has a descriptive name, and the parameters are explicitly telling what they are supposed to be. This is often seen as good practice for writing functions.

A function can be more than a simple line of calculations. It can even contain print statements, loops and even other functions.

Small Example

The following function will ask the user to input his name and his age.

```def ask_personal_data():
return name, age
```

The function will then be used as such:

```user_name, user_age = ask_personal_data()

if user_name == "John":
print("Hello John! Did you know that this is a very common name?")
else:
print("Hello!")
```

As said, the above function will ask the user to type the name and the age and then the function returns both values. The user will see something like this:

```Please enter your name:
Jacob
25
```

With this function, you can now use it everywhere in your code to perform the same tasks again and again where they are needed. One advantage is that they make the program sorter and easier to read. Another advantage is, that you only need to modify the code one single time instead of modifying it on each occasion where you use the same algorithm.

Increased Maintainability

Let’s have a look at the following example of a driving robot:

```motor_speed = 0.2 # m/s

sensor_input = 540 #assume: 0 -> 0 meter and 1024 -> 2 meter
distance_to_wall = sensor_input * 2 / 1024
if distance_to_wall <= 0.2:
print("You need to stop now!")
motor_speed = 0

sensor_input = 370 #assume: 0 -> 0 meter and 1024 -> 2 meter
distance_to_wall = sensor_input * 2 / 1024
if distance_to_wall <= 0.2:
print("You need to stop now!")
motor_speed = 0

# calculate battery voltage

sensor_input = 210 #assume: 0 -> 0 meter and 1024 -> 2 meter
distance_to_wall = sensor_input * 2 / 1024
if distance_to_wall <= 0.2:
print("You need to stop now!")
motor_speed = 0
```

Now let’s see how this could be reduced with a function:

```def calculate_distance(sensor_input, motor_speed):
sensor_input = 540 #assume: 0 -> 0 meter and 1024 -> 2 meter
distance_to_wall = sensor_input * 2 / 1024
if distance_to_wall <= 0.2:
print("You need to stop now!")
motor_speed = 0
return motor_speed

motor_speed = 0.2 # m/s

motor_speed = calculate_distance(540, motor_speed)

# calculate battery voltage

motor_speed = calculate_distance(370, motor_speed)

motor_speed = calculate_distance(210, motor_speed)
```

Now you might ask: where is here an advantage in number of code lines? The first option only has 4 lines more than the second option. Yes, this is correct, the difference is not that big indeed.

However, imagine you decide not to use the distance in meters as you will always get small decimal values but instead, you want to use centimeters instead. In the first option, you need to modify the calculation of the distance three times. In the second option, you only need to do it once. Also, if you use the same calculations 20 times inside your program, you don’t always think of each time you used it and you might forget it at one spot and then there are mistakes in the code. Or imagine you have a different sensor with a range from 0 to 2048 bits instead of 1024. This means many changes all over the code or only one single change in the function.

Not convinced yet? The following function will not save you many lines, but the calculation inside is not very self-explanatory. The function name will tell you more about what you are calculating.

```# import the square-root function from the math module
from math import sqrt

def distance_between_points(x1, x2, y1, y2):
distance = sqrt((x2-x1)**2 + (y2-y1)**2)
return distance
```

Functions can also be used simply to structure your code into logical chunks or to give meaningful names to the algorithms that you program, even if you know you will use this algorithm only once in this program.

Modularity

Also, you might notices the line from math import sqrt. This line imports a function from another python file, so you can use it in your code as well. This means functions make the software more modular and reusable. There are many more functions that you already saw like the input() function, the print() function (yes, technically in Python 2, the print function is not a real function but a statement but in Python 3 it is a function) and here the sqrt() function.

So you have been using functions all along until now, without really noticing it. And this is why people use functions, to make their lives easier and keep the complexity hidden in other places. You can define the functions inside the same file as the main program or in a separate file and then import the functions from this file.

Importing functions from other Python files (so called Python modules) allow developers to make an Artificial Intelligence (AI) application with less than 50 lines of code. The total code behind this can then be several thousands of lines, but the part that the developer is writing is only a few lines long.

```motor_speed = calculate_distance(210, motor_speed)