Session 9 - Functions

Session 9 of the Python Fundamentals series, covered in depth. It packages code into a named, reusable tool, covering def, parameters as inputs, return as output, and calling with parentheses. It draws the difference between return and print, shows that a function with no return gives None, and covers default arguments, functions that call other functions, and refactoring a repeated block into a single function. The traps are printing when you needed to return, calling without parentheses, and calling before the def. Every snippet and error message was copied verbatim from CPython 3.12.

Subject: Python Fundamentals · 95 slides · code lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. Functions

Title

Python Fundamentals - Session 9

Name a block of code once, use it again and again

2. What you will be able to do

Objectives

So far each program is one long script. Functions let you name and reuse steps. By the end you can:

  1. Define a function with def, give it parameters, and call it.
  2. Return a value and use it later in the program.
  3. Explain the difference between return and print.
  1. Know that a function with no return gives back None.
  2. Use default arguments and call one function from another.
  3. Refactor a repeated block into a single function.

3. What survived from Session 8 - Dictionaries?

Warm-up

Discussion prompt

Before we open Session 9 - Functions: without looking back, what was the main idea of Session 8 - Dictionaries, and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

That session covers key-value lookup, d[key] against d.get(), adding and updating, the in operator, looping over items, replacing an if/elif chain with a lookup, and tallying counts.

4. Naming a Block of Code

Section

Part 1

5. A function is a named, reusable block

Concept

A function bundles a few steps under one name. Call the name to run those steps - as many times as you like.

function — A named block of code you can call. It may take inputs (parameters) and hand back a result (return).

6. Break it if you can: A function is a named, reusable block

Counterexample

Discussion prompt

A function bundles a few steps under one name. Call the name to run those steps - as many times as you like.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

7. def creates a function

Concept

Start with def, the name, parentheses for inputs, and a colon. The indented block below is the function's body.

Defining a function does not run it - it just teaches Python the recipe for later.

8. What has to happen first: Define and call greet

Ranking

Put in order

Put the moves of Define and call greet into the order they have to happen.

  1. Lines 1-2 define greet - nothing runs yet
  2. Line 4 calls it with "Sam"
  3. Read the output

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Python just records the recipe: given a name, build a greeting.

9. Define and call greet

Worked example

def greet(name):
    return "Hello, " + name + "!"

print(greet("Sam"))

Lines 1-2 define greet - nothing runs yet

Why: Python just records the recipe: given a name, build a greeting.

Line 4 calls it with "Sam"

Why: Now the body runs with name = "Sam" and hands back the greeting.

Read the output

Why: Verified by execution: Hello, Sam!

callnamereturns
greet("Sam")SamHello, Sam!

10. Inspect it line by line: Define and call greet

Error analysis

Annotate

Walk the callouts on Define and call greet. Each one is a place this is easy to get subtly wrong.

  • Python just records the recipe: given a name, build a greeting.
  • Now the body runs with name = "Sam" and hands back the greeting.

11. Parentheses call the function

Concept

greet("Sam") - the parentheses mean 'run it now, with this input'. Without them you have only the name, not the result.

12. By analogy: Parentheses call the function

Analogy

Discussion prompt

Explain Parentheses call the function by analogy to something with no Python Fundamentals in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

greet("Sam") - the parentheses mean 'run it now, with this input'. Without them you have only the name, not the result.

13. A function is a little machine

Intuition

Picture a machine with an input slot and an output slot. You drop a value in (the argument), it does its work, and a result comes out (the return).

You do not care how the machine works inside when you use it - you just feed it inputs and take the output. That is the power of naming a block.

14. Teach it back: A function is a little machine

Explain it

Discussion prompt

Explain A function is a little machine to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Picture a machine with an input slot and an output slot. You drop a value in (the argument), it does its work, and a result comes out (the return).

15. The body runs only when called

Concept

Code inside a function sits idle until the function is called. Each call runs the body fresh, with the inputs you gave.

Call it three times and the body runs three times - that is reuse.

16. Parameters: Inputs

Section

Part 2

17. Parameters are the inputs

Concept

The names inside the def parentheses are parameters - placeholders for the values you will pass in.

