Beginner: Defining Functions
Table of Contents
What is a Function?
Functions are a handy way of parceling up your code, making it easier to reuse, share, and organize. You can think of a function as a block of “pre-prepared” code that you might want to run again and again.
You’ve already used a lot of functions without realizing it - for instance:
print()to display text"hello".split()to split stringsstr(),int(), andfloat()to convert between types
Anything that looks like a name followed by round brackets () is usually a function in Python.
To understand why functions are useful, suppose we were writing some code, and it ended up looking something like this:
In this program there are several places where we are doing the same operation: doubling a number, adding one, and then printing the result.
We can’t use a loop here, since the overall program is not simply repeating over and over, but it is clear that this calculation is repetitive. This is the kind of situation where functions are useful.
We can put the repeated logic into a function and give it a name. In Python, functions are created using the def keyword, followed by the function name, a pair of parentheses, and a colon. The code inside the function is indented:
Note: Much like
ifstatements and loops, indentation is very important for functions. Whilst in other languages such asMatlabthere are keywords signifying when a function ends (such asend); in Python the only way to tell which code is and is not inside a function is through indentation. In short, make sure your indentation is present and consistent! Also, don’t forget the colon after thedefexpression!
Now we can call our function whenever we need that same operation, without having to repeat the calculation each time:
This version of the program behaves exactly the same, but the repeated calculation is written only once, inside the function. If we ever needed to change the logic (for example, triple the number instead of double it), we would only have to update the function (instead of updating the three lines it was used on one by one).
Anatomy of a Function
Let’s break down the basic syntax of a function.
The first line always begins with the def keyword and ends with a colon :. These tell Python where the function starts.
`def` keyword colon
↓ ↓
def my_function(inputs):
print("Code inside function")
print("Code outside function")
After def, we choose a name for the function. In this case, it’s my_function. This is the name we will later use to “call” (i.e. run) the function.
name of function
↓
def my_function(inputs):
print("Code inside function")
print("Code outside function")
Next, inside the round brackets (), we specify the inputs to the function. These are the variables or values that the function will use when it runs.
inputs to the function
↓
def my_function(inputs):
print("Code inside function")
print("Code outside function")
The indented block of code that follows is called the body of the function. This code does not run until the function is called.
def my_function(inputs):
print("Code inside function") ← body of the function
print("Code outside function")
Finally, any code that is not indented is outside the function and will run as normal when the program is executed.
def my_function(inputs):
print("Code inside function")
print("Code outside function") ← this code will run as normal
Don’t worry if this seems a little confusing for now, we will see lots of examples in the next few sections.
Inputs and Outputs
You can think of a function a bit like a black box: you put some inputs into it, the function runs some code, and it gives you a result.
For example, the print_double_and_add_one function we saw earlier took in a number x, doubled it, added one, and printed the result.
Up until now, our functions have only printed things. But often we want a function to return a result that we can use later in our program. This is done with the return keyword.
Notice how this function doesn’t print the result directly. Instead, it returns it. We then stored the result in m and printed it afterwards.
Test your understanding: Try changing the value of
kabove. What do you think will happen when you do this?
Note: We can also write
return(y)instead ofreturn y. Both are valid and do exactly the same thing.
Once a return statement is reached, the function ends immediately. Any code written after it will not be executed. For instance:
A function doesn’t just have to have one input. Multiple inputs to a function can be specified like so:
Test your understanding: Write some code which calls this function on the values
x=3andy=2. Predict what output your code will give, and check your answer by running the code.
Multiple outputs can also be returned like so:
If we don’t want all the outputs, we can ignore one with the underscore _:
Functions can also be written with no inputs or outputs at all. For example:
Input arguments are named, meaning you can call the function on inputs by using their names, rather than by using the order they were defined in. For example:
You can also specify default values for inputs so that if an input is not entered, the function will assume it takes some predefined value. For example:
Variable Scope
When we create variables inside a function, those variables only exist inside the function. The region of the program where a variable can be used is called the scope of the variable.
For example:
The variable output_variable is created inside the function, so it only exists while the function is running. Once the function finishes, output_variable disappears.
Variables created inside a function are called local variables. They can’t be accessed outside of the function.
On the other hand, variables created outside of a function are called global variables, and they can be used inside functions (though usually it’s better practice to pass them in as inputs).
In general, it’s good practice to:
- Use function inputs and outputs rather than relying on global variables.
- Give your variables clear names so you don’t accidentally confuse a local variable with a global one.
Exercises
Question 1: Below is a simple function with two inputs.
What do you think will be printed when each of the following is run?
my_simple_function(3,4)my_simple_function(y=3,x=4)my_simple_function(y=4)my_simple_function()my_simple_function(x=3)
Explain your results and verify your answers by running the code.
Question 2: Write a function that takes a string my_string as input and returns the number of uppercase letters it contains. For example, if the input is "this Is mY string", the function should return 2.
Hint: Recall from week 3 that a string is an iterable object. This means that you can iterate over the characters in a string using for character in my_string:. You may also wish to use the upper function.
Question 3: In physics, energy can take different forms. In this question, you will write two functions to calculate kinetic and potential energy.
- The first,
calculate_kinetic_energy, should takemass(in kg) andvelocity(in m/s) as inputs and return the kinetic energy,E_k, computed using the formula \(E_{K} = \frac{1}{2}mv^2\). For example, if the mass is2kg and velocity is10m/s, the function should return100.0. - The second,
calculate_potential_energy, should takemass(in kg),height(in m), andgravity(in m/s²) as inputs and return the gravitational potential energy,E_p, computed using the formula \(E_{P} = mgh\). For example, if mass is1kg, height is50m, and gravity is9.8m/s², the function should return 490.0.
Question 4: Your task in this question is to write code which models the behaviour of a ball falling from rest.
To begin, you must create a list of time points from 0 to 5 seconds in increments of 0.1 seconds. For every time point, you must then compute the velocity of the ball, using \(v = gt\) (\(g = 9.8\) m/s²), and the height of the ball using \(h = h_0 - \frac12gt^2\) (where \(h_0 = 100\) m is the initial height from which it is dropped). You must record the values in three lists named times, velocities, and heights.
Next, you must use the functions you wrote in Question 3 to calculate the kinetic and potential energy at each time and store the results in lists called kinetic_energy and potential_energy.
Once you have created the lists named times, kinetic_energy and potential_energy, you can run the below code, which should create a plot of the two forms of energy against time. Try to describe what these plots are telling you. Are the energies increasing or decreasing over time? How do you explain their behaviour?
Note: Don’t worry if you are unsure what the
importandfromkeywords are doing in the above code. For now, you can think of these as a way of loading in pre-written functions such as theplot_energy_over_timefunction. You’ll have plenty of opportunities to practice and understand these features of Python as the course goes on.
Question 5: The below code will load a function called time which you can run as time(). See if you can work out what this function does (you may have to look online).
Question 6: Often in speech-to-text processing, spoken audio is transcribed as text. This can produce long strings of English sentences that have been automatically generated from speech. One common problem is that people often use filler words such as "um", "uh", "uhm", "er", and "err".
Write a function remove_filler which takes in a string containing transcribed speech and returns a new string with the same speech but with the filler words listed above removed. For instance, given the text
"Um I was, uh, going to the store but uhm I er forgot."
your function should return
"I was, going to the store but I forgot."
Hint: You may want to consider the split function for strings for this problem.
Question 7: Consider the following badly written code that uses both a global and a local variable with the same name, x. When you run the code, you’ll notice that the two print statements output different values. By performing your own research online if necessary, see if you can explain why the value printed inside the function differs from the value printed outside the function.
Question 8: The \(n\)th Fibonnaci number, \(F(n)\), is defined by the following recurrence relation;
\(F(0)=0, F(1)=1\) and \(F(n)=F(n-1)+F(n-2)\) for \(n>1\)
Write a function Fibonnaci which takes in a list of integers [x1,x2,...,xk] of arbitrary length and returns their corresponding fibonnaci numbers, i.e. [F(x1),F(x2),...,F(xk)].
Question 9: The “Look and Say” sequence is a sequence of integers defined in the following way.
- The first member of the “Look and Say” sequence is 1, i.e. \(l(1) = 1\).
- To generate a member of the sequence from the previous member, read the digits of the previous member, counting the number of digits in groups of the same digit. For example:
- 1 is read off as “one 1” or 11 (\(l(2) = 11\)).
- 11 is read off as “two 1s” or 21 (\(l(3) = 21\)).
- 21 is read off as “one 2, then one 1” or 1211 (\(l(4) = 1211\)).
- 1211 is read off as “one 1, one 2, then two 1s” or 111221 (\(l(5) = 111221\)).
- 111221 is read off as “three 1s, two 2s, then one 1” or 312211 (\(l(6) = 312211\)).
Write a function which, given the kth integer from the look and say sequence, \(l(k)\), computes the (k+1)th integer in the sequence, \(l(k+1)\). Hint: The str function may be helpful for this task!
Question 10: Using your function from Question 9, now write a function las_k which given an integer, \(k\), returns the kth look and say number, \(l(k)\). Give 3 reasons why you think it may be useful to lay out your code in functions in this way.