Functions¶
In this notebook, we will discuss built-in and user-defined functions in Python, as shown under the following topics:
Built-in functions
Defining your own funcions
Multiple parameters
return vs. print
Variable Scope
Built-in Functions: input()
, print()
, int()
, float()
, str()
¶
Python comes with several built-in capabilities. In this section, we will explore some useful built-in functions.
print()
¶
The print()
function is used to display characters on the screen. When we print something, notice that there is no output (no Out[] cell). This is because it does not return a value as an output (like a Python expression). It simply performs an action.
input()
¶
The input()
function is used to take input from the user. We specify the prompt we want the user to see within the parentheses. By default, input values are always of type string.
int()
¶
The int()
function is used to convert strings of digits to integers.
str()
¶
The str()
function is used to convert other data types to a string type and return it.
float()
¶
The float()
function is used to convert strings of digits that is a valid representation of a floating point number into floating point numbers.
age = input("Enter your age: ")
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/690836526.py in <module>
----> 1 age = input("Enter your age: ")
/usr/local/lib/python3.9/site-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
1001 """
1002 if not self._allow_stdin:
-> 1003 raise StdinNotImplementedError(
1004 "raw_input was called, but this frontend does not support input requests."
1005 )
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
age # notice that it is a string
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/366431356.py in <module>
----> 1 age # notice that it is a string
NameError: name 'age' is not defined
age = int(age) # convert to int
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/3350126167.py in <module>
----> 1 age = int(age) # convert to int
NameError: name 'age' is not defined
age
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/2113650149.py in <module>
----> 1 age
NameError: name 'age' is not defined
radius = input("Enter radius value: ") # radius of circle
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/3719892012.py in <module>
----> 1 radius = input("Enter radius value: ") # radius of circle
/usr/local/lib/python3.9/site-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
1001 """
1002 if not self._allow_stdin:
-> 1003 raise StdinNotImplementedError(
1004 "raw_input was called, but this frontend does not support input requests."
1005 )
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
radius # currently a string
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/540134667.py in <module>
----> 1 radius # currently a string
NameError: name 'radius' is not defined
radius = float(input("Enter radius value: ")) # radius of circle can be a float
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/3717502585.py in <module>
----> 1 radius = float(input("Enter radius value: ")) # radius of circle can be a float
/usr/local/lib/python3.9/site-packages/ipykernel/kernelbase.py in raw_input(self, prompt)
1001 """
1002 if not self._allow_stdin:
-> 1003 raise StdinNotImplementedError(
1004 "raw_input was called, but this frontend does not support input requests."
1005 )
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
radius # now it is float
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/2386209522.py in <module>
----> 1 radius # now it is float
NameError: name 'radius' is not defined
pi = 3.14159
print("Area of circle with radius", radius, "is", pi * (radius**2)) # comma adds space
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/3651269028.py in <module>
----> 1 print("Area of circle with radius", radius, "is", pi * (radius**2)) # comma adds space
NameError: name 'radius' is not defined
str(199) # converts value to str type
'199'
str(None) # converts None to str type
'None'
dollars = 10
print('The burrito costs $' + str(dollars) + '.') # can also concatenate with +
The burrito costs $10.
Question. Which of the functions among print()
, input()
, int*(
return an explicit value as output?
What does the print()
function return? print()
doesn’t explicitly return anything and just displays the printed text on the screen.
It turns out that calling print()
actually returns the special None
value. Python uses a None return value to indicate the function was called to perform an action when there is no explicit return value.
To emphasize that calls to print()
return None
, try out the following piece of code:
str(print("Hello!"))
Hello!
'None'
Defining your own functions¶
Functions are a great way of abstracting and reusing useful blocks of code. We have already used built-in functions like print()
, input()
and int()
. We can define our own functions as shown in the examples below.
def square(num):
'''A simple user-defined function.'''
return num * num
Calling or invoking the function: We can call a function many times, but we only define it once.
square(5)
25
square(7)
49
Parameters
A parameter names “holes” in the body of our function that will be filled in with the argument value for each invocation.
The particular name we use for a parameter is irrelevant, as long as we use the name consistently in the body.
def square(someNumber):
return someNumber * someNumber
The following function call will generate the same result as the one from the definition of the function with a different parameter name.
square(5)
25
Function parameters only have meaning within the body of the function. We will come back to this concept, when we discuss variable scope.
someNumber # what does this return?
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/3495249345.py in <module>
----> 1 someNumber # what does this return?
NameError: name 'someNumber' is not defined
Multiple parameters¶
A function can take as many parameters as needed. They are listed one by one, separated by commas.
Important (Order matters!) The order of parameters specifies the order of argument values.
def totalSecs(mins, secs):
'''Given the parameters mins and secs, return total number of seconds'''
return (mins * 60) + secs
If we call the function and provide the arguments in the wrong order (seconds first and then minutes), it will not work. The order of arguments in the function call should be the same as order of the corresponding paramenters in the function definition.
Call the function:
totalSecs(3, 67) # 3 minutes, 67 seconds
247
Why use docstrings? To help the user of the function understand the intended use.
help(totalSecs) # help is another in-built function!
Help on function totalSecs in module __main__:
totalSecs(mins, secs)
Given the parameters mins and secs, return total number of seconds
Function calling Functions¶
Once you have defined a function, you can call it from within other functions.
def song(action):
return "If you are happy and you know it, " + action
def singsong():
print(song("clap your hands"))
print(song("stomp your feet"))
print(song("snap your fingers!"))
singsong() # what will happen?
If you are happy and you know it, clap your hands
If you are happy and you know it, stomp your feet
If you are happy and you know it, snap your fingers!
In the above example, singsong()
is a zero-parameter function which is calling
the function print()
, which is calling the function song()
.
Note The function song()
returns a string. The returned string replaces the function call within the print()
, which results in it being printed.
Excercise: Write function average()
¶
Let us define a function named average()
that takes two numbers and returns the average of the two.
# Here define the function average
def average(x,y):
return (x + y) / 2
Now try calling your function below:
average(6, 16)
11.0
average(5, 7)
6.0
return
vs. print()
¶
return
specifies the result of the function invocationprint()
causes characters to be displayed in the shell.They are very different!
def exp(num, k):
"""Return the kth power of given number num"""
return num**k
def printExp(num, k):
"""Print the kth power of given number num"""
print("{} raised to exponent {} is {}".format(num, k, num**k))
Try out the result of the following expressions:
exp(3, 2) + exp(2, 3)
17
printExp(3, 2)
3 raised to exponent 2 is 9
Question. Will this work? What does printExp()
return?
printExp(3, 1) + printExp(4, 2)
3 raised to exponent 1 is 3
4 raised to exponent 2 is 16
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/2939101779.py in <module>
----> 1 printExp(3, 1) + printExp(4, 2)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
type(printExp(3, 2))
3 raised to exponent 2 is 9
NoneType
print(printExp(3, 2))
3 raised to exponent 2 is 9
None
Make Change Example¶
Problem. Suppose you are a cashier and you need to make change for a given number of cents using only quarters, dimes, nickels, and pennies.
Most cashiers use the following greedy strategy to make change using the fewest number of coins: use as many quarters as possible first, then as many dimes as possible next, and so on, using the fewest number of pennies last. Assume you have an unlimited supply of each coin.
# simple function to make change
def numCoins(cents):
"""Takes as input cents and returns the fewest number of coins of type
quarter, dimes, nickels and pennies that can make change for cents"""
pass
# we will write this together in class in Atom
help(numCoins)
Help on function numCoins in module __main__:
numCoins(cents)
Takes as input cents and returns the fewest number of coins of type
quarter, dimes, nickels and pennies that can make change for cents
Variable Scope¶
Local variables. An assignment to a variable within a function definition creates/changes a local variable. Local variables exist only within a function’s body, and cannot be referred outside of it. Parameters are also local variables that are assigned a value when the function is invoked.
def square(num):
return num * num
square(5)
25
num # num is not valid outside of square
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/md/kwd9nc_d2ns0hw9wsvdrnt2c0000gn/T/ipykernel_42072/1831334593.py in <module>
----> 1 num # num is not valid outside of square
NameError: name 'num' is not defined
def myfunc (val):
val = val + 1
print('local val = ', val)
return val
val = 3
newVal = myfunc(val)
local val = 4
print('global val =', val)
global val = 3
newVal
4