3b Defining Your Own Functions

This lesson introduces the def statement with its header and indented body, separates defining a function from calling one, traces the detour a call makes through the flow of execution, and distinguishes a parameter from an argument.

Subject: Python · 65 slides · code lesson

Open the interactive version of this deck

What this lesson covers

The lesson, slide by slide

1. Lesson 3b Defining Your Own Functions

Title

Python · Chapter 3 — Functions

§3.4-3.7, pp. 19-21

2. By the end of this lesson you can

Objectives

Five things, each one you can check yourself at an interpreter prompt.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 19-21 — the pages these objectives are drawn from

3. Before we start: what would you want to name?

Warm-up

Functions exist because some sequences of statements deserve a name. Find one.

Discussion prompt

Think of any three-or-four-line sequence you have written or read in this course so far that you might want to do more than once. Describe it in three words, as though naming it.

Hint: The name is the point. If you can name it, it probably wants to be a function.

Answer:

Printing a heading, converting a temperature, showing a value twice — any of these is a candidate.

Notice what naming did: it let you refer to four lines with three words, and it let you talk about the sequence without listing it.

That is the whole benefit, and this lesson is about the syntax for claiming it. A function is a named sequence of statements that performs a computation — you have had the definition since lesson 3a, and now you get to write one.

4. The one idea behind this lesson: a definition creates, a call runs

Concept

A function definition specifies the name of a new function and the sequence of statements that run when the function is called. Those two things happen at two different times, and keeping them apart is what this whole lesson is for.

function definition — A statement that creates a new function, specifying its name, its parameters, and the statements it contains.

Function definitions get executed just like other statements, but the effect is to create function objects. The statements inside the function do not run until the function is called, and the definition itself generates no output.

Figure (svg): Two columns contrasting what happens when a definition runs with what happens when a call runs

Two separate events. The first must happen before the second.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 19-20

5. The def statement: header, colon, indented body

Section

Section 1

6. The shape of a definition

Concept

The keyword def indicates that this is a function definition. The first line is called the header; the rest is called the body. The header has to end with a colon and the body has to be indented.

header — The first line of a function definition: the keyword def, the name, the parentheses and the colon.

def print_lyrics():
    print("I'm a lumberjack, and I'm okay.")
    print("I sleep all night and I work all day.")
PartWhat it isNote
defthe keyword that starts a definitionrequired
print_lyricsthe name of the new functionsame rules as variable names
()empty: this function takes no argumentsrequired even when empty
:ends the headerrequired
print(...)the body, indented four spacesruns only when called

By convention, indentation is always four spaces. The body can contain any number of statements. The rules for function names are the same as for variable names: letters, numbers and underscore are legal, the first character cannot be a number, and you cannot use a keyword.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 19-19

7. Picture it: the two parts of a definition

Picture it

The colon at the end of the header and the indentation of the body are what tell Python where the function starts and stops.

Figure (svg): Two columns showing the header line of a definition and the indented body beneath it

The indentation is not decoration. It is how Python knows the body has ended.

Every compound statement in Python has this shape — a header ending in a colon, then an indented block. You will meet the same shape for if in chapter 5 and for loops in chapter 7.

8. Worked example: writing a definition and calling it

Worked example

Two separate things happen here. Watch when the output appears.

def print_lyrics():
    print("I'm a lumberjack, and I'm okay.")
    print("I sleep all night and I work all day.")

print_lyrics()
LinesWhat happensEffect
1-3the definition runsa function object is created; NO output
5the call runsthe body's two statements run
outputtwo linesboth from inside the function

Run the definition and notice the silence.

Why: The definition generates no output. Three lines executed and nothing appeared, which is exactly right.

Run the call.

Why: The syntax for calling the new function is the same as for built-in functions: the name, then parentheses.

Account for the two lines of output.

Why: Both came from the body. Each print inside the function ran once, in the order they are written.

Figure (svg): The state of the program after each line of Worked example writing a definition and calling it, drawn as a ladder with one rung per traced line

The whole run at once: each drop is one line of the program.

Two lines of output, both produced by the call on line 5. The definition on lines 1 to 3 produced nothing at all — it created the function rather than running it.

Verify: Delete the last line and run the file again.

Why: Nothing is printed. That is the cleanest possible demonstration that a definition runs nothing: the body is still there, still correct, and still silent, because nothing called it.

9. Predict: what does a definition display?

Prediction

You have seen this pattern before, with assignment in lesson 2a.

Predict first

You type a three-line function definition into a script and run it. What appears on the screen?

  • The body of the function
  • The name of the function
  • Nothing at all
  • An error, because the function was never called

Correct: Nothing at all — the definition generates no output.

Why: A function definition is executed like any other statement, but its effect is to create a function object and bind a name to it. The statements inside the body do not run until the function is called, so none of their output appears. This is the same shape as an assignment: an effect with no visible result, and silence is the correct outcome rather than a symptom.

10. Worked example: quotation marks inside the body

Worked example

The book uses double quotes here for a specific reason. Work out what it is.

print("I'm a lumberjack, and I'm okay.")
print('I am a lumberjack, and I am okay.')
VersionWhyResult
double quotes outsidethe apostrophes inside are ordinary charactersworks
single quotes outsidewould end the string at the apostrophewould break
the rulesingle and double quotes do the same thingchoose the one the text does not contain

Notice the apostrophes in the text.

Why: I'm contains a single quote, which is also an apostrophe.

See what would happen with single quotes outside.

Why: The string would end at the apostrophe in I'm, and the rest of the line would be leftover text Python could not parse.

State the rule.

Why: Single quotes and double quotes do the same thing; most people use single quotes except in cases like this, where a single quote appears in the string.

Figure (svg): Two columns showing a string with an apostrophe delimited by double quotes and the broken version delimited by single quotes

Both kinds of quote mark do the same job. Pick the one your text does not contain.

