Chapter 2 · Decide, repeat, reuse
Functions
Step 1 of 22 · Concept
A function names a piece of work
In this lesson you write your own functions, give them values and get answers back.
def greet(name):
"""Print a greeting."""
print("Hello,", name)
| part | means |
|---|---|
def greet | make a function named greet |
(name) | its parameter: a name for the value it gets |
: and the indented block | its body |
def binds the name greet to a function object. The body runs later, at each call, such as greet("Ada").
Step 2 of 22 · Quiz
What does def print?
What does this program print?
def greet(name):
print("Hello,", name)
print("Ready")
Step 3 of 22 · Demo
Call it twice
Each call runs the body, with name pointing at the call's argument: "Ada", then "Alan". The last line
asks for greet's type: a function is an object too. Run it.
Step 4 of 22 · Concept
return sends a value back
def square(n):
return n * n
def cube(n):
return n * square(n)
print(square(4) + 1)
print(cube(2))
returnhands a value back to the caller, and the call ends.- The call
square(4)then stands for that value,16, sosquare(4) + 1prints17. cubecallssquarein its ownreturn:cube(2)is2 * 4, which prints8.- A function without
returnhands backNone: Python's value for "nothing".
Step 5 of 22 · Quiz
Predict the output
show prints, but has no return. Type exactly what this program prints.
def show(n):
print("n is", n)
result = show(3)
print(result)
Step 6 of 22 · Demo
See it run
Run it and compare with your answer.
Step 7 of 22 · Try it
Try it: return, not print
area has two parameters, so a call gives two arguments, in order. describe calls area and returns an
f-string. Run it: 12, then 3 by 4: None.
Change area so that it returns w * h instead of printing it. Then the program prints only 3 by 4: 12.
Put return where print is: return w * h. return is not a function, so it needs no brackets.
Step 8 of 22 · Exercise
Your turn: is_even
Write a function is_even(n) that returns True when n is even and False when it is odd. The program must
print:
False
True
True
n is even when the remainder after dividing it by 2 is 0. And 0 counts as even.
The def comes before the calls, with one parameter. A comparison already gives True or False (lesson 6),
so the body can return one comparison about n % 2.
def is_even(n):
Step 9 of 22 · Trace
Watch a call
A call gets a new frame on the stack. It goes on top of the caller's frame, here the <module> frame.
Its parameter n and the names its body binds, such as result, are its locals. They go with the frame when
the call returns.
The numbers are drawn in their boxes (lesson 3's shorthand). Press Next to run one moment at a time.
def square(n):
result = n * n
return result
print(square(4))- Line 1's
defmade the function and boundsquare. Line 5 is next. - Line 5 calls
square(4): a frame forsquaregoes on the stack, withn4. Line 2 is next. - Line 2 bound
resultto 16 insquare's frame. Line 3 is next. returnhanded 16 back, andsquare's frame is gone. Back on line 5,printgets 16.- Line 5 printed
16. The program is finished, and the stack is empty.
Step 10 of 22 · Concept
An argument is an arrow, copied
def bump(n):
n = n + 1
n = 5
bump(n)
- A call copies the arrow, not the object. Two names
n, in two frames, point at one5. n = n + 1givesbump'sna new value,6. It moves onlybump's arrow.
Step 11 of 22 · Quiz
What does the caller see?
Type exactly what this program prints.
def bump(n):
n = n + 1
print("inside:", n)
n = 5
bump(n)
print("outside:", n)
Step 12 of 22 · Demo
See it run
Run it and compare with your answer.
Step 13 of 22 · Exercise
Your turn: grade(score)
Turn lesson 6's grading chain into a function. grade(score) returns "A" for 90 or more, "B" for 70 or
more, and "C" otherwise. The program must print:
A
B
C
Each block of the chain returns its letter instead of printing it.
Inside grade: if score >= 90:, then elif score >= 70:, then else:. Each block holds one return.
if score >= 90:
return "A"
Step 14 of 22 · Demo
A call fills every parameter
Each parameter needs a value. Run it: the first call prints 12. The second gives only one argument, by its
place (a positional argument), so Python stops with
TypeError: area() missing 1 required positional argument: 'h'.
Step 15 of 22 · Concept
Defaults and keyword arguments
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Ada")
greet("Alan", greeting="Hi")
greeting="Hello"is a default value: a call may leavegreetingout.greet("Ada")printsHello, Ada!.greeting="Hi"in a call is a keyword argument: it names the parameter it fills.printhas its own:sep=goes between the values (a space by default),end=at the end (a new line).
Step 16 of 22 · Quiz
Predict the greetings
Type exactly what this program prints.
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Ada")
greet("Alan", greeting="Hi")
for i in range(5):
print("*", end="")
print()
print(1, 2, 3, sep=" < ")
Step 17 of 22 · Demo
See it run
Run it and compare with your answer.
Step 18 of 22 · Quiz
A function reads a name, or makes its own
show and add both use count. What happens when this program runs?
count = 0
def show():
print("count is", count)
def add():
count += 1
show()
add()
Step 19 of 22 · Demo
= inside a function makes a local
Run it. += or = inside a function makes the name a local, so add reads its own count. Python stops
with
UnboundLocalError: cannot access local variable 'count' where it is not associated with a value
("variable" is Python's word for a name).
The fix: pass the value in, return the new one. Avoid Python's global, which also works.
def add(count):
return count + 1
count = add(count)
Step 20 of 22 · Check yourself
Check yourself: a temperature converter
No shape this time.
- Write
to_fahrenheit(c), which returnsc * 9 / 5 + 32. - Write
describe(c, label="Today"), which returns the textToday: 25 C is 77.0 Ffor 25. - Print
describe(25), then 100 with the labelBoilingand -40 withSame in both, as keyword arguments.
The output must be exactly:
Today: 25 C is 77.0 F
Boiling: 100 C is 212.0 F
Same in both: -40 C is -40.0 F
describe can call to_fahrenheit inside its f-string, and returns the text; the calls print it.
Step 21 of 22 · Challenge · optional
Challenge: the first divisor
Optional.
first_divisor(n) returns the smallest number from 2 up that divides n. For a prime such as 13, that number is
n itself. The program must print:
3
7
13
return ends the call at once, even inside a loop. So a loop can stop at the first number that divides n.
Loop d over range(2, n). When n % d == 0, return d. After the loop, no number divided n: return n.
if n % d == 0:
return d
Step 22 of 22 · Recap
Recap
def square(n):bindssquareto a function object. Its body runs at each call.returnhands a value back; without it, a call givesNone.- Each call gets a frame. Its parameters and locals go when it returns.
- An argument copies the arrow: rebinding a parameter leaves the caller's name alone.
- A default may be left out; a keyword argument names its parameter:
end="".
Next: lesson 8 uses Python's own modules and splits a program into files.
Review
5 questions from this lesson, in a new order each time. Answer from memory: 3 of 5 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
def greet(name):
"""Print a greeting."""
print("Hello,", name)
greet("Ada")
greet("Alan")
print(type(greet))
def show(n):
print("n is", n)
result = show(3)
print(result)
def area(w, h):
print(w * h)
def describe(w, h):
return f"{w} by {h}: {area(w, h)}"
print(describe(3, 4))
# is_even(n): True when n is even, else False
print(is_even(3))
print(is_even(8))
print(is_even(0))
def bump(n):
n = n + 1
print("inside:", n)
n = 5
bump(n)
print("outside:", n)
def grade(score):
return "?"
print(grade(95))
print(grade(72))
print(grade(40))
def area(w, h):
return w * h
print(area(3, 4))
print(area(3))
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Ada")
greet("Alan", greeting="Hi")
for i in range(5):
print("*", end="")
print()
print(1, 2, 3, sep=" < ")
count = 0
def show():
print("count is", count)
def add():
count += 1
show()
add()
# to_fahrenheit(c) and describe(c, label="Today"),
# then three calls to describe, each printed
def first_divisor(n):
return n
print(first_divisor(15))
print(first_divisor(49))
print(first_divisor(13))