We have already used (called) functions multiple times, like print()
, int()
, len()
or randint()
.
import random
name = "James Bond"
number = int("007")
print(name)
print(len(name))
print(number)
print(random.randint(1, 100))
The concept of a function in programming is very close to the mathematical definition of a function. These functions can:
By defining custom functions, the redundancy in the code can be reduced. A custom function can be defined with the def
keyword:
def function_name ( <parameter_list> ):
function_statement
By defining a function we are just "storing" it, be we are not executing it yet. For example:
def hello():
print("Hello World!")
Now we may call the function even multiple types to execute it:
print("First line")
hello()
print("Second line")
hello()
What will be the type of a function?
print(type(hello))
Functions may have zero, one or multiple parameters, which are given between parentheses as variables to the function:
def greet(name):
print("Hello " + name + "!")
greet("John")
someName = "Jane"
greet(someName)
In the above example the variable name
is a parameter. The literal value John
and the variable someName
are the arguments of the function call. So parameters are the generalized variables in the function definitions, while arguments are the actual, concrete values in a function call.
Functions can return a value with the return
statement. When a function reaches a return statement, the execution of the function is stopped and the given value is returned. (A function can contain multiple return statements when using conditions or iterations.)
Let's write the sum_list
function, which receives a list of numerical values as a parameter and returns the sum of the numbers!
def sum_list(numbers): # numbers is assumed to be a list of numerical values
sum_value = 0
for num in numbers:
sum_value += num
return sum_value
print("This line will never get printed")
Until now, we have only defined the function, now we can call it:
nums = [12, 8, 37, 21, 67, 42, 25]
print(sum_list(nums))
A function can contain multiple return
statements. After the first return
statement reached, the execution of the function is stopped.
Let's write the average
function, which receives a list of numerical values as a parameter and returns the average of the numbers. If the list is empty, the returned value shall be None
. Reuse the previous sum_list
function to produce the sum of the values.
def average(numbers): # numbers is assumed to be a list of numerical values
if len(numbers) == 0:
return None
else:
return sum_list(numbers) / len(numbers)
print("This line will never get printed")
nums = [12, 8, 37, 21, 67, 42, 25]
print(average(nums))
Remark: the None
keyword is used to define a no value at all (also called null value).
None
is not the same as 0
, False
, or an empty string. None
has a data type of its own (NoneType
) and only None
can be None
.
Functions returning a value are called fruitful functions. Functions without a return value are called void functions. In that case the returned value is None.
greet("Matthew")
result = greet("Andrew")
print(result)
Functions may have multiple parameters. In such a case the arguments are matched to the parameters in the same order as they are listed.
def add(a, b):
print("Adding {0} and {1}".format(a,b))
c = a + b
return c
result = add(10, 32)
print(result)
result = add(-5, 8)
print(result)
Python allows function parameters to have default values. If the function is called without the argument, the parameter gets its default value.
def power(base, exp = 10):
return base ** exp
print(power(2, 6))
print(power(2, 10))
print(power(2))
IMPORTANT: if a parameter has a default value, all other parameters following it must have a default value too! E.g. this is invalid:
def power(base = 2, exp):
return base ** exp
In Python, we can either pass the arguments by their position - as we have seen it so far:
print(power(2, 6))
print(power(6, 2))
Alternatively arguments can be passed by the respective parameter name:
print(power(base = 2, exp = 6))
print(power(exp = 6, base = 2))
print(power(2, exp = 6))
Note: passing arguments by their name is especially useful when:
There are many built-in functions in Python for common use cases, e.g. for looking up the maximum/minimum value in a list, or to calculate the sum of a list:
print("Maximum value in nums: {0}".format(max(nums)))
print("Minimum value in nums: {0}".format(min(nums)))
print("Sum of the values in nums: {0}".format(sum(nums)))
A comprehensive list can be found in the documentation:
https://docs.python.org/3/library/functions.html
Note: defining a variable or function with the same of an existing (even builtin) function will hide it.
print("Maximum value in nums: {0}".format(max(nums)))
max = 42
print("Maximum value in nums: {0}".format(max(nums))) # yields error ,as max in an integer now, not a function
In Python a logical unit of definitions (variables, functions, classes) shall be put in a standalone file to support the easy reuse of the code. Such a file is called a module; definitions from a module can be imported into other modules or into the main module.
There are many built-in modules, we have already used the math
and the random
module for example.
By using modules we can access preinstalled libraries and use them, so our code will be shorter and more compact.
import math
print(math.pi) # using a variable definition from module math
print(math.factorial(10)) # using a function definition from module math
You can easily get a documentation for a module, by either looking it up in the reference:
https://docs.python.org/3/library/math.html
Or fetching it dynamically with the help
function:
help(math)
Write a function fahr2cels
, which computes the temperature in Celcius from Fahrenheit. The formula is the following:
$$ C = \frac{5}{9} * (F - 32)$$
Where $C$ is the degree in Celsius and $F$ is the degree in Fahrenheit.
Write a program which prints out the appropriate Celsius values for each degree in Fahrenheit between 0 and 100, using an incremental step of 10.
def fahr2cels(f):
c = 5 / 9 * (f - 32)
return c
for fahr in range(0, 101, 10):
cels = fahr2cels(fahr)
print("Fahr = {0}, Cels = {1:.4f}".format(fahr, cels))
Write a function isPrime
which determines whether a number received as a parameter is a prime or not.
(You may reuse your algorithm from the previous lecture.)
Wrtite a program which request a number from the user and tests whether it is a prime or not. Check whether the user input is really an integer number or not.
import math
def isPrime(number):
# Handle 0 and 1 as a special case
if number < 2:
return False
# Numbers >= 2 are tested whether they have any divisors
for i in range(2, int(math.sqrt(number) + 1)):
#print("Testing divisor %d" % i)
if number % i == 0:
# If we found a divisor, we can stop checking, because the number is NOT a prime
return False
# If no divisors were found, then the number is a prime
return True
try:
num = int(input("Number to check: "))
if isPrime(num):
print("{0} is a prime".format(num))
else:
print("{0} is NOT a prime".format(num))
except:
print("That was not a number!")
Request a string input from the user (a sentence). Write a function wordCount
which count the words in the sentence!
def wordCount(sentence):
spaceCount = 0
for char in sentence:
if char == ' ':
spaceCount += 1
return spaceCount + 1
userInput = input('Say a sentence: ')
print('Your sentence consisted of {0} words.'.format(wordCount(userInput)))
Hint: count the spaces in the input string.
A) Given a list a numbers, write a function isMonotonous
which decides whether the sequence is monotically increasing or not?
Sample input:
list1 = [10, 20, 50, 400, 600]
list2 = [10, 20, 50, 40, 600]
list3 = [1000, 500, 200, 50, 10]
list4 = [10, 20, 50, 50, 300]
def isMonotonous(numbers):
# Assume that the list is monotically increasing and search for an index pair where it is not true!
for i in range(1, len(numbers)):
if numbers[i - 1] > numbers[i]:
return False
# If no such errornous index pair was found, then the list was really monotically increasing.
return True
print("List 1: {0}".format(isMonotonous(list1)))
print("List 2: {0}".format(isMonotonous(list2)))
print("List 3: {0}".format(isMonotonous(list3)))
print("List 4: {0}".format(isMonotonous(list4)))
B) Modify the previous function, so it decides whether the sequence is monotonous or not. (It can be either increasing or decreasing.)
def isMonotonous(numbers):
# Check for monotically increasing
isIncreasing = True
for i in range(1, len(numbers)):
if numbers[i - 1] > numbers[i]:
isIncreasing = False
break
# Check for monotically decreasing
isDecreasing = True
for i in range(1, len(numbers)):
if numbers[i - 1] < numbers[i]:
isDecreasing = False
break
# Return whether either one of the 2 conditions were true!
return isIncreasing or isDecreasing
print("List 1: {0}".format(isMonotonous(list1)))
print("List 2: {0}".format(isMonotonous(list2)))
print("List 3: {0}".format(isMonotonous(list3)))
print("List 4: {0}".format(isMonotonous(list4)))