Professional Documents
Culture Documents
Topic 5
Functions and Modules
Fall 2021
Michael S. Brown
EECS Department
York University
• You can pass data to a function that can be used by the function's
statements
a = "hello"
b = "HELLO"
if strEqual(a, b): Example of calling the
print("Strings are equal.") function. Since the function
else:
print("Strings aren't equal.")
returns a Boolean, we can
use it in an if-statement.
https://trinket.io/python/5b69ae38f3
EECS1015 – York University -- Prof. Michael S. Brown 9
Function "call signature"
def function_name(name, age, weight, height):
"""docstring"""
statement
The parameter list is also known as the
statement
function's call signature. This tells Python how
return data1 many arguments need to be passed to the function.
Example
def computeBMI(weight, height):
BMI = (height*height) / weight
return BMI This call does not use the
correct call signature. There should be
bmi = computeBMI(72, 180) two parameters. This will cause
bmi = computeBMI(72) an TypeError.
bmi = computeBMI(72)
Program output TypeError: computeBMI() missing 1 required positional
argument: 'height'
EECS1015 – York University -- Prof. Michael S. Brown 10
Calling the function - TypeError
• If your function call does not match the function's call signature, you
will get a "TypeError."
• It might seem strange that this is a TypeError, but you can think that
your function is an object of type "function" whose type also includes
the call signature.
• If your call doesn't match the call signature, then your call is the
wrong Type.
a = "hello"
b = "HELLO"
The strings bound to a and b
if strEqual(a, b):
print("Strings are equal.") are passed into the function call strEqual(a,b).
else:
print("Strings aren't equal.")
The function can be called as many times as we
c= "HeLo" want. We can pass different data each time we make
if strEqual(a, c): a call. For this call, we pass the data bound to a and
print("Strings are equal.") c – strEqual(a,c).
else:
print("Strings aren't equal.") This shows how functions can be "reused" over and
over.
https://trinket.io/python/a4e210fa90
EECS1015 – York University -- Prof. Michael S. Brown 12
Parameter and arguments
Calling the function (arguments) Function definition (parameters)
num = int(input("Input number: ")) def processNum( x )
result = processNum(num)
print(result) # compute some number
print(processNum(5)) y = x**2 + 5*x – 2
The parameter is what is declared
return y in the function. The parameter
here is x.
• See next slides for an example when multiple functions are called
1: def func1(x):
2: y = x*x
3: return y
4: def func2(x):
5: y = func1(x)
6: y = y * 3
7: return y
8: def func3(x):
9: y = func2(x)
10: return y
11: x = func3(5)
12: print(x)
Call Stack
11: x = func3(5) 9: y = func2(x)
12: print(x) List of variables Data/Objects stored in memory
Python creates temporary memory for
func2() and places it on the "Call Stack". parameter: x 5
Executing code in func2() y
4: def func2(x):
5: y = func1(x)
func1 local memory
5: y = func1(x) List of variables Data/Objects stored in memory
Python creates temporary memory for
func1() and places it on the "Call Stack". parameter: x 5
Executing code in func1(x) y 21
1: def func1(x):
Function calls and the "Call Stack" (2/3)
List of variables Data/Objects stored in memory
func1(param: x) (function)
1: def func1(x): func2(param: x) (function)
2: y = x*x
12: print(x) x func3(param: x) (function)
3: return y
5
4: def func2(x): 75
11: x = func3(5)
5: y = func1(x)
6: y = y * 3 Inside func3 func3 local memory
7: return y 9: y is bound to return from function List of variables Data/Objects stored in memory
10: return 75 to calling function's memory
8: def func3(x): delete func3 local memory from the parameter: x 5
9: y = func2(x) "Call Stack" y 75
10: return y
9: y = func2(x) func2 local memory
Call Stack
11: x = func3(5) Inside func2
12: print(x) List of variables Data/Objects stored in memory
5: y is bound to return from function
6: compute y = y *3 5
parameter: x 25
7: return 75 to calling function's emory
y
delete func2 local memory from the 75
"Call Stack"
func1 local memory
Start reading 5: y = func1(x) List of variables Data/Objects stored in memory
here! Inside func1
2: Compute y=5*5 parameter: x 5
3: return 25 back to calling function's memory y 22
25
delete this memory from the "Call Stack"
Function calls and the "Call Stack" (3/3)
List of variables Data/Objects stored in memory
func1(param: x) (function)
1: def func1(x): func2(param: x) (function)
2: y = x*x x func3(param: x) (function)
3: return y
5
4: def func2(x): 75
5: y = func1(x)
6: y = y * 3
func3 local memory
Functions get their own Data/Objects stored in memory
7: return y List of variables
local memory each time
8: def func3(x): the function is called. Since parameter: x 5
9: y = func2(x) functions can call other y 75
10: return y functions, this local
memory is "stacked", that is func2 local memory
Call Stack
11: x = func3(5) why we use the term Stack.
12: print(x) List of variables Data/Objects stored in memory
5
Note that a return parameter: x
statement returns data 25
y
to the calling function's memory. 75
func1 local memory
When a function is complete,
List of variables Data/Objects stored in memory
it's local memory is
deleted from the call stack. parameter: x 5
y 23
25
Tracing the flow of the program
• Like conditional statements, functions also change the flow of the
program.
What is the flow of this program?
1: def func1(x):
See a trace of the line numbers.
2: y = x*x
3: return y
main program 11 main 12
4: def func2(x):
5: y = func1(x)
func3() 8, 9 func3() 10
6: y = y * 3 func2() 4,5 func2() 6, 7
7: return y
func1() 1, 2, 3
8: def func3(x):
9: y = func2(x)
10: return y
11: x = func3(5)
12: print(x)
local memory
RecursionError: maximum recursion depth exceeded
func2() for func2()
func2 call's func1
This is very much like an infinite loop! This is an infinite function call.
The difference is in the function case you will eventually run out of Call Stack memory.
……….
EECS1015 – York University -- Prof. Michael S. Brown 25
https://trinket.io/python/d49638a319
Stack overflow
• Where did the name come from? See previous slide.
• Stack overflow is now known as one of the most useful websites
about programming
• Be careful with stack overflow, sometimes the answers are not
correct
Global variables can be used by functions. However, in this example, since we have
In this case, the variable PI is being used in an assignment (or binding) operator in the function,
compute area. PI is treated as a local variable. Here we
see the output of the global variable PI
is not changed. That is because changing
the local variable PI in the function
EECS1015 – York University -- Prof. Michael S. Brown 30
has no effect on the global variable.
Global keyword to modify global data in a function
• It is possible for a function to access a global variable
• The keyword "global" can be added before a variable to specify it is
not local
def computeArea(radius):
global PI The keyword global allows
PI = 3.14159 this function to have access
area = radius**2 * PI to the global variable PI. PI
return (area) can now be modified and
the change will appear
PI = 3.15 outside the function.
r = 10
area = computeArea(r) This statement must be
print("Area is : %.2f" % (area)) made before the variable is
print("PI is %.4f" % (PI)) used.
Area is : 314.16
PI is 3.1416
EECS1015 – York University -- Prof. Michael S. Brown 31
Another example of using global keyword
def doSomething():
def doSomething():
global y
y = 15 This line of code will cause an In this example, since y is
y = 15
NameError. Why? Because not already a global variable,
doSomething() y is local to function this statement will create a
doSomething()
print(y) doSomething() only. global variable named y
print(y)
https://trinket.io/python/4b9bc57e2f
https://trinket.io/python/d4e8d482eb
print(y)
NameError: name 'y' is not defined
In this example, we have the statement "global y" in the
function. Because there isn't already a global variable
Variable y is defined inside the function doSomething(). named y, this will create a global variable. This
It is "local" to that function. It cannot be used outside code will not have an error.
the function. Where a variable can be accessed is
known as its "scope". This variable is locally scoped to
doSomething().
def func():
global a, b
a = 18
b = a
Check these results and see if you understand
what makes them different?
a = 10
b = 5
func()
print("a=%d b=%d" % (a,b))
a=18 b=18
EECS1015 – York University -- Prof. Michael S. Brown 34
Part 3: Passing data, default arguments,
and returning data
studentRecord(number=203333995, name="Sascha")
studentRecord(name, number)
Output:
Name: 'Sascha' Student Number: 203333995
test(x=1, y=2, 3)
test(x=1, y=2, 3)
^
SyntaxError: positional argument follows
keyword argument
call signature is two parameters, but only one must be given (name),
the other is optional (greeting) since it has a default value.
Using default arguments (for one argument only) Using default arguments (for multiple arguments)
def greetingFunc(name, greeting="Hello"): def greetingFunc(name="Student", greeting="Hello"):
print("{}: {}".format(greeting, name)) print("{}: {}".format(greeting, name))
greetingFunc("Mingnan") greetingFunc()
greetingFunc("Abdel", "Good evening") greetingFunc("EECS class")
greetingFunc(greeting="Good afternoon")
https://trinket.io/python/cfb46fe1b7
10 100 1000
y_sq = computeSquareAndCube(x)
(100, 1000) (100, 1000) The return is multiple values
stored, but stored in a single variable.
This is called a "tuple" and we
https://trinket.io/python/4f3cbaa291
will learn about it in our next lecture.
EECS1015 – York University -- Prof. Michael S. Brown
43
Part 4: Modules
and special variable __name__
Usage:
Note, when we use the from approach to import functions, we do not need to use use the
moduleName prefix before the function. See next slide.
https://trinket.io/python/baba392168
def main():
str="" Code here only runs if this program
while (str.upper() != "Q"):
is the main program.
d1 = randint(1, 6)
d2 = randint(1, 6)
print("You rolled {} {} ".format(d1, d2))
str = input(" Press enter to roll again, q to quit ") This is a very common way you
if __name__ == "__main__":
will see Python code written.
main()
Why would we do this?
https://trinket.io/python/68b1739a0c
print("Function 2: getNegativeNumber()")
def getNegativeNumber(prompt="Input a negative number: "): print("Keep inputting until an int < 0 is provided")
num = input(prompt) print("Try an example")
num = int(num) x = getNegativeNumber()
while (num >= 0): print("The number is " + str(x))
print(" Error: That isn't a negative number. ")
num = input(prompt) print("Function 3: getNumber()")
num = int(num) print("Keep inputting until a number is provided")
return num print("Try an example")
x = getNumber()
print("The number is " + str(x))
def getNumber(prompt="Input a number: "):
str = "" If this module is run as a
while (not str.isnumeric()): main program, we can have it
str = input(prompt)
return– York
EECS1015 int(str)
University -- Prof. Michael S. Brown
do a demo of the functions.
53
Part 5: Putting it all together
• Ask the user to press enter to roll a dice for the computer
• Get the computer's dice roll result
• Print the result out
• If dice rolls are the same, you tie. Otherwise, if user's dice is larger – the user wins,
otherwise the user loses.
• Ask if they want to play again. If so, repeat the game. If not, stop the program
• Ask if they want to play again. If so, repeat It is clear we will need a while loop to have the game
the game. If not, stop the program run over and over.
EECS1015 – York University -- Prof. Michael S. Brown 56
Example solution – first define functions
# First, let's import a function from the module random # function to see who won and print out the results
from random import randint def checkGameResults(playerDice, computerDice):
print("-----------------------------------------")
if (playerDice < computerDice):
# function to get a key press. print("***Computer's is larger -- YOU LOSE!***")
def pressEnter(prompt="Press Enter "): elif (playerDice > computerDice):
input(prompt) print("***Your role is larger - YOU WIN!***")
else:
# simple function to simulate a dice roll print("***Dice are the same - YOU TIE!***")
# it returns a value between 1-6
def rollDice(): print("-----------------------------------------")
result = randint(1, 6)
return result
#
# main entry point of program.
# Check if this is the main program
# if so, call the main function
if __name__ == "__main__":
main()
https://trinket.io/library/trinkets/94860c2307
EECS1015 – York University -- Prof. Michael S. Brown 59
Putting it all together
• One beautiful thing about programming is that you can have many
different designs that are all valid
• This example did not use a user-defined module . . that will come
later.
• Virtually all languages support functions and have the notion of local
and global variables