Double quotes, because the text contains apostrophes. The two kinds of quotation mark are interchangeable, which is precisely so that you can pick whichever one is not inside your text.

Verify: Check the constraint-challenge answer from lesson 1b against this.

Why: That probe predicted exactly this fix — use double quotes when the message contains a single quote — and here the book uses it in real code. A prediction from one lesson confirmed by the next chapter's practice is worth noticing.

11. Error analysis: four attempted definitions

Error analysis

One is correct. Mark what is wrong with the other three.

Annotate

  • Line 1 has no colon. The header has to end with a colon, and without it Python reports a syntax error at the end of the line.
  • Lines 2 and 3 together are the second attempt: a correct header, but the body is not indented, so Python does not treat it as the body at all.
  • An un-indented line after a header produces an IndentationError with the message expected an indented block, which is one of the most literal error messages Python produces.
  • Line 4 breaks the naming rules: a function name cannot begin with a number, exactly as a variable name cannot. The rules for function names are the same as for variable names.
  • The correct form needs all four things at once: def, a legal name, parentheses, a colon, and then an indented body beneath it.
  • Note that three of these are syntax errors, so nothing runs at all. A broken definition does not produce a half-working function; it stops the file.

The indentation error is the one worth causing on purpose once. It is the first time in this course that whitespace changes the meaning of a program.

12. Complete it: supply the missing punctuation

Faded example

Two characters are missing, and both are required rather than conventional.

Fill in the blanks

def greet():
print('Hello!')

Why: The empty parentheses indicate that this function does not take any arguments — they are required even when there is nothing to put in them, because they are what make it a function definition rather than something else. The colon ends the header and announces that an indented block follows. Omitting either is a syntax error, and neither is a matter of style.

13. Sort: legal or illegal function name?

Sorting

The rules are the same as for variable names, which you already know.

Sort into buckets

Sort each proposed function name.

legal
print_lyrics; repeat_lyrics; verse2
illegal
2nd_verse; def; print-lyrics
ok
Letters, digits and underscores only, no leading digit, and not a keyword. These are exactly the variable-name rules, applied unchanged to functions.
no
One begins with a digit, one is a keyword — and it is the keyword that starts a definition, so using it as a name would be hopeless — and one contains a hyphen, which Python reads as subtraction.

14. Think it through: why does the body have to be indented?

Socratic

Most languages use braces. Python uses whitespace, and there is a reason.

Discussion prompt

Python could have marked the end of a function body with a keyword like end. What does using indentation instead buy, and what does it cost?

Hint: Think about what programmers do to code anyway, in every language.

Answer:

It buys agreement between what the code looks like and what it means. In a language with braces, you can indent a line misleadingly and the indentation lies about the structure; in Python that is impossible, because the indentation IS the structure.

It costs you the ability to be careless with whitespace. Mixing tabs and spaces, or losing indentation when pasting code, changes the meaning of a program rather than merely its appearance.

The convention of four spaces exists to make the cost small: if everybody uses the same amount, code from different sources lines up. This is why the book states the convention as though it were a rule.

15. A definition creates an object, and the name refers to it

Section

Section 2

16. What a definition actually leaves behind

Concept

Defining a function creates a function object, which has type function. The name of the function is a variable that refers to that object — which is exactly the state-diagram picture from lesson 2a, with a function on the right of the arrow instead of a number.

>>> def print_lyrics():
...     print('a')
...
>>> print(print_lyrics)
<function print_lyrics at 0xb7e99e9c>
>>> type(print_lyrics)
<class 'function'>
What you writeWhat it meansWhat you get
print_lyricsthe name, with no parenthesesthe function object itself
type(print_lyrics)asking its typeclass function
print_lyrics()the name WITH parenthesesruns the body

If you type a function definition in interactive mode, the interpreter prints dots to let you know the definition is not complete. To end the function, you have to enter an empty line.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 20-20

17. Picture it: the same arrow as always

Picture it

Nothing new is happening here. A name refers to a value, and this time the value is a function.

Figure (svg): A state diagram showing the name print_lyrics with an arrow pointing at a function object, alongside n pointing at seventeen

A function is a value like any other. The def statement is a way of creating one and naming it.

This is why the parentheses matter so much: without them you have the value, and with them you run it. Lesson 3a made the same point about math.sqrt, and it is the same fact.

18. Worked example: a function calling a function

Worked example

Once a function is defined, its name is available inside other definitions.

def print_lyrics():
    print("I'm a lumberjack, and I'm okay.")
    print("I sleep all night and I work all day.")

def repeat_lyrics():
    print_lyrics()
    print_lyrics()

repeat_lyrics()
LinesWhat happensEffect
1-3define print_lyricsno output
5-7define repeat_lyricsno output
9call repeat_lyricswhich calls print_lyrics twice
outputfour linestwo per call of print_lyrics

Notice that the second definition uses the first.

Why: Once you have defined a function, you can use it inside another function. There is nothing special about doing so — the name is just available.

Count the output.

Why: repeat_lyrics calls print_lyrics twice, and each of those prints two lines, so four lines appear.

Notice which lines produced output.

Why: Only line 9. Both definitions were silent, exactly as before, and all four lines of output came from the single call at the bottom.

Figure (svg): A call diagram showing repeat_lyrics calling print_lyrics twice, with two lines of output from each

Four lines of output, all from the one call on line 9. The two definitions produced nothing, and the doubling came from repeat_lyrics calling print_lyrics twice.

Verify: Count the print statements in the file and compare with the output.

Why: There are two print statements and four lines of output. The counts no longer match — which, as in lesson 1a, is the signature of something running more than once. Here it is a function called twice rather than a loop, but the diagnostic is the same.

19. Predict: what does this script print?

Prediction

The definition is correct. Look at what happens after it.

def greet():
    print('Hello')

greet
LinesWhat happensOutput
1-2the definitioncreates the function, no output
4the name with NO parenthesesa bare expression
script modea bare expression is discardedno output