parameter vs argument — A parameter is the name in the definition (def add(a, b)). An argument is the actual value you pass when calling (add(3, 4)).

18. Take the definitions apart: function vs parameter vs argument

Definition probe

Sort into buckets

Every line below is part of the definition of function or of parameter vs argument — one or the other, never both. Put each where it belongs.

function
A named block of code you can call.; It may take inputs (parameters) and hand back a result (return).
parameter vs argument
A parameter is the name in the definition (def add(a, b)).; An argument is the actual value you pass when calling (add(3, 4)).
b1
A named block of code you can call. It may take inputs (parameters) and hand back a result (return).
b2
A parameter is the name in the definition (def add(a, b)). An argument is the actual value you pass when calling (add(3, 4)).

19. Two inputs: add

Worked example

def add(a, b):
    return a + b

print(add(3, 4))

a and b are filled by the call

Why: add(3, 4) sets a = 3 and b = 4.

The body computes and returns

Why: Verified by execution: 3 + 4 = 7, so it prints 7.

abreturns
347

20. Draw the shape of it: Two inputs: add

Blank canvas

Draw it

Draw what Two inputs: add just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

21. Arguments fill parameters in order

Concept

The first argument goes to the first parameter, the second to the second, and so on. Order matters.

22. Order changes the result

Worked example

def subtract(a, b):
    return a - b

print(subtract(10, 3))
print(subtract(3, 10))

Swapping the arguments swaps a and b

Why: First call: a=10, b=3. Second: a=3, b=10.

Read the output

Why: Verified by execution: 7 then -7. Same function, different order in.

callabreturns
subtract(10, 3)1037
subtract(3, 10)310-7

23. Fill in: returns for Order changes the result

Comparison

Comparison matrix

From Order changes the result: refill the returns column from what you know. The rest of the table is as it appeared.

callabreturns
subtract(10, 3)1037
subtract(3, 10)310-7

24. A reusable area function

Worked example

def area(w, h):
    return w * h

print(area(3, 4))
print(area(5, 2))

One definition, many uses

Why: Each call reuses the same recipe with new numbers.

Read the output

Why: Verified by execution: 12 then 10.

callreturns
area(3, 4)12
area(5, 2)10

25. What each one costs: A reusable area function

Trade off

Comparison matrix

From A reusable area function: every row here is a choice with a cost. Fill the returns column, then say which row you would actually pick and what you give up for it.

callreturns
area(3, 4)12
area(5, 2)10

26. return: Output

Section

Part 3

27. return hands a value back

Concept

return value sends a result back to whoever called the function. The call then 'becomes' that value.

So add(3, 4) can be stored, printed, or used in more math - it stands in for 7.

28. Predict the next row: Store the returned value

Pattern

Predict first

The table runs: add(3, 4) | 7 · total | 7

In Store the returned value, given the rows so far: what is the next one — the row where step is total + 1?

Correct: total + 1 | 8

stepvalue
add(3, 4)7
total7
total + 18

Why: The relationship between the columns, not the individual numbers, is what generates the next row. Verified by execution: total + 1 is 8.

29. Store the returned value

Worked example

def add(a, b):
    return a + b

total = add(3, 4)
print(total + 1)

The call's result is stored in total

Why: add(3, 4) returns 7, so total is 7.

The value can be used further

Why: Verified by execution: total + 1 is 8. A returned value is a real value.

stepvalue
add(3, 4)7
total7
total + 18

30. Watch it run: Store the returned value

Pattern

Step through it

Step through Store the returned value one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: step is add(3, 4)
  2. Step 2: step is total
  3. Step 3: step is total + 1

31. return ends the function

Concept

The moment a return runs, the function stops and hands back that value. Any lines after it in the same path do not run.

This lets you return early - answer as soon as you know the result.

32. Where does each piece belong: Session 9 - Functions

Sorting

Sort into buckets

These are the pieces of Session 9 - Functions, out of order. Put each one back under the part of the lesson it belongs to.

