Dr Jon Shiach, Department of Computing and Mathematics, Manchester Metropolitan University
On successful completion of this page readers will be able to:
A function is a block of code that is used to perform a single action. These are very useful in programming as they allow us to think of a program as a collection of single individual tasks which helps when writing longer programs. Functions also allow us to repeat tasks easily without having to write out the individual commands again.
You have already been introduced to functions that are in the math library. For example, execute the code cell below
import math
math.exp(1)
2.718281828459045
Here we have used the exp
function from the math
library to calculate the value of the constant $e$. Using a function like this is known as calling a function
Functions in Python are defined using the def
keyword
def function_name(inputs):
commands
return outputs
Where
function_name
is the name which is used to call the function. A function name must begin with a character or underscore and not a number. Also care must be taken not to use the same name as a previously defined function (e.g., if you define a new function called abs
then you won't be able to use Python's built-in abs
function).inputs
are variables which are used as inputs to the function. outputs
are variables which are outputted by the function.Note that the commands within the function are indented. The commands following a function that are not indented are not part of the function so functions are ended with the next non-indented command (similar to loops and if statements).
The Python code below defines a function that doubles the number that is parsed into it. Enter this into the code cell below and execute it (this will not produce any output but needs to be done in order for us to be able to call the function later).
def double(x):
y = 2 * x
return y
def double(x):
y = 2 * x
return y
To use (or call) our function we use the function name and parse a number into it. You will need to execute the code block above which defines the function double
before it can be used. Enter the following command into the code cell below and execute it.
double(3)
double(3)
6
Any variables defined within a function are known as local variables because they can only be accessed from commands within the function. It can be useful to think of a function as a black box in that any variables which are defined within a function cannot be used outside of the function unless they have been outputted using the return
command.
Variables that have been defined prior to the a function being called are known as global variables and can be access within a function, i.e., all variables defined outside of a function are global variables by default.
The program below defines a function that demonstrates the difference between local and global variables. Enter it into the code cell below and execute it.
def example_function():
b = 2
print("The value of the global variable a is {}.".format(a))
print("The value of the local variable b is {}.".format(b))
a = 10
example_function()
# try to print the variable b (uncomment the line below to see what happens)
# print(b)
def example_function():
b = 2
print("The value of the global variable a is {}.".format(a))
print("The value of the local variable b is {}.".format(b))
a = 10
example_function()
# try to print the variable b (uncomment the line below to see what happens)
# print(b)
The value of the global variable a is 10. The value of the local variable b is 2.
Here we defined a global variable a
and a function example_function
in which we also define a local variable b
. The two print
commands within the function are used to show that both the local and global variables can be accessed in the function even though the global variable is not an input argument of the function. If we tried to access the value of b
outside of the function Python would return an error (uncomment the last line to try it).
f
which calculates the value of the function $f(x) = 2x^2 - 3x + 4$ for an input $x$. def f(x):
return 2 * x ** 2 - 3 * x + 3
Test your function on the following:
(a) $f(1) = 2$
f(1)
2
(b) $f(-3) = 30$
f(-3)
30
(c) $f(1.23) = 2.3358$
f(1.23)
2.3358
my_abs
which calculates the absolute value of an inputted number. Test your function on $|-2| = 2$.
def my_abs(n):
if n >= 0:
return n
else:
return -n
my_abs(-2)
2
odd_or_even
which takes in an input of a integer number and returns the character string "even"
or "odd"
depending on the value of the number.def odd_or_even(n):
if n % 2 == 0:
return "even"
else:
return "odd"
odd_or_even(3)
'odd'
isprime
that takes in an input of an integer number $n$ and returns True
or False
depending whether it is an integer or not using a for loop to check whether the numbers between 2 and $n-1$ are factors of $n$.def isprime(n):
for i in range(2, n):
if n % i == 0:
return False
return True
Test your function with the numbers:
(a) 3217 (prime)
isprime(3217)
True
(b) 4233 (not prime)
isprime(4233)
False
norm
that calculates the magnitude of a vector that is inputted into it. Your function should be able to deal with vectors of any length.
import numpy as np
def norm(a):
anorm = 0
for x in a:
anorm += x ** 2
return np.sqrt(anorm)
Test your function on $|(1,2,3)| \approx 3.7417$.
norm(np.array([1, 2, 3]))
3.7416573867739413
Functions can have multiple inputs.
def function_name(input1, input2, ... ):
commands
return output
The program below defines a function which raises the number x
to the power n
and then uses it to calculate $2^5$. Enter it into the code cell below and execute it. Try changing the values in the power(2, 5)
command to calculate different powers.
def power(x, n):
y = 1
for i in range(1, n+1):
y = x * y
return y
# Use the function power to calculate 2^5
power(2, 5)
def power(x, n):
y = 1
for i in range(1, n+1):
y = x * y
return y
# Use the function power to calculate 2^5
power(2, 5)
32
g
which calculates the value of the bivariate function $g(x, y) = x^2 + y^3$ for inputs of $x$ and $y$. def g(x, y):
return x ** 2 + y ** 3
Test your function on:
(a) $g(1, 2) = 9$
g(1, 2)
9
(b) $g(3, -1) = 8$
g(3, -1)
8
(c) $g(4, 6) = 232$
g(4, 6)
232
pythagoras
which takes in two inputs of the lengths of the two shortest sides of a right-angled triangle a
and b
and returns the length of the hypotenuse c
calculated using Pythagoras' theorem.import numpy as np
def pythagoras(a, b):
return np.sqrt(a ** 2 + b ** 2)
Test your function to find the hypotenuse when the two shortest sides are:
(a) 5 and 12 giving a hypotenuse of 13
pythagoras(5, 12)
13.0
(b) 2 and 3 giving a hypotenuse of 3.6056
pythagoras(2, 3)
3.605551275463989
dot_product
that calculates the dot product of two inputted vectorsimport numpy as np
def dot_product(a, b):
adotb = 0
for i in range(len(a)):
adotb += a[i] * b[i]
return adotb
Test your function on $(1,2,3,4) \cdot (5, 6, 7, 8)=70$
dot_product(np.array([1, 2, 3, 4]), np.array([5, 6, 7, 8]))
70
cross_product
that calculates the cross product of two vectors in $\mathbb{R}^3$.
import numpy
def cross_product(a, b):
axb = np.zeros(3)
axb[0] = a[1] * b[2] - a[2] * b[1]
axb[1] = a[2] * b[0] - a[0] * b[2]
axb[2] = a[0] * b[1] - a[1] * b[0]
return axb
Test your function on $(1, 2, 3) \times (-1, 0, 2) = (4, -5, 2)$
print(cross_product(np.array([1, 2, 3]), np.array([-1, 0, 2])))
[ 4. -5. 2.]
Euclid's algorithm for finding the greatest common divisor (gcd) of two numbers is:
For example, consider the gcd of 9 and 15
so $\operatorname{gcd}(9, 15) = 3$. Define a function called gcd
that uses Euclid's algorithm to calculate the gcd of two numbers.
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
Test your function on
(a) $\operatorname{gcd}(3, 6)=6$
gcd(15, 9)
3
(b) $\operatorname{gcd}(24, 54)=6$
gcd(24, 54)
6
Functions can also output multiple values.
def function_name(input1, input2, ... ):
commands
return output1, output2, ...
The outputs of a function can be accessed by listing the values or as a single tuple, e.g.,
output1, output2, ... = function_name(input1, input2, ...)
or
outputs = function_name(input1, input2, ...)
The program below defines a function that calculates the roots of the quadratic polynomial $0=ax^2 + bx + c$. Enter it into the code cell below and execute it to see the result. Try using the function to calculate roots of different quadratics including ones with one or no real roots.
import numpy as np
def quadratic(a, b, c):
discriminant = b ** 2 - 4 * a * c
if discriminant < 0:
print("No real roots.")
return
elif discriminant == 0:
root = -b / (2 * a)
return root
else:
root1 = (-b - np.sqrt(discriminant)) / (2 * a)
root2 = (-b + np.sqrt(discriminant)) / (2 * a)
return root1, root2
# Use the function quadratic() to compute the roots of 0 = x^2 - 4a + 3
quadratic(1, -4, 3)
import numpy as np
def quadratic(a, b, c):
discriminant = b ** 2 - 4 * a * c
if discriminant < 0:
print("No real roots.")
return
elif discriminant == 0:
root = -b / (2 * a)
return root
else:
root1 = (-b - np.sqrt(discriminant)) / (2 * a)
root2 = (-b + np.sqrt(discriminant)) / (2 * a)
return root1, root2
# Use the function quadratic() to compute the roots of 0 = x^2 - 4a + 3
quadratic(1, -4, 3)
(1.0, 3.0)
cylinder
that calculates the volume and surface area of a cylinder given inputs of the radius and height. import numpy as np
def cylinder(r, h):
volume = np.pi * r ** 2 * h
surface_area = 4 * np.pi * r + np.pi * r ** 2 * h
return volume, surface_area
Test your function on a cylinder with radius 1 and height 2 which gives a volume of 6.28 units cubed and surface area 18.85 units squared.
cylinder(1, 2)
(6.283185307179586, 18.84955592153876)
my_exp
that uses a while loop to compute the value of $\exp(x)$ by adding the $n$th term at each iteration. Your while loop should stop when the value of the $n$th term is less than $10^{-6}$. Your function should return the value of $\exp(x)$ and the number of terms used to achieve the required accuracy.
def my_exp(x):
expx, term, n = 1, 1, 0
while term > 1e-6:
n += 1
term *= x / n
expx += term
return expx, n + 1
Test your function on $\exp(1) = 2.718281$ which requires 11 terms.
my_exp(1)
(2.7182818011463845, 11)
my_sqrt
which uses a while
loop to calculate this scheme whilst $|x_{n+1} - x_n| > 5\times 10^{-5}$ where $x_0=1$ and $x_1=2$. Your function should output the approximation of $\sqrt{s}$ and the number of iterations used.def my_sqrt(s):
x0, x1, iterations = 1, 2, 0
while abs(x1 - x0) > 5e-5:
x0, x1 = x1, 1 / 2 * (x1 + s / x1)
iterations += 1
return x1, iterations
Test your function on $\sqrt{2}=1.4142\ldots$.
my_sqrt(2)
(1.4142135623746899, 4)