Predict first

What does this script display?

  • Hello
  • Nothing
  • The function object
  • A NameError

Correct: Nothing — the last line is a bare expression naming the function without calling it, and bare expressions are silent in a script.

Why: Two rules combine, one from each of two lessons. The name without parentheses refers to the function rather than calling it, so the body never runs. And a bare expression in script mode is evaluated and discarded, so even the function object is not displayed. At the interactive prompt the same file would show the function object — which is why this bug behaves differently depending on how you run it.

20. Worked example: the interactive-mode dots

Worked example

Defining a function at the prompt looks different from defining one in a file. Read the difference.

>>> def print_lyrics():
...     print('first line')
...     print('second line')
...
>>>
PromptWhat it meansWhat to do
>>>the normal promptstart a new statement
...the continuation promptthe definition is not finished
empty lineends the definitionback to the normal prompt

Recognise the second prompt.

Why: If you type a function definition in interactive mode, the interpreter prints dots to let you know that the definition is not complete.

Keep typing the body.

Why: Every indented line belongs to the function. The dots keep appearing because Python is still waiting to find out where the body ends.

End it with an empty line.

Why: To end the function you have to enter an empty line. In a file this is unnecessary — the end of the indentation is enough — which is why this only arises at the prompt.

Figure (svg): The state of the program after each line of Worked example the interactive-mode dots, drawn as a ladder with one rung per traced line

The whole run at once: each drop is one line of the program.

The dots are a continuation prompt, meaning the statement is not finished. An empty line ends the definition and the normal prompt returns.

Verify: Check that the function exists afterwards.

Why: Typing print_lyrics at the prompt now displays a function object rather than a NameError. Getting the ordinary prompt back does not by itself prove the definition worked, so checking the name is the confirmation.

21. Trap: calling a function without the parentheses

Trap

The trap

Wanting to run print_lyrics, a student writes the name on a line by itself.

Treat the name as the instruction

Why: In English, naming an action and asking for it are often the same thing.

In a script, nothing happens at all: the line is a bare expression, which is evaluated and discarded. At the prompt it displays a function object, which looks like an error and is not.

The fix

The parentheses are the operator that means call this.

Write the name to refer to the function; add parentheses to run it

Why: Both are legal and they mean different things — which is exactly the math.sqrt versus math.sqrt(2) distinction from lesson 3a.

If nothing happened, check for the parentheses first

Why: A silent script whose function body contains print statements is nearly always a call that was never made.

The displayed function object is genuinely informative when it happens: it tells you the name exists and refers to a function, which rules out a typo in the name.

22. Discriminate: does this run the body?

Discrimination

The parentheses decide. Sort on that alone.

Sort into buckets

For each line, does the function's body run?

the body runs
print_lyrics(); print(print_lyrics()); x = print_lyrics()
the body does not run
print_lyrics; print(print_lyrics); type(print_lyrics)
runs
Each of these has parentheses immediately after the function name, which is the call operator. What happens to the result afterwards — printed, assigned, discarded — does not change the fact that the body ran.
no
In each of these the name appears without parentheses after it, so the function object is referred to rather than called. The parentheses in print(...) and type(...) belong to those functions, not to print_lyrics.

23. Match: what each of these produces

Matching

Four expressions built from one function name. Match each to its result.

Match the pairs

  • a. greet
  • b. greet()
  • c. type(greet)
  • d. type(greet())
  • r1. the function object itself
  • r2. runs the body, and produces None
  • r3. the class function
  • r4. runs the body, then reports NoneType

Why: The pattern is entirely mechanical: parentheses after greet mean the body runs, and no parentheses mean it does not. The fourth is the interesting one — the body runs, producing output, and THEN its return value is asked about, giving NoneType. That None is the subject of lesson 3c, and meeting it here as a puzzle makes it less surprising there.

24. Explain it yourself: is a function a value?

Explain it to yourself

The state diagram said yes. Make sure you believe it.

Discussion prompt

In what sense is a function a value like 17 or 'hello'? Give two things you can do with a function that you can also do with an integer, and one thing you can do with a function that you cannot do with an integer.

Hint: Think about names, and about type().

Answer:

You can bind a name to it, and you can ask type() about it. Both work identically for 17 and for a function object, which is what the state diagram was showing.

What you can do with a function and not with an integer is call it — put parentheses after it and have something happen. Trying that on an integer gives int object is not callable, which is the same message as math.pi() from lesson 3a.

The reason this is worth being clear about is that chapter 19 will pass functions to other functions as arguments. That only makes sense if a function really is a value, and the evidence for that is already on this slide.

25. Definitions and uses: define before you call

Section

Section 3

26. Why the order of the lines matters

Concept

Function definitions get executed just like other statements, so they run in order like everything else. As you might expect, you have to create a function before you can run it — in other words, the function definition has to run before the function gets called.

def print_lyrics():
    print('lyrics')

def repeat_lyrics():
    print_lyrics()
    print_lyrics()

repeat_lyrics()
LinesWhat happensRequirement
1-2define print_lyricsthe name now exists
4-6define repeat_lyricsits body is not checked yet
8call repeat_lyricswhich needs print_lyrics to exist NOW

The book sets two exercises here that are worth doing rather than reading about: move the last line to the top and see what error you get, then move the definition of print_lyrics after the definition of repeat_lyrics and see what happens. The two experiments have different answers, and the difference is the whole point.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 20-21

27. Picture it: two experiments with different outcomes

Picture it

One rearrangement breaks the program and the other does not. Predict which before looking.

Figure (svg): Two columns showing the call moved to the top, which fails, and one definition moved after another, which works

What matters is the order at the moment of the CALL, not the order on the page.

The right-hand column surprises people. repeat_lyrics mentions print_lyrics before it is defined, and that is fine — because the mention is inside a body, and bodies are not run until they are called.