Naming a Block of Code
A function is a named, reusable block; def creates a function; Define and call greet
Parameters: Inputs
Parameters are the inputs; Two inputs: add; Arguments fill parameters in order
return: Output
return hands a value back; Store the returned value; return ends the function
s1
Naming a Block of Code is where Session 9 - Functions puts A function is a named, reusable block, def creates a function, Define and call greet. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s2
Parameters: Inputs is where Session 9 - Functions puts Parameters are the inputs, Two inputs: add, Arguments fill parameters in order. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s3
return: Output is where Session 9 - Functions puts return hands a value back, Store the returned value, return ends the function. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.

33. Return early

Worked example

def sign(n):
    if n > 0:
        return "positive"
    if n < 0:
        return "negative"
    return "zero"

print(sign(-4))

The first matching return wins

Why: n < 0 is true, so it returns negative and stops - the zero line is never reached.

Read the output

Why: Verified by execution: negative. No else needed - a return already exits.

nreturns
7positive
-4negative
0zero

34. Watch it run: Return early

Pattern

Step through it

Step through Return early one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: n is 7
  2. Step 2: n is -4
  3. Step 3: n is 0

35. return is the answer slot

Intuition

Think of the machine's output slot. return is what you place in it - the single value that comes out when the machine finishes.

No return, nothing in the slot: the caller gets None (coming up).

36. return vs print

Section

Part 4

37. print shows; return gives back

Concept

print puts text on the screen for a human. return hands a value back to the program to use.

They feel similar because you often see a result either way - but only a returned value can be reused.

38. Restore the missing line: Two versions of double

Fill the middle

Fill in the blanks

From Two versions of double — one line has had its right-hand side removed. Put it back.

def double_print(n):
print(n * 2)

def double_return(n):
return n * 2

double_print(6)
r = double_return(6)
print(r + 1)

Why: r is what everything below it consumes, so the wrong expression here fails later and somewhere else. You see 12, but there is no value to store.

39. Two versions of double

Worked example

def double_print(n):
    print(n * 2)

def double_return(n):
    return n * 2

double_print(6)
r = double_return(6)
print(r + 1)

double_print shows 12 but hands nothing back

Why: You see 12, but there is no value to store.

double_return gives 12 to reuse

Why: Verified by execution: r is 12, and r + 1 is 13. Prints 12 then 13.

versionscreenreusable value
double_print(6)12none
double_return(6)-12

40. Something is wrong here: printing when you need to return

Anomaly

Predict first

A student writes this, and it looks reasonable:

The function prints instead of returning, then you try to reuse it.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: total becomes None, so total * 2 tries None * 2 and crashes.

return the value so the caller can use it.

Why: total becomes None, so total * 2 tries None * 2 and crashes. You saw 7 on screen, but could not use it.

41. Trap: printing when you need to return

Trap

The trap

The function prints instead of returning, then you try to reuse it.

def add(a, b):
    print(a + b)

total = add(3, 4)
print(total * 2)

add prints but returns None

Why: total becomes None, so total * 2 tries None * 2 and crashes. You saw 7 on screen, but could not use it.

stepvalue / result
add(3, 4)prints 7, returns None
total * 2TypeError: unsupported operand type(s)

The fix

return the value so the caller can use it.

def add(a, b):
    return a + b

total = add(3, 4)
print(total * 2)

Now total holds 7

Why: return hands 7 back; total * 2 is 14. Real output: 14. Rule of thumb: return the result, and let the caller decide whether to print it.

stepvalue
total7
total * 214

42. A returned value is flexible

Concept

Return, and the caller chooses what to do: print it, store it, compare it, or feed it into another function.

Print inside the function, and you have locked it into one behavior. Returning keeps functions reusable.

43. Restore the missing line: Reuse a returned value three ways

Fill the middle

Fill in the blanks

From Reuse a returned value three ways — one line has had its right-hand side removed. Put it back.

def area(w, h):
return w * h

a = area(3, 4)
print(a)
print(a > 10)
print(a + area(2, 2))

Why: a is what everything below it consumes, so the wrong expression here fails later and somewhere else. Stored, compared, and added to another call - all because area returns.

44. Reuse a returned value three ways

Worked example

def area(w, h):
    return w * h

a = area(3, 4)
print(a)
print(a > 10)
print(a + area(2, 2))

The one result is used three ways

Why: Stored, compared, and added to another call - all because area returns.

Read the output

