In this notebook there are the following topics/activities:
1. Defining your own funcions
2. Multiple parameters
3. Excercise 1: write your own function average
4. return vs. print
5. Zero-parameter functions
6. Exercise: Computing the Day of the Week
7. Variable Scope
Acknowledgement. This notebook has been adapted adapted from the Wellesley CS111 Spring 2019 course materials (http://cs111.wellesley.edu/spring19).
Functions are a way of abstracting over computational processes by capturing common patterns.
You have already used built-in functions like print
, input
and int
.
Here is a user-defined function to compute the square of a number.
def square(x):
"""A simple user-defined function."""
return x * x
Calling or invoking the function: we can call a function many times, but we define it once.
square(5)
square(7)
Parameters
A parameter names "holes" in the body 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)
someNumber
A function can take as many parameters as needed. They are listed one by one separated by comma.
Important (Order matters!) The order of parameters specifies the order of argument values.
def energy(mass, velocity):
"""Calculate kinetic energy"""
return 0.5 * mass * velocity**2
Problem description: A 1 kg brick falls off a high roof. It reaches the ground with a velocity of 8.85 m·s-1. What is the kinetic energy of the brick when it reaches the ground?
Call the function:
energy(1, 8.85)
import math
def distanceBetweenPoints(x1, y1, x2, y2):
"""Calculate the distance between points """
return math.sqrt((x2-x1)**2 + (y2-y1)**2)
You are given the following simple graph that depicts two points A and B in the 2-D coordinate system, where every tick is a unit of 1. Call the functioon distanceBetweenPoints
with the right values to calculate the distance.
Call the function:
distanceBetweenPoints(2, 1, 4, 3)
average
¶Define a function named average
that takes two numbers and returns the average of the two.
# Here define the function average
def average(num1, num2):
return (num1+num2)/2
Now try calling your function as below:
average(6,16)
return
vs. print
¶return
specifies the result of the function invocationprint
causes characters to be displayed in the shell.def square(x):
return x*x
def printSquare(a):
print('Square of', a , 'is', square(a))
Try out the result of the following expressions:
square(3) + square(4)
printSquare(5)
IMPORTANT: If a function doesn't return a value (but only prints one as a side effect), don't use it in expressions where
a value is expected. Can you guess what result you'll get below:
printSquare(3) + printSquare(4)
DIGGING DEEPER: See the notes on the None
value and the NoneType
type to understand in more detail why this happens.
We can verify that None
is not a string, by invoking the built-in function type
:
type(None)
type(printSquare(3))
print(print(print(printSquare(3))))
Sometimes it's helpful to define functions that have zero parameters.
Note: you still need parentheses after the function name when defining and invoking the function.
def rocks():
print("CS134 rocks!")
rocks()
rocks()
# Invoke the same function multiple times
def rocks3():
rocks()
rocks()
rocks()
rocks3()
Suppose we wanted to compute the day of the week for an arbitrary date, specified using a month, day, and year. We'll limit ourselves to dates between 1900 and 2099, inclusive.
The computed remainder tells us the day of the week, where 0 is Saturday.
If you do this in your head, you need to remember a short table of monthly adjustments. Each entry in the table corresponds to a month, where January is month 1 and December is month 12.
Month | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Adjusment | 1 | 4 | 4 | 0 | 2 | 5 | 0 | 3 | 6 | 1 | 4 | 6 |
Notice that $144$ is $12^2$, $025$ is $5^2$, $036$ is $6^2$, and $146$ is a bit more than $12^2$. If the year is divisible by $4$ (it's a leap year) and the date is January or February, you must subtract 1 from the adjustment.
Now, here's the algorithm:
madj
.year
since 1900. Grace Hopper, computer language pioneer, was born December 9, 1906. That would be year 6. Pixel, Iris's dog, was born on May 16, 2018, which is year 118.Now, compute the sum of the following quantities:
madj
(eg., 6 for Admiral Hopper) year
year
(e.g. 1 for Admiral Hopper)Compute the remainder of the sum of step 4, when divided by 7. The remainder gives the day of the week, where Saturday is 0, Sunday is 1, etc.
Notice that we can compute the remainders before we compute the sum. You may also have to compute the remainder after the sum as well, but if you're doing this in your head, this considerably simplifies the arithmetic.
How might you adjust the algorithm to make the result of 0 indicate Sunday?
John Conway. The above technique is due to John Conway, of Princeton University. Professor Conway answers 10 day of the week problems before gaining access to his computer. His record is well under 15 seconds for 10 correct dates. See Scientist at Work: John H. Conway; At Home in the Elusive World of Mathematics," The New York Times, October 12, 1993.
# Do not worry about how its implemented yet this part yet!
def monthAdjust(month, year):
'''Function that takes in month in 1-12 and year and returns monthly adjustment'''
# this is a *list* containing 12 integers.
adjustments = [1,4,4,0,2,5,0,3,6,1,4,6]
# the integers in the adjustment list are indexed 0 through 11
madj = adjustments[month-1]
# madj is the adjustment based on the particular month
if (year%4 == 0) and (month <= 2): # we will learn if statements in next lecture
madj -= 1 # shorter way of writing madj = madj - 1
return madj
monthAdjust(12, 1906)
monthAdjust(2, 2020)
def dayName(dayNum):
'''Takes day of the week as a number and returns day of
the week as a string, where Saturday is 0, Sunday is 1, etc.'''
# a *list of strings*, indexed between 0 and 6 (remainders, mod 7)
dayName = ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
return dayName[dayNum]
dayName(0)
dayName(3)
# Let us write out the final function to compute the day of the week.
def dayOfWeek(month, day, year):
'''This function takes a date as month 1-12, day 1-31, and year (1900-2099)
as input and returns the day of the week for that date'''
madj = monthAdjust(month, year)
year -= 1900 # same as year = year - 1900
sum = madj + day + year + (year//4)
rem = sum % 7
return dayName(rem)
dayOfWeek(2, 12, 2020) # Today's date
dayOfWeek(8, 15, 1997) # day of India's independence from British rule
dayOfWeek(12, 9, 1906) # Grace Hoppers Birthday!
So far we have been testing functions interactively and seeing what they return. If we define a function in a python script we must also include a function call that invokes the function.
Main function. To invoke the dayOfWeek function we need the following values from the user: month, day, and year. We can structure these input statements in another function whose purpose it is to get these inputs from the user, call dayOfWeek, and finally print out the solution in a nice user-friendly manner.
# Place your code for gathering user input and calling the dayOfweek function
def main():
month = int(input("Month (1-12): "))
day = int(input("Day (1-31): "))
year = int(input("Year (1900-2099): "))
# invoke the dayOfWeek function and save return value in a dow variable
dow = dayOfWeek(month, day, year)
print('Day of the week for the date ', month, '/', day, '/', year, ' is ', dow, sep = '')
# This function call runs the code in main()
main()
Local variables. An assignment to a variable within a function definition creates/changes a local variable. Local variables exist only within a functions 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)
num
def myfunc (val):
val = val + 1
print('local val = ', val)
return val
val = 3
newVal = myfunc(val)
print('global val =', val)
newVal