Published: 2024-07-27
Lesson 5 - Functions and Modules
Time To Complete: 2 hours
Programmers are lazy. Re-using working code in the world of programming is very important. If you don’t then your fingers will probably fall off from typing. you can re-use useful code by writing functions.
Using Functions
Functions have already been used in other lessons. The range()
function returns values from x to y.
#list of items from 0 up to 100
print(list(range(0,100)))
You could type out every value from 0 up to 100, but if you want to create a bigger list that would take a lot more time. If you use functions you could just as easily create a list with thousands of numbers.
def print_range(r):
print(list(range(1,r + 1)))
#print values 1 to 100
print_range(100)
Functions are chunks of code that tell Python to do something. They are one way to reuse code. You can use them over and over again. Functions are handy for simple programs and essential for complex programs with thousands of lines of code.
Parts of a Function
A function has three parts: name, parameters, and a body.
def myfunc(myname):
print("hello" + myname)
The name of this function is myfunc
. It has a single parameter, myname
, and its body is a block of code that follows the line starting with def
, which is short for define. A parameter
is a variable that exists only while a functions is being used.
You can run a function by calling its name and using ()
around the parameter
value.
myfunc("Jake")
Functions can take multiple values as parameters.
def myname(fname, lname):
print('Hello' + " " + fname + " " + lname)
myname("John", "Smith")
The two values are separated by comma like so, myname("John", "Smith")
.
You can also create some variables first and pass them into the function.
fname = "John"
lname = "Smith"
myname(fname , lname)
A function is used to return a value using the return statement.
Calculating Savings
You deliver newspapers every morning. You make $150 per week on your paper route. You already had $20 bucks in your pocket and you spent $40 bucks over the weekend. Write a function that returns your savings as an integer.
def savings(pocket_money, paper_route, spending):
return pocket_money + paper_route - spending
Code
This function returns three parameters. It adds the first two parameters (pocket_money & paper_route) and subtracts the last parameter (spending). The function returns the result and it can be stored in a variable.
Now, if you try to run this function as is nothing happens. This is because you have to call the function. This can be done by typing the name of the function and by providing values for the parameters.
money = savings(20, 150, 40)
print(money)
You can even save specific instances of a function, savings(20,150,40)
, as an object and reference that object later like in the example above.
Full Code:
def savings(pocket_money, paper_route, spending):
return pocket_money + paper_route - spending
money = savings(20, 150, 40)
print(money)
Variables and Scope
Variables can be created inside of functions. This can make writing functions with a lot of data a lot easier for developers, however, variables inside the body of a function can’t be used again. This is because variables created inside of a function only exist within that function. In the world of programming this is referred to as scope.
Let’s take a look at a simple function that uses a couple of variables.
def var_test():
first = 10
second = 20
return first * second
This function simply multiplies the value of first
with the value of second
and returns the result. If you call this function using print
you get 200
.
What happens if you try to print the value of first
and the value of second
?
def var_test():
first = 10
second = 20
return first * second
print(first)
print(second)
print(var_test())
If you try to execute the code above, you might notice the squiggle lines underneath print(first)
and print(second)
. This is python saying “Hey, I don’t know what these variables mean outside of var_test()
.” If you ignore python’s warning and run the code anyway you will be met with an error that may look like this:
Traceback (most recent call last):
File "<pythonshell>", line 12, in <module>
print(first)
NameError: name 'first' is not defined.
A variable defined inside of a function has a different scope than a variable defined outside of a function.
Now let’s declare a variable outside of a function and then call it inside of a function.
txt = 'hey'
def myfunc():
print(txt)
myfunc()
In the previous example, first
and second
could not be used outside of the function because they were declared locally, or inside of a function. In the example above the variable txt
can be used inside of the function because it was declared globally. An easy way to remember this is that, in python, variables declared globally can be used inside functions. Variable declared locally cannot be used outside of functions.
Building a spaceship
Suppose you were building a spaceship out of tin cans. You think you can flatten 2 cans a week to create the walls for your ship. You’ll need 500 cans to fully furnish your ship. Write a function to work out how long it will take to flatten 500 cans.
code:
def build_spaceship(cans): #1
total_cans = 0 #2
for i in range(1,53): #3
total_cans = total_cans + cans #4
print("Week " + str(i) + " = " + str(total_cans) + " cans" ) #5
explanation:
On 1
, define the function build_spaceship(cans)
. build_spaceship()
takes one parameter, cans
. Inside of the function on 2
, the variable total_cans
represents the number of cans that have been flattened. At the start there will be 0. The for loop
starting on 3
loops through the number of weeks in one year. After each iteration (or after each week) 4
calculates the number of cans flattened by adding the total_cans
variable and the number of cans flattened that week. 5
prints the number of cans flattened that week.
After 1 year (52 weeks) only 104 cans have been flattened. 500 cans are needed, so there is still a long way to go. Let’s speed things up by calling the function build_spaceship()
and passing in a value greater than 2 into cans
.
build_spaceship(13)
If 13 cans get flattened a week, then after 1 year you will produce 676 cans for your spaceship. By week 39, 507 cans had been flattened, why overproduce? Let’s tweak the function to stop at 500 total cans.
def build_spaceship(cans):
total_cans = 0
week = 0
while total_cans < 500:
total_cans = total_cans + cans
week += 1
print("Week " + str(week) + " = " + str(total_cans) + " cans" )
build_spaceship(13)
To do this very easily you can change the loop from for i in range(1,53):
to while total_cans < 500:
. Additionally, create a new local variable called week
and increment week by 1
at the end of each iteration to keep track of time.
Modules
Modules are used to group functions, variables and other things together into larger and more powerful programs. Python has some built in modules and others you can download off of the internet.
Let’s import a function that will allow us to display the current time.
import time
print(time.asctime())
The import command is used to tell python that you want to use the time
module. You can use functions that are available in this module using the dot symbol. In this case, time.asctime()
. The function asctime()
is apart of the time module and it returns the current date and time as a string.
Programming Problems
1. Basic Moon Weight Function
In lesson 3, one problem was to create a loop to determine what the weight of an object would on the moon if it increased in size over a 15 year period. The for
loop used to solve the problem in lesson 3 could easily be turned into a function. Revisit that problem, and write a function to calculate an object’s weight on the moon.
solution 1:
def moon_weight(weight):
moon_factor = .165
return weight * moon_factor
print(moon_weight(30))
solution 2:
def moon_weight(weight):
moon_factor = .165
print("weight on the moon: " + str(weight * moon_factor))
moon_weight(30)
2. Moon weight function in years
Now let’s completely rewrite the moon weight problem from lesson 3 as a function.
There is a bucket of rocks that weighs 145 pounds. If 1 lb of rocks is added every year, how much would the bucket weigh on the moon after 15 years?
def moon_weight(weight, added, years):
moon_factor = .165
for i in range(years):
weight += added
moon_weight = weight * moon_factor
print(str(i + 1) + ". " + str(moon_weight))
moon_weight(30, 1, 20)
3. Moon Weight Program
Now let’s take it one step further. Instead of a function that runs once, write a program using input()
to prompt the user to enter values for the function.
Try this one on your own. Reference the calculator program from lesson 4. Don’t over think it. All you have to do is put all of the pieces together.
Challenge
Make the program re-usable. Write the program in a way that allows the user to continuously run the program without having to restart.
Hint: refer to the
simple calculator program
in lesson 4.
3. Solution
This problem can have multiple solutions. Here are a few solutions:
solution 1
def moon_weight(weight, added, years):
moon_factor = .165
for i in range(years):
weight += added
moon_weight = weight * moon_factor
print(str(i + 1) + ". " + str(moon_weight))
weight = int(input("enter the starting weight: "))
added = int(input("enter the number of lb(s) added each year: "))
years = int(input("enter the number of years: "))
moon_weight(weight, added, years)
solution 2
def moon_weight():
moon_factor = .165
weight = int(input("enter the starting weight: "))
added = int(input("enter the number of lb(s) added each year: "))
years = int(input("enter the number of years: "))
for i in range(years):
weight += added
moon_weight = weight * moon_factor
print(str(i + 1) + ". " + str(moon_weight))
moon_weight()
solution 3
def moon_weight(weight, added, years):
moon_factor = .165
for i in range(years):
weight += added
moon_weight = weight * moon_factor
print(str(i + 1) + ". " + str(moon_weight))
moon_weight(int(input("enter the starting weight: ")),
int(input("enter the number of lb(s) added each year: ")),
int(input("enter the number of years: ")))
Note: Solution 3 works, but it is not as readable as the other two.