28. Worked example: the first experiment, calling too early

Worked example

The book's first exercise. Predict the error before advancing.

repeat_lyrics()

def print_lyrics():
    print('lyrics')

def repeat_lyrics():
    print_lyrics()
LineWhat happensConsequence
1call repeat_lyricsbut nothing has defined it yet
resultNameError: name 'repeat_lyrics' is not definedthe program stops
3-7never reachedthe definitions never run

Start at line 1 as always.

Why: Execution always begins at the first statement of the program, so the call is the first thing attempted.

Look up the name.

Why: Nothing has created repeat_lyrics yet — the def statement that would create it is four lines below and has not run.

Read the error.

Why: A NameError, which is the same error you would get from using any undefined name. Python does not distinguish not defined yet from never defined.

Figure (svg): The state of the program after each line of Worked example the first experiment, calling too early, drawn as a ladder with one rung per traced line

The whole run at once: each drop is one line of the program.

A NameError on line 1. The definitions never run, because the program stops at the first error, so the file is no better off for containing them.

Verify: Compare with what happens if you use an undefined variable.

Why: Using an undefined variable gives the same NameError, with the same wording. Function names are ordinary names — the state diagram said so — and this error is the same error, which is why no new concept is needed to explain it.

29. Predict: when does the error appear?

Prediction

The function mentions a name that does not exist anywhere.

def show():
    print(missing_name)

print('before')
LinesWhat happensResult
1-2the definition runsno error; the body is not checked
4print('before') runsdisplays before
nevershow is never calledthe bad name is never looked up

Predict first

What does this script do?

  • A NameError immediately, because missing_name does not exist
  • It prints 'before' and exits with no error
  • A NameError after printing 'before'
  • A SyntaxError, because the name is undefined

Correct: It prints 'before' and exits with no error, because show is never called and its body is never run.

Why: The definition creates a function object without examining what the body refers to. Since nothing ever calls show, the name missing_name is never looked up, and no error occurs. This is genuinely useful to know: a Python file can contain a completely broken function and run perfectly, right up until somebody calls it.

30. Worked example: the second experiment, which works

Worked example

The book's second exercise, and the answer surprises most readers.

def repeat_lyrics():
    print_lyrics()
    print_lyrics()

def print_lyrics():
    print('lyrics')

repeat_lyrics()
LinesWhat happensWhy it works
1-3define repeat_lyricsits BODY is not run and not checked
5-6define print_lyricsthe name now exists
8call repeat_lyricsits body runs NOW, and print_lyrics exists

Notice what line 2 does when the definition runs.

Why: Nothing. The statements inside the function do not run until the function is called, so the mention of print_lyrics on line 2 is not looked up yet.

Run the second definition.

Why: By line 6, both names exist.

Run the call.

Why: Now the body of repeat_lyrics executes, and when it reaches print_lyrics that name has existed for two lines. It works.

Figure (svg): A flow chart showing definitions being executed in order and then a call causing the body to run, with the name lookup happening at call time

It runs correctly. A function body may mention a name that does not exist yet, as long as the name exists by the time the body actually runs.

Verify: Delete the definition of print_lyrics entirely and see when the error appears.

Why: The file still defines repeat_lyrics without complaint, and the NameError appears only when repeat_lyrics is called. That the error waits until the call is proof that bodies are genuinely not examined at definition time — which is the fact this experiment exists to establish.

31. Trap: believing Python checks the body when the definition runs

Trap

The trap

A student writes a function that calls a helper they have not written yet, runs the file, sees no error, and concludes the helper must exist somewhere.

Assume that no error means everything referenced is present

Why: In many languages a compiler would indeed check this before running anything.

Python does not. The definition succeeds regardless of what the body mentions, and the error waits until the body actually runs — possibly much later, possibly only for certain inputs.

The fix

A definition creates an object. It does not verify the body.

Expect name errors at CALL time, not at definition time

Why: Which means a file can import cleanly and still fail the moment a particular function is used.

Call every function you write at least once

Why: This is the only way to find out whether its body actually works, and it is one reason the book's development method in chapter 6 tests as it goes.

The upside of the same rule is the second experiment: functions may refer to each other in any order, which makes it possible to write two functions that call each other at all.

32. Rank: put these lines in a working order

Ranking

Four lines, one working arrangement. Definitions before the call that needs them.

Put in order

  1. print('starting')
  2. def helper(): print('help')
  3. def main(): helper()
  4. main()

Why: The only hard requirement is that the call to main comes after main is defined. Beyond that there is freedom: helper could be defined after main, because main's body is not run until it is called. The order given here is the conventional one — a bit of setup, then definitions, then the call that starts everything — and conventions like this exist so that a reader does not have to check whether the order is legal.

33. Step zero: where do you put the call?

Step zero

A structural decision that every Python file makes.

Discussion prompt

You are writing a script with three function definitions and one line that starts everything off. Where does that line go, and what would go wrong if you put it between the second and third definitions?

Hint: Ask which definitions have to have run by then.

Answer:

It goes at the bottom, after all three definitions. That is the arrangement that is guaranteed to work regardless of which functions call which.

Putting it between the second and third definitions works ONLY if nothing reachable from that call needs the third function. Since that depends on the whole call graph, it is a fact you would have to re-check every time you edited any of the three.

So the bottom is not merely conventional. It is the only position whose correctness does not depend on details that change as the program grows — which is a good reason for a convention to exist.

34. Find the counterexample: must a definition come first on the page?

Counterexample

The rule is about time, not about position. Show that the two differ.

Discussion prompt

Construct a program where a function is USED on a line that appears above the line defining it, and yet the program runs correctly. Explain why it works.

Hint: The second experiment in this section is one. Find the general principle.

Answer:

Any pair of mutually referring functions does it: def a(): b() written above def b(): print('hi'), with the call to a at the bottom.

It works because the mention of b inside a's body is not looked up when a is defined — only when a is called, by which time b exists.