Why: Verified by execution: 12, then True (12 > 10), then 16 (12 + 4).

expressionvalue
a12
a > 10True
a + area(2, 2)16

45. Watch it run: Reuse a returned value three ways

Pattern

Step through it

Step through Reuse a returned value three ways one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: expression is a
  2. Step 2: expression is a > 10
  3. Step 3: expression is a + area(2, 2)

46. Functions with No return

Section

Part 5

47. No return means None

Concept

If a function never runs a return, it still hands something back: the special value None, meaning 'no value'.

None — Python's 'nothing here' value. A function with no return gives back None; storing that result gives you None.

48. Term to definition: Session 9 - Functions

Matching

Match the pairs

Match each term to the definition this lesson gave it — not the one you would guess from the word.

  • t1. function
  • t2. parameter vs argument
  • t3. None
  • d1. A named block of code you can call. It may take inputs (parameters) and hand back a result (return).
  • d2. A parameter is the name in the definition (def add(a, b)). An argument is the actual value you pass when calling (add(3, 4)).
  • d3. Python's 'nothing here' value. A function with no return gives back None; storing that result gives you None.

Why: These are the working definitions of function, parameter vs argument, None as Session 9 - Functions uses them. Pairing them correctly is the test of whether you could state each one with the slide switched off.

49. Restore the missing line: A print-only function returns None

Fill the middle

Fill in the blanks

From A print-only function returns None — one line has had its right-hand side removed. Put it back.

def show(x):
print("value is", x)

result = show(5)
print(result)

Why: result is what everything below it consumes, so the wrong expression here fails later and somewhere else. Verified by execution: prints value is 5, then None.

50. A print-only function returns None

Worked example

def show(x):
    print("value is", x)

result = show(5)
print(result)

show prints but has no return

Why: So its call hands back None.

result is None

Why: Verified by execution: prints value is 5, then None.

stepoutput / value
show(5)prints value is 5
resultNone

51. Fill in: output / value for A print-only function returns None

Comparison

Comparison matrix

From A print-only function returns None: refill the output / value column from what you know. The rest of the table is as it appeared.

stepoutput / value
show(5)prints value is 5
resultNone

52. If your answer prints as None...

Concept

Seeing None where you expected a real result almost always means you forgot the return.

Check: does the function actually return the value, or only print it (or compute it and drop it)?

53. Something is wrong here: forgetting to return the result

Anomaly

Predict first

A student writes this, and it looks reasonable:

The function computes but never returns.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Without a return, square hands back None, so print shows None - the 25 is lost inside the function.

Return the computed value.

Why: Without a return, square hands back None, so print shows None - the 25 is lost inside the function.

54. Trap: forgetting to return the result

Trap

The trap

The function computes but never returns.

def square(n):
    result = n * n

print(square(5))

result is computed then thrown away

Why: Without a return, square hands back None, so print shows None - the 25 is lost inside the function.

you writeprints
square(5)None

The fix

Return the computed value.

def square(n):
    return n * n

print(square(5))

return sends 25 back

Why: Now the call is 25. Real output: 25. Compute, then return what you computed.

you writeprints
square(5)25

55. Defaults & Combining

Section

Part 6

56. Default arguments

Concept

Give a parameter a default with = in the def. If the caller omits it, the default is used.

def greet(name, greeting="Hi"): lets you call greet("Ana") or greet("Ana", "Welcome").

57. A default greeting

Worked example

def greet(name, greeting="Hi"):
    return greeting + ", " + name

print(greet("Ana"))
print(greet("Ana", "Welcome"))

Omit greeting and it defaults to Hi

Why: First call uses the default; second overrides it.

Read the output

Why: Verified by execution: Hi, Ana then Welcome, Ana.

callgreetingreturns
greet("Ana")HiHi, Ana
greet("Ana", "Welcome")WelcomeWelcome, Ana

58. Functions can call functions

Concept

A function's body can call other functions. This is how you build bigger tools from small, tested ones.

59. Use is_even inside a decision

Worked example

def is_even(n):
    return n % 2 == 0

num = 7
if is_even(num):
    print("even")
else:
    print("odd")

is_even returns a bool the if can use

Why: is_even(7) is False, so the else runs.