The principle: the rule is that the definition must EXECUTE before the call executes, not that it must appear earlier in the file. The two coincide for top-level calls, which is why the shorter version of the rule is usually good enough — but functions calling each other is exactly the case where they come apart.

35. Flow of execution: a call is a detour

Section

Section 4

36. Where the program is, at any moment

Concept

To ensure that a function is defined before its first use, you have to know the order statements run in, which is called the flow of execution. Execution always begins at the first statement of the program, and statements are run one at a time in order from top to bottom.

flow of execution — The order in which statements run.

In summary, when you read a program you do not always want to read from top to bottom. Sometimes it makes more sense to follow the flow of execution.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 21-21

37. Picture it: the detour and the return

Picture it

The flow leaves the main line, does some work, and comes back to exactly the point it left.

Figure (svg): A flow chart showing execution running down a program, jumping into a function body, running it, and returning to the line after the call

The crucial word is back. A call is not a jump to somewhere else; it is a jump that returns, which is what makes functions composable at all.

38. Worked example: tracing the flow through two calls

Worked example

Write down the order in which the print statements run before advancing.

def greet():
    print('B')

print('A')
greet()
print('C')
Line runningWhat happensOutput
4print('A')A
5call greet: detour into the body-
2print('B') inside the functionB
5the body ends: return to the call site-
6print('C')C

Start at the first statement that is not a definition.

Why: The definition on lines 1 to 2 creates the function and runs nothing, so execution effectively begins at line 4.

Follow the detour.

Why: At line 5 the flow jumps into the body, runs line 2, and reaches the end of the body.

Follow the return.

Why: The flow comes back to pick up where it left off — line 6, the statement after the call.

Figure (svg): A call diagram showing the main flow printing A, calling greet which prints B, and returning to print C

A, then B, then C. The output is in the order the flow visits the print statements, which is not the order they appear in the file.

Verify: Read the file top to bottom and note that the order differs.

Why: Reading the page gives B, A, C — the order the lines are written. The actual output is A, B, C. That mismatch is exactly why the book says you do not always want to read a program from top to bottom, and following the flow is the alternative it recommends.

39. Watch the flow: where is the program now?

Invariant

Step through and say, at each frame, which line is currently running.

Step through it

At frame 3, how many functions are paused waiting to resume — and where will the flow go when inner finishes?

  1. The flow is in __main__ and has reached the call.
  2. The detour began: the flow is now inside outer, at its first statement.
  3. A second detour: the flow is inside inner, and outer is paused at line 6 waiting for it.
  4. inner finished and returned. outer resumes at the line after its call.
  5. outer finished and returned. The flow is back where it started and the program ends.

Two things are paused at frame 3: outer, at line 6, and __main__, at line 9. Python keeps track of both, which is why it can return through them in the right order. Lesson 3c draws this as a stack diagram.

40. Worked example: a detour inside a detour

Worked example

Two levels deep. Track where the flow is at each moment.

def inner():
    print('inner')

def outer():
    print('outer start')
    inner()
    print('outer end')

outer()
LineWhat happensOutput
9call outerflow enters outer
5print('outer start')outer start
6call innerflow enters inner
2print('inner')inner
7inner returns; outer continuesouter end

Enter the first detour.

Why: The call on line 9 sends the flow into outer's body.

Enter the second detour from inside the first.

Why: While in the middle of one function, the program has to run the statements in another. That is line 6.

Come back twice.

Why: inner finishes and the flow returns to line 7, still inside outer. Then outer finishes and the flow returns to line 9, which is the end of the program.

Figure (svg): The state of the program after each line of Worked example a detour inside a detour, drawn as a ladder with one rung per traced line

The whole run at once: each drop is one line of the program.

outer start, inner, outer end. The flow went two levels deep and came back out through both, resuming each function exactly where it had paused.

Verify: Check that outer end printed after inner rather than before.

Why: It did, which proves the flow genuinely returned into the middle of outer rather than abandoning it. If a call did not come back, outer end would never appear — and that is the difference between a call and a jump.

41. Trap: reading a program in file order

Trap

The trap

Asked what a program outputs, a student reads the print statements top to bottom and lists them in that order.

Assume the order on the page is the order of execution

Why: For a program with no functions it is, which is why the habit forms in chapters 1 and 2.

With functions, the order on the page and the order of execution come apart completely. A print inside a definition near the top may run last, or never.

The fix

Follow the flow of execution, which is a different reading order.

Skip the definitions on the way down

Why: They create objects and run nothing. Note the names they create and move on.

At each call, jump to the body, read it, and come back to the line after the call

Why: That is the detour, and it is what turns file order into execution order.

This is the reading skill the section exists to teach, and it is worth practising deliberately: put your finger on the line the flow is at, and move it.

42. Predict: the order of the output

Prediction

Follow the flow rather than the page.

def f():
    print(2)

print(1)
f()
print(3)
LineWhat runsOutput
4print(1)1
5call f, run its body2
6print(3)3

Predict first

In what order do the numbers appear?

  • 2, 1, 3
  • 1, 2, 3
  • 1, 3, 2
  • 1, 3 — the 2 never prints

Correct: 1, 2, 3 — the flow prints 1, detours into f to print 2, then returns and prints 3.

Why: The numbers were deliberately chosen so that execution order and file order disagree: on the page the 2 appears first. Following the flow gives 1, 2, 3, which is the answer, and reading the page gives 2, 1, 3, which is not. This is the shortest possible demonstration of why the two reading orders are different skills.

43. Analogical pivot: the detour

Analogy

Match each part of a function call to the part of the journey it corresponds to.

Match the pairs

  • a. the call
  • b. the body
  • c. the end of the body
  • d. the line after the call
  • r1. leaving the main road at a junction
  • r2. the stretch of road you drive along the detour
  • r3. rejoining the main road
  • r4. the point on the main road you continue from

Why: The analogy is exact in the way that matters: you rejoin at the point you left, not at the start and not further along. Where it breaks down is that a detour can contain another detour to any depth, and the driver always remembers every junction — which is the part Python handles for you and which lesson 3c makes visible as a stack of frames.

44. Push the boundary: what if a function calls itself?

Edge cases

Nothing in the rules forbids it. Work out what would happen.

Discussion prompt

The rule says a call detours into the body and comes back. What happens if the body contains a call to the same function? Describe the flow, and say whether it ever comes back.

Hint: Apply the rule literally, twice, and then again.

Answer:

The flow detours into the body, reaches the call, and detours into the body again — the same body, but a fresh detour that will have to come back separately.

With nothing to stop it, this repeats forever, and Python eventually stops it with a RecursionError because it cannot keep track of unlimited paused calls.

With something to stop it — a condition that skips the inner call in some case — it becomes recursion, which is one of the most powerful ideas in the book. Chapter 5 introduces it properly, and the flow rule you have just applied is the whole mechanism. Nothing new is needed.

45. Parameters and arguments: two words, two things

Section

Section 5

46. The name the caller uses and the name the function uses

Concept

Some of the functions you have seen require arguments. Inside the function, the arguments are assigned to variables called parameters. The two are different things and the book keeps two words for them.

parameter — A name used inside a function to refer to the value passed as an argument.

def print_twice(bruce):
    print(bruce)
    print(bruce)
PieceWhich wordMeaning
brucethe PARAMETER, named in the headera name the function uses
print_twice('Spam')'Spam' is the ARGUMENTsupplied by the caller
inside the bodybruce refers to 'Spam'for this call only

This function assigns the argument to a parameter named bruce. When the function is called, it prints the value of the parameter — whatever it is — twice. The function works with any value that can be printed.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 21-22

47. Picture it: the argument travels, the name does not

Picture it

The value crosses into the function. The name it had outside stays outside.

Figure (svg): A diagram showing the caller's variable michael and the function's parameter bruce both pointing at the same string value

Two names, one value. The names have nothing to do with each other.

The book puts it memorably: it does not matter what the value was called back home in the caller; here in print_twice, we call everybody bruce.

48. Worked example: one function, four different arguments

Worked example

The parameter is a name; whatever arrives becomes what it refers to.

>>> print_twice('Spam')
Spam
Spam
>>> print_twice(42)
42
42
>>> print_twice(math.pi)
3.141592653589793
3.141592653589793
ArgumentIts typeWhat bruce refers to
'Spam'a strbruce refers to 'Spam'
42an intbruce refers to 42
math.pia floatbruce refers to that float

Notice that the function was not changed.

Why: One definition, three calls, three different types of argument. Nothing about the definition mentions a type.

See what the parameter does.

Why: It is a name that refers to whatever was passed. On each call it refers to something different, and the body does not care.

State the scope of the claim.

Why: The function works with any value that can be printed — which, since print accepts anything, means any value at all.

Figure (svg): The state of the program after each line of Worked example one function, four different arguments, drawn as a ladder with one rung per traced line

The whole run at once: each drop is one line of the program.

All three work, printing each argument twice. The parameter is a name, not a type, and the function is written in terms of what it does rather than what it is given.

Verify: Pass something for which printing is unusual and check the claim holds.

Why: print_twice(print_twice) prints the function object twice. That the function accepts even a function as its argument confirms there is no type restriction at all — which is a stronger check than three ordinary values.

49. Predict: does this work?

Prediction

The caller's variable has a completely different name from the parameter.

def print_twice(bruce):
    print(bruce)
    print(bruce)

michael = 'Eric, the half a bee.'
print_twice(michael)
LineWhat happensState
michael = ...creates a name in __main__michael -> the string
print_twice(michael)the VALUE is passedbruce -> the same string
the bodyprints bruce twicetwo identical lines

Predict first

What happens when this runs?

  • A NameError, because bruce was never assigned
  • It prints the sentence twice
  • It prints the word michael twice
  • A TypeError, because the names do not match

Correct: It prints the sentence twice. Only the value is passed; the names are unrelated.

Why: The parameter bruce is created by the call itself and set to refer to whatever the argument evaluated to. The caller's name for that value, michael, never enters the function and is not needed there. If the names had to match, a function could only ever be called with one variable, which would make functions almost useless.

50. Worked example: the argument is evaluated first

Worked example

This is the composition rule from lesson 3a, and it applies to your own functions too.

>>> print_twice('Spam ' * 4)
Spam Spam Spam Spam 
Spam Spam Spam Spam 
>>> print_twice(math.cos(math.pi))
-1.0
-1.0
Argument expressionWhen it is evaluatedWhat the body sees
'Spam ' * 4evaluated ONCE, before the call'Spam Spam Spam Spam '
brucerefers to the finished stringprinted twice
math.cos(math.pi)evaluated once, before the call-1.0

Identify the argument.

Why: It is an expression, and the same rules of composition that apply to built-in functions also apply to programmer-defined functions.

Note when it runs.

Why: The argument is evaluated before the function is called, so 'Spam ' * 4 is only evaluated once even though bruce is used twice inside.

Check the consequence.

Why: The two printed lines are identical, because they are two printings of one value rather than two evaluations of one expression.

Figure (svg): A diagram showing an argument expression being evaluated to a value, which is then bound to the parameter and used twice inside the function

One evaluation, one value, however many times the parameter is used.

Both work, and in each case the argument expression is evaluated once, before the call. The body sees a finished value and has no access to the expression that produced it.

Verify: Reason about what you would see if the expression were evaluated per use.

Why: If the expression ran once per mention of bruce, a random or time-dependent argument would print two different values. It does not, which is observable evidence for the once-before-the-call rule rather than an assertion of it.

51. Trap: believing the argument's name must match the parameter's

Trap

The trap