Read the output

Why: Verified by execution: prints odd. A returning function slots straight into a condition.

numis_even(num)prints
7Falseodd
4Trueeven

60. Reuse instead of repeat

Concept

If you find yourself copying the same few lines, that is a signal to make a function. Write it once, call it everywhere.

Fix a bug in one place instead of ten. This is the practical heart of why functions matter.

61. The Refactor Payoff

Section

Part 7

62. Turn a repeated block into a function

Concept

Take a chunk you keep rewriting, wrap it in a def, replace the varying parts with parameters, and return the result.

63. A matchup checker as a function

Worked example

def effective(attack, defender):
    if attack == "water" and defender == "fire":
        return "super effective"
    return "normal"

print(effective("water", "fire"))
print(effective("grass", "fire"))

The decision lives in one named place

Why: The two varying inputs become parameters; the answer is returned.

Call it as often as you like

Why: Verified by execution: super effective, then normal.

callreturns
effective("water", "fire")super effective
effective("grass", "fire")normal

64. Draw the shape of it: A matchup checker as a function

Blank canvas

Draw it

Draw what A matchup checker as a function just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

65. Predict the next row: Reuse across many calls

Pattern

Predict first

The table runs: 3x4 | 12 | 12 · 5x2 | 10 | 22

In Reuse across many calls, given the rows so far: what is the next one — the row where room is 6x6?

Correct: 6x6 | 36 | 58

roomareatotal
3x41212
5x21022
6x63658

Why: The relationship between the columns, not the individual numbers, is what generates the next row. area is reused inside the loop; no repeated w * h everywhere.

66. Reuse across many calls

Worked example

def area(w, h):
    return w * h

rooms = [(3, 4), (5, 2), (6, 6)]
total = 0
for w, h in rooms:
    total += area(w, h)
print(total)

One function, called once per room

Why: area is reused inside the loop; no repeated w * h everywhere.

Trace the total

Why: Verified by execution: 12 + 10 + 36 = 58.

roomareatotal
3x41212
5x21022
6x63658

67. Inspect it line by line: Reuse across many calls

Error analysis

Annotate

Walk the callouts on Reuse across many calls. Each one is a place this is easy to get subtly wrong.

  • area is reused inside the loop; no repeated w * h everywhere.
  • Verified by execution: 12 + 10 + 36 = 58.

68. Pitfalls

Section

Part 8

69. Something is wrong here: calling without parentheses

Anomaly

Predict first

A student writes this, and it looks reasonable:

Forgetting the parentheses on the call.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: You get the function object, not a result - it never runs.

Add parentheses (and the argument) to actually call it.

Why: You get the function object, not a result - it never runs. Nothing is greeted.

70. Trap: calling without parentheses

Trap

The trap

Forgetting the parentheses on the call.

def greet(name):
    return "Hi " + name

print(greet)

greet without () is the function itself

Why: You get the function object, not a result - it never runs. Nothing is greeted.

you writeprints
print(greet)<function greet ...> (the function, not a result)

The fix

Add parentheses (and the argument) to actually call it.

def greet(name):
    return "Hi " + name

print(greet("Sam"))

greet("Sam") runs the function

Why: The parentheses trigger the call. Real output: Hi Sam.

you writeprints
print(greet("Sam"))Hi Sam

71. Which of these survive contact with Session 9 - Functions?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
A function bundles a few steps under one name. Call the name to run those steps - as many times as you like.; greet("Sam") - the parentheses mean 'run it now, with this input'. Without them you have only the name, not the result.; Picture a machine with an input slot and an output slot. You drop a value in (the argument), it does its work, and a result comes out (the return).
Breaks
The function prints instead of returning, then you try to reuse it.; The function computes but never returns.
sound
These are stated as this lesson states them — each one survives the edge cases Session 9 - Functions puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

72. Define before you call

Concept

Python reads top to bottom, so a function must be defined above the line that calls it.

Calling a function that has not been defined yet is a NameError.

73. Order of def and call

Worked example

def say_hi():
    print("hi")

say_hi()

def comes first, call second

Why: By the time say_hi() runs, Python already knows the recipe.

Reversed order fails