Having written def print_twice(bruce), a student believes they must create a variable called bruce before they can call it.

Assume the two names are connected

Why: They appear in the same call, and one does supply the other's value, so a connection is a natural inference.

This leads to renaming variables at the call site to match parameters, which is unnecessary, and to confusion whenever the same function is called with two differently named variables.

The fix

The names are entirely independent. Only the VALUE travels.

Name the caller's variable for what it means there

Why: michael = 'Eric, the half a bee.' is named for the caller's purposes.

Name the parameter for what it means inside the function

Why: bruce is the function's own name for whatever it was given.

The book states it directly: the name of the variable passed as an argument has nothing to do with the name of the parameter. It does not matter what the value was called back home; here in print_twice, we call everybody bruce.

52. Match the word to the thing

Matching

Two words that beginners routinely swap. Fix them here, once.

Match the pairs

  • a. parameter
  • b. argument
  • c. where the parameter is named
  • d. where the argument is supplied
  • r1. the name inside the function
  • r2. the value supplied by the caller
  • r3. in the header, between the parentheses of def
  • r4. at the call site, between the parentheses of the call

Why: The clean way to remember it: the parameter is written once, in the definition; the argument is written at every call, and can be different every time. One function with one parameter can be called with a thousand different arguments, which is the whole reason parameters exist.

53. Fill the middle: write a function with a parameter

Fill the middle

One blank in the header, one in the body. They must agree with each other and with nothing else.

Fill in the blanks

def shout(message):
print(message)

shout('hello')

Why: Any legal name would do for the parameter, as long as the body uses the same one — the two blanks must match each other. Note what they need NOT match: the argument at the call site is the literal 'hello', which has no name at all, and that is perfectly fine. A parameter is the function's private name for whatever arrives.

54. Explain it: parameter versus argument

Explain it

This is the distinction most worth being able to explain, because so much documentation assumes it.

Discussion prompt

In two sentences, explain to somebody the difference between a parameter and an argument, using print_twice as your example. Then give them a one-line test they could run to convince themselves the names are independent.

Hint: The test should involve calling the function with a variable that has a different name.

Answer:

Say: the parameter is the name the function uses for whatever it is given, written once in the header. The argument is the actual value handed over at the call, written fresh every time you call it.

The test: make a variable with any name at all — x = 'hi' — and call print_twice(x). It works, which proves the caller's name is irrelevant.

A stronger version of the test is to call it twice with two differently named variables. Both work, and no single name could have satisfied both, so the independence is not a coincidence of the first example.

55. Compare: defining versus calling

Comparison

Fill the blanks. Almost every confusion in this lesson is a mix-up between these two columns.

Comparison matrix

QuestionThe definitionThe call
What does it do?creates a function object and names itruns the statements in the body
Does it produce output?no, neveryes, if the body prints anything
How is it written?def, a name, parentheses, a colon, an indented bodythe name, then parentheses
When are the body's names looked up?not at allwhen the body runs, at call time

The bottom row is the one that surprises people, and it is the reason a broken function can sit in a file for months without anybody noticing.

56. The procedure: writing a function from scratch

Pattern

Six steps, and the last two are the ones beginners skip.

  1. Decide what the function should do, and name it for that — the naming rules are the variable-name rules.
  2. Decide what it needs to be told, and give each of those a parameter name in the header.
  3. Write the header: def, the name, the parameters in parentheses, and a colon.
  4. Write the body, indented four spaces, using the parameter names for the values that arrive.
  5. Put the definition above the line that will call it, or at least above the point where that call runs.
  6. Call it at least once, with a real argument, and check the output — because nothing in the body is checked until it runs.

Step 6 is not a formality. A definition with a typo in its body is accepted silently and fails only when called, so an uncalled function is an untested function.

Python documentation — More Control Flow Tools More Control Flow Tools

57. Check yourself 1 of 3: what a definition outputs

Check

Two events, and only one of them produces anything.

def show():
    print('hi')
LinesWhat happensNote
1-2the definition executesa function object is created
outputnonethe body has not run
to see 'hi'call show()then the body runs

Check your understanding

This is the entire content of a script. What does it print?

  • A. hi
  • B. Nothing (correct)
  • C. The function object
  • D. An error, because show is never called

Answer: B

Why: The definition creates a function object and binds the name show to it. The statements inside the function do not run until the function is called, and nothing calls it, so the print statement never executes. A definition generates no output — the silence is correct rather than a symptom.

Why A tempts people
This is what a CALL would print. The body exists and is correct; it simply never runs, because no line in the file invokes it.
Why C tempts people
Nothing displays the function object either. That would require a bare expression at the interactive prompt, and this script contains no expression at all outside the definition.
Why D tempts people
Leaving a function uncalled is entirely legal. Most real programs define functions they do not call on every run.

58. Check yourself 2 of 3: the flow of execution

Check

Follow the flow, not the page.

def f():
    print('B')

print('A')
f()
print('C')
LineWhat runsOutput
4print('A')A
5detour into fB
6return and continueC

Check your understanding

In what order does this script print A, B and C?

  • A. B, A, C
  • B. A, B, C (correct)
  • C. A, C, B
  • D. A, C — B never prints

Answer: B

Why: The definition runs silently, so execution effectively starts at line 4 and prints A. The call on line 5 is a detour into the body, which prints B, and then the flow comes back to pick up where it left off — line 6, which prints C. Following the flow gives A, B, C.

Why A tempts people
This is file order: the print inside the definition appears first on the page. It is exactly the reading the section warns against, because definitions run nothing.
Why C tempts people
This would require the call to be deferred until after line 6, which nothing in the program does. A call happens where it is written.
Why D tempts people
The call on line 5 does run the body. B appears — the only way it would not is if line 5 were removed or the parentheses omitted.

59. Check yourself 3 of 3: parameters and arguments

Check

Only the value crosses into the function.

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

count = 5
double(count)
LineWhat happensState or output
count = 5a name in __main__count -> 5
double(count)the value 5 is passedn -> 5
print(n * 2)inside the function10

Check your understanding

Which of these is true about this program?

  • A. It fails, because the caller's variable is not called n
  • B. It prints 10, and n is the parameter while count is the argument's name in the caller (correct)
  • C. It prints 10, and n and count are two names for the same variable
  • D. It prints 5, because n refers to the name count rather than to its value

Answer: B

Why: The call evaluates the argument — the expression count, which is worth 5 — and assigns that value to the parameter n. The names are independent: n exists only inside the function, count only outside, and only the value 5 travelled between them. Doubling it prints 10.

Why A tempts people
The names never have to match. If they did, a function could only be called with one particular variable, which would defeat the purpose of parameters.
Why C tempts people
They are not two names for one variable. They are two separate names that happen to refer to the same value, which is a different claim — and lesson 3c shows why the difference matters when a function assigns to its parameter.
Why D tempts people
A name is not passed; its value is. The expression count is evaluated before the call, exactly as 'Spam ' * 4 was, and the function receives 5 with no knowledge of where it came from.

60. Where this shows up outside this course

Real world

Defining something once and invoking it by name is not a programming idea.

Discussion prompt

Find something outside programming that is defined once and then invoked by name many times, where the definition itself does nothing until invoked — a recipe, a legal procedure, a piece of choreography, a keyboard shortcut. What plays the role of the argument?

Hint: A recipe that says for any quantity of flour has a parameter.

Answer:

A recipe is the clearest case. Writing it down does nothing; cooking it is the call. Scale to n servings is a parameter, and the number of guests is the argument.

Legal procedure works too: a defined process is invoked with a particular case as its argument, and the process is written in terms of the applicant rather than a specific person's name — which is exactly the parameter-versus-argument distinction.

In both cases the definition is written once, in general terms, and the specific values arrive at invocation. That is the whole design pattern, and functions are the programming instance of it.

61. Confidence wager: commit before you check

Commit first

Answer, then rate your confidence. This one is about when Python checks things.

Predict first

A script defines a function whose body calls a function that does not exist anywhere. The script never calls the defined function. What happens when you run it?

  • A NameError when the definition runs
  • A SyntaxError, caught before anything runs
  • Nothing — it runs cleanly with no error
  • A warning, but the program continues

Correct: Nothing — it runs cleanly, because the body is never executed and its names are never looked up.

Why: A definition creates a function object without examining what the body refers to. Names inside a body are looked up when the body runs, and this body never runs. The practical consequence is important and slightly alarming: a Python file can contain thoroughly broken functions and still run without complaint, which is why calling every function you write at least once is not optional. If you predicted an immediate error, you were expecting a compiler-style check that Python does not perform.

62. Explain it to someone else

Explain it

The definition-versus-call distinction is the whole lesson, and it is best tested by explaining it.

Discussion prompt

A classmate has written a function with three print statements in it, run the file, and got no output. They are sure the function is wrong. Explain what has probably happened and what one line would fix it — and say how you knew without seeing their code.

Hint: This is the same diagnostic shape as the script-mode silence from lesson 2a.

Answer:

Say: a definition creates the function and runs nothing, so a file that only defines functions produces no output. They almost certainly never called it.

The fix is one line at the bottom: the function's name followed by parentheses. Nothing inside the function needs to change.

How you knew without seeing it: the symptom is total silence from code that obviously contains print statements, and there are only two common causes — no print at all, or no call. Since they told you there are three prints, it is the call. Being able to narrow it that far from a symptom is exactly what the error taxonomy from lesson 2b is for.

63. Exit ticket

Exit ticket

One honest answer. It decides what the next lesson opens with.

Predict first

Which of these is still least solid for you?

  • The syntax: header, colon, indented body
  • Why a definition produces no output, and when the body's names are checked
  • Tracing the flow of execution through a call and back
  • Parameter versus argument, and why the names are independent

Correct: Whichever you picked is the right answer — this one is for you, not for a mark.

Why: The syntax settles within a handful of functions and your editor helps. The definition-versus-call distinction is the conceptual core and is worth revisiting until it is automatic, because lesson 3c's stack diagrams assume it. Flow tracing is a skill that keeps improving and pays off most in chapter 5, where recursion makes it essential. And the parameter-argument distinction is the one that quietly blocks progress if left fuzzy — it is why chapter 6's fruitful functions make sense, and why chapter 10's list arguments are surprising.

64. Synthesis: draw the map of this lesson

Connect it up

One page, no code, from memory.

Draw it

Draw a timeline running left to right for a script that defines two functions and then calls one of them. Mark on it: when each function object is created, when the flow detours, when it returns, and when any output appears. Then, above the timeline, mark the one moment at which the names inside a body are looked up — and write one sentence on why that moment is later than most people expect.

65. What you can do now

Recap

Three pages, and you can write functions of your own.

If you remember one thingIt is this
From the syntaxThe colon ends the header and the indentation is the body. Both are required.
From definitionsA definition runs nothing and checks nothing. An uncalled function is an untested function.
From the flowA call is a detour that comes back to the very next line.
From parametersOnly the value travels. What it was called back home is nobody's business inside the function.

The next lesson finishes chapter 3: what happens to a function's variables when it returns, how to draw a stack diagram, how to read a traceback, and the difference between a function that returns a result and one that merely does something.

Think Python, 2nd edition — Allen B. Downey §3.4-3.7, pp. 19-21 — everything on these slides traces back here

Sources

  1. Think Python, 2nd edition — Allen B. Downey — Allen B. Downey, Think Python: How to Think Like a Computer Scientist, 2nd edition (Green Tea Press, 2015), §3.4-3.7, pp. 19-21
  2. Python documentation — More Control Flow Tools
  3. Python documentation — Built-in Functions

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

Book on Wyzant · Text (657) 465-8108