Why: Verified by execution: this prints hi. Putting say_hi() above the def would raise NameError: name 'say_hi' is not defined.

orderresult
def then callhi
call then defNameError

74. Where the cost goes: Order of def and call

Cost model

Annotate

In Order of def and call, before reading the notes: mark where the time actually goes. Which line dominates?

  • By the time say_hi() runs, Python already knows the recipe.
  • Verified by execution: this prints hi. Putting say_hi() above the def would raise NameError: name 'say_hi' is not defined.

75. Passing arguments by name

Concept

You can name arguments in the call: greet(name="Ana", greeting="Yo"). Named arguments can even come in any order.

This makes a call self-documenting - you can see which value is which without checking the definition.

76. Teach it back: Passing arguments by name

Explain it

Discussion prompt

Explain Passing arguments by name to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

You can name arguments in the call: greet(name="Ana", greeting="Yo"). Named arguments can even come in any order.

77. Keyword arguments

Worked example

def greet(name, greeting="Hi"):
    return greeting + ", " + name

print(greet(greeting="Yo", name="Ana"))

Named arguments ignore position

Why: greeting and name are matched by name, so the reversed order still works.

Read the output

Why: Verified by execution: Yo, Ana.

arggoes to
greeting="Yo"greeting
name="Ana"name

78. What each one costs: Keyword arguments

Trade off

Comparison matrix

From Keyword arguments: every row here is a choice with a cost. Fill the goes to column, then say which row you would actually pick and what you give up for it.

arggoes to
greeting="Yo"greeting
name="Ana"name

79. Functions that answer yes/no

Concept

A function that returns a bool reads like a question. Name it starting with is_ or has_: is_passing(score).

It slots straight into an if, which keeps your conditions short and readable.

80. By analogy: Functions that answer yes/no

Analogy

Discussion prompt

Explain Functions that answer yes/no by analogy to something with no Python Fundamentals in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

A function that returns a bool reads like a question. Name it starting with is_ or has_: is_passing(score).

81. An is_passing helper

Worked example

def is_passing(score):
    return score >= 60

print(is_passing(72))
if is_passing(50):
    print("pass")
else:
    print("fail")

It returns True or False

Why: is_passing(72) is True; is_passing(50) is False.

Reads naturally in an if

Why: Verified by execution: prints True, then fail.

scoreis_passingif prints
72True-
50Falsefail

82. Fill in: if prints for An is_passing helper

Comparison

Comparison matrix

From An is_passing helper: refill the if prints column from what you know. The rest of the table is as it appeared.

scoreis_passingif prints
72True-
50Falsefail

83. Name functions for what they do

Concept

A good function name is a short verb phrase: calculate_total, greet, is_even. The name should tell the reader what the call produces.

If you cannot name it in a few words, it may be doing too much - a hint we follow up on next session.

84. Break it if you can: Name functions for what they do

Counterexample

Discussion prompt

A good function name is a short verb phrase: calculate_total, greet, is_even. The name should tell the reader what the call produces.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

If you cannot name it in a few words, it may be doing too much - a hint we follow up on next session.

85. Patterns & Checks

Section

Part 10

86. Writing a function

Pattern

1. def name(parameters): then an indented body

Why: Parameters are the inputs the body will use.

2. return the result (do not just print it)

Why: A returned value can be stored, compared, or reused; a printed one cannot.

3. Call it with name(arguments)

Why: The parentheses run it; arguments fill the parameters in order.

4. Define above the call, and reuse instead of repeating

Why: Python reads top to bottom. One function, many calls, one place to fix.

87. return vs print, decided

Pattern

Need the value later? return it

Why: Store it, compare it, feed it onward. This is the default for most functions.

Only showing a human? print is fine

Why: For a pure message with nothing to reuse, printing inside is okay.

Result comes out None? you forgot return

Why: The most common function bug - compute AND return.

88. Where this shows up: Session 9 - Functions

Real world

Discussion prompt

Outside this lesson: where does Session 9 - Functions actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of return vs print, decided is doing the work in it.

Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.

Answer:

Session 9 of the Python Fundamentals series, in depth. Packaging code into a named, reusable tool: def, parameters as inputs, return as output, calling with parentheses; the difference between return and print; functions with no return giving None; default arguments; functions calling functions; and refactoring a repeated block into one function.

89. Check: the return

Check

What comes back?

def add(a, b):
    return a + b

print(add(10, 5))
abreturns
105?

Check your understanding

What does this print?

  • A. 15 (correct)
  • B. None
  • C. 105
  • D. a + b

Answer: A

Why: add(10, 5) returns 10 + 5 = 15, and print shows it. Verified by execution.

Why B tempts people
There is a return, so the result is 15, not None.
Why C tempts people
The + adds the numbers (15); it does not join them as text (that needs strings).
Why D tempts people
a and b are replaced by their values before the addition runs.

90. Check: no return

Check

Spot the missing return.

def triple(n):
    n * 3

print(triple(4))
has return?result
no?

Check your understanding

What does this print?

  • A. None (correct)
  • B. 12
  • C. 4
  • D. Error

Answer: A

Why: n * 3 is computed but never returned, so triple hands back None. Adding return n * 3 would print 12. Verified by execution.

Why B tempts people
12 requires a return. Here n * 3 is computed and immediately discarded.
Why C tempts people
The function does not return n either; with no return at all, the result is None.
Why D tempts people
It is not an error - the function just returns None by default.

91. Check: print vs return

Check

Can you reuse a printed value?

def show(n):
    print(n)

x = show(5)
print(x)
show(5) printsx holds
5?

Check your understanding

What are the two lines of output?

  • A. 5 then None (correct)
  • B. 5 then 5
  • C. None then 5
  • D. 5 then Error

Answer: A

Why: show prints 5 but has no return, so x is None; then print(x) shows None. To reuse the value, show would need to return n. Verified by execution.

Why B tempts people
x is not 5 - show returns None because it only prints. So the second line is None.
Why C tempts people
show prints 5 first (that line runs), then the None from x prints second.
Why D tempts people
Printing None is fine - no error occurs.

92. Check: argument order

Check

Which parameter gets which value?

def divide(a, b):
    return a / b

print(divide(2, 8))
aba / b
28?

Check your understanding

What does this print?

  • A. 0.25 (correct)
  • B. 4.0
  • C. 4
  • D. 0

Answer: A

Why: Arguments fill in order: a = 2, b = 8, so a / b is 2 / 8 = 0.25. Verified by execution.

Why B tempts people
4.0 would be 8 / 2 - but the first argument (2) is a, and the second (8) is b.
Why C tempts people
Order aside, / always gives a float, so it would be 4.0, not 4.
Why D tempts people
2 / 8 is 0.25, not 0 - / does true division, not floor division.

93. Check: default argument

Check

The second argument is omitted.

def power(base, exp=2):
    return base ** exp

print(power(5))
baseexpreturns
5??

Check your understanding

What does this print?

  • A. 25 (correct)
  • B. 5
  • C. 10
  • D. Error - exp is missing

Answer: A

Why: exp defaults to 2 when omitted, so power(5) is 5 ** 2 = 25. Verified by execution.

Why B tempts people
exp is not 1 - its default is 2, so it is 5 squared, not 5.
Why C tempts people
is a power, not multiplication: 5 2 is 25, not 5 * 2.
Why D tempts people
exp has a default, so leaving it out is fine - no error.

94. Connect it up: Session 9 - Functions

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — Naming a Block of Code · Parameters: Inputs · return: Output · return vs print · Functions with No return · Defaults & Combining. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

95. What you can do now

Recap

A function is a named block. def defines it, parameters are its inputs, return is its output, and parentheses call it.

You writeIt means
def add(a, b):define a function with two inputs
return a + bhand the result back
add(3, 4)call it; the call becomes 7
no returnthe call is None
def f(x, y=2):y defaults to 2 if omitted

Return values you will reuse; print only for messages. Next session we go deeper - small single-job functions, local variables, and scope.

Sources

  1. Python 3 Tutorial - Defining Functions
  2. Python 3 Tutorial - Default Argument Values
  3. All snippets and error messages executed and copied from CPython 3.12. — Author verification run, 2026-07-15 (Python Fundamentals series, Session 9).

Want this taught 1-on-1? Alexander tutors Python Fundamentals — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108