Embercode
✕
Functions and ScopeLesson 1 of 17

40 min read

Writing and calling functions in Python

Why it matters

Every program you write will grow past the point where one long list of lines is easy to read. Without structure, the same five lines turn up in three places, and when you find a bug in one copy you forget the other two. A function is the tool that fixes this. You write a group of steps once, give the group a name, and then use that name wherever you need the steps. Interviewers look for this habit in coding rounds, and the rest of this course depends on it. Binary search, sorting, recursion and dynamic programming are all written as functions.

The idea, from the beginning

A function is a named block of code that does one job. "Block" here means a group of statements that belong together. In Python a block is marked by indentation, which means the lines are pushed right by four spaces. "Named" means you give the group a word, such as greet, so that you can refer to it later. "One job" is a rule of good design, not a rule of the language. Python will run a function that does three jobs, but you will understand it far more easily if you keep each function to one job.

Java programmers call this a method. In Python the word method is kept for a function that belongs to a class, which you meet in the object lesson. A function defined at the top level of a file is simply called a function.

Think of a recipe card. You write the steps for making tomato soup once, on a card in your kitchen drawer. Each time you want soup you do not rewrite the card. You read the card, or you say "make the soup", and the steps happen. The card is the function definition. Each time you cook is a function call. The soup is what the function does, and if you improve the recipe you change the card once and every future bowl benefits.

A Python program works the same way. The definition is the card. The call is the moment the program reads the card and carries out the steps. A definition does nothing by itself. Only a call makes the steps happen. Python reads a def line and stores the function under its name, and it runs the body only when the name is called. This single fact explains most of the first mistakes beginners make, so keep it in mind as you read.

Your first function

Here is a complete Python program. It defines one function called greet and calls it twice. Read it once before you run it.

Python · editable

Press Run. The output is four lines:

Hello!
Welcome to ForgeStack.
Hello!
Welcome to ForgeStack.

The two lines of the function body ran twice, once for each call. The body was typed only once. That is the whole point of a function.

Python runs a file from the top, one statement at a time. The def statement is a statement like any other. When Python reaches def greet():, it creates the function and binds it to the name greet. The two lines inside it do not run at that moment. They run later, when greet() is called. Then the two calls on the last two lines do the work.

The parts of a function definition

Look at the first line of greet again:

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

A function definition has five visible parts, in this order.

The first word, def, is short for define. It tells Python that a function definition starts here.

The second part, greet, is the name. Choose names that describe the job. Python style, written down in a guide called PEP 8, uses lower case words joined with underscores for function names. Good names are print_report, calculate_tax and is_empty. Poor names are do_stuff, function1 and x. A good name often starts with a verb, because a function does something.

The third part, (), is the parameter list. The brackets are empty here, so the function needs no information from its caller. In the next lesson you will put names inside these brackets.

The fourth part, the colon :, ends the header. Python requires it. Without it you get an error, which the common mistakes section shows.

The fifth part is the body. The body is the indented code under the header. Every line of the body is pushed right by the same amount, usually four spaces. Python uses that indentation to know where the body ends. When a line returns to the left margin, the body is over.

Python does not use a word like void to say what a function returns. Every function returns something. If the body does not say return, the function returns the special value None, which means "nothing". The next lesson covers return in detail.

Python does not use the word static. A function at the top level of a file can be called from anywhere below its definition in that file. There is no class to put it in, so there is no need to mark it.

A function can be defined above or below the code that calls it, but only if the definition has already run when the call happens. The order matters in Python, and the mistakes section shows what happens when it is wrong.

Calling a function

Defining a function is writing the card. Calling it is cooking. To call a function, write its name followed by round brackets: greet(). The brackets are required even when the function has no parameters. Without them Python does not run the function. The name on its own refers to the function object, and Python does nothing with it. That is a common mistake, covered below.

When Python reaches a call, four things happen in order.

  1. Python remembers the line it is on, so it knows where to come back to.
  2. Python jumps into the body of the called function.
  3. Python runs every line of that body, in order.
  4. When the body ends, Python jumps back to the remembered line and continues with the line after the call.

Step 1 is the important one. It is why a function can be called from many different places and still return to the right spot. The last section of this lesson shows how Python keeps track of this.

Here is a program where one function calls another. Read the output carefully, because it is the best test of whether you understand the order.

Python · editable

The output is:

start
----------
  REPORT
----------
end

Trace it by hand. The first print shows start. Then the program reaches title() and jumps into title. The first line of title is line(), so Python jumps into line, prints a row of dashes, and comes back. Back in title the next line prints REPORT. Then title calls line a second time and comes back again. When title ends, Python returns to the top level, which prints end.

Notice that title calls line twice. A function can call the same function as often as it likes, and a function can call another function that calls a third one. There is no fixed limit to the depth of this chain in ordinary programs, although very deep chains can run out of room, which the last section explains.

Why split code into functions

Beginners sometimes think functions are only a way to avoid typing. That is one benefit, but there are four others. Each one matters more as programs grow.

The first is no repetition. When a rule changes, for example the price of a delivery, you edit one function instead of five copies.

The second is readability. A line that says print_report() tells a reader what happens without forcing them to read every line that does it. You can read the bottom of a file as a summary of the program, and read a function only when you need its details.

The third is testing. You can check one small function by calling it with a few inputs and comparing the results with what you expect. A hundred-line block of top-level code is much harder to check, because a failure could be anywhere.

The fourth is change. A bug fixed in one function is fixed for every call. If you find a mistake in a copy-pasted block, you have to hunt down every copy.

Interviewers look for these qualities. If you write a long solution where one helper function would make the idea clearer, the interviewer may ask you to refactor it. Refactoring means changing the structure of code without changing what it does, and splitting code into well-named functions is the most common kind.

A useful rule is this: if you need a comment to explain a block of code, that block is often a good candidate for a function, and the function's name can replace the comment. Compare two versions of the same idea.

# version A: a comment explains the block
# compute the total price including 18 percent tax
total = price + price * 0.18
# version B: the function name explains the block
def total_with_tax(price):
    return price + price * 0.18

Version B is shorter where it is used, and its name can be read in a sentence. The comment in version A can go out of date when someone edits the line. The name of a function is checked every time you call it. If you rename the function and forget one call, the call fails with a NameError the first time that line runs, so the mismatch cannot hide for long.

Naming functions well

A name is a promise to the reader. When a function is called print_report, the reader expects a report to appear on the screen. When it is called calc, the reader has to open the function to learn what it calculates. Good names save time for everyone who reads the code later, including you.

Follow four simple habits. Start with a verb, because a function does something: print, draw, compute, check, load. Use the words that the problem uses, so a bank program talks about deposit and withdraw, not op1 and op2. Keep names short but complete, so total_with_tax is better than t and better than total_amount_including_the_tax_percentage. And make a name that answers yes or no start with is or has, as in is_empty or has_passed, so an if statement reads like English.

Be careful with names that hide a second job. A function called check_age that also prints a warning and changes a counter is doing three jobs, and its name lies about two of them. Rename it, or split it.

Avoid names that clash with Python's own words, such as if, for, class or def. Python will not let you use them. Names that are real but unhelpful, such as data or info, are allowed but make the code hard to follow. Also avoid shadowing built-in names such as list, sum or print. A function named sum hides Python's own sum for the rest of the file. The scope lesson explains why.

Keep the same spelling across the file. If one function uses print_line and another uses print_ln, a reader will wonder whether they are different things. Python treats them as different names too, so one of the two calls will fail with a NameError.

A longer program, read as a summary

Real programs have many functions, and the way to read them is from the top down. The bottom of the file is a summary. Each call in it names a job. You open a called function only when you need its details. The table below shows how a reader might map a short program with four functions.

FunctionJobWho calls it
mainRuns the whole program in orderThe last line of the file
show_headerPrints the title and a dividermain
show_itemsPrints each menu itemmain
show_footerPrints the closing line and thanksmain

Reading the table tells you the shape of the program without reading any code. Notice that main calls three functions and none calls main. Many programs look like this: one entry point, with a row of helpers above it. The helpers do not call each other unless they need to. When two helpers do call each other, draw the arrows on paper. A small diagram like that is a quick check that no function is doing a job that belongs to another.

A reader can also check the program by asking two questions about each function. What is its job, in a sentence? Who calls it? If you cannot answer the second question, the function is not used, and you should either call it or delete it. If you cannot answer the first in one sentence, the function is doing too much.

Worked example 1: a menu made of functions

Here is a small program that prints a shop menu. It uses three functions that each do one job, and main shows the menu by calling them in order. The last two lines use a pattern you will see in many Python files. Run it and then read the trace below.

Python · editable

Output:

ForgeStack Shop
================
1. Tea
2. Coffee
3. Juice
Choose a number.

The last two lines are the usual entry point. __name__ is a built-in variable. When you run a file directly, Python sets __name__ to the text "__main__". When another file imports this file, __name__ is the file's own name, and the if block does not run. So the menu appears only when the file is run as a program. That lets you reuse the functions in another file without the menu printing as a side effect.

Trace the calls. main calls show_menu. The first line of show_menu calls show_title, which prints two lines and returns. Next show_menu calls show_items, which prints three lines and returns. Finally show_menu prints the last line and returns to main, which has nothing left to do.

Look at the structure rather than the output. Each function has a single purpose, and the name tells you what it prints. If the shop adds a fourth drink, you change only show_items. If the title changes, you change only show_title. show_menu is the place where the order of the menu is decided, so a reader who wants to know how the menu is built can start there.

Worked example 2: calling in a loop

A function can be called inside a loop. The loop controls how many times, and the function controls what each repeat does. This program prints three rows. Each row comes from one call to print_stars.

Python · editable

Output:

row 1: **********
row 2: **********
row 3: **********
done

The print call with end="" prints the label and leaves the cursor on the same line. By default print adds a newline at the end, which is why the label and the stars share a line here. Then print_stars prints the stars and ends the line. So each loop pass produces exactly one complete line.

The variable n is set to 3 in the file, so the program needs no input. In a later module you will read the number from the user with input(). For now, notice that the loop and the function are separate jobs. The loop decides how many rows, and print_stars decides what one row looks like.

Worked example 3: the order of execution

The next program has functions written in a different order from the calls. Python does not care about the order of definitions as long as each definition has run before its call. Read the program, predict the output, then run it.

Python · editable

The output is numbered so that you can check the order:

1 main begins
2 inside second
3 inside third
4 back in second
5 main ends

main calls second, and second is defined below main. That is allowed here because all three def lines have run before the last line calls main(). When second reaches third(), Python finds the definition and runs it. The numbers show that main does not finish until second has returned, and second does not finish until third has returned. Each function finishes its own lines only after the call it made.

This is the first real rule about how functions behave. A function's lines run in order, but when a line is a call, the caller waits. Nothing else happens in the caller until the called function returns. The last section explains what memory holds that waiting.

Compare this with the same program where the call comes first:

main()
 
def main():
    print("1 main begins")

This fails with NameError: name 'main' is not defined. The def has not run yet, so the name does not exist. The rule is that the definition must run before the call, and in a file that means the def must be above the call at the top level.

What happens inside

You do not need to understand the interpreter to write functions, but a short picture helps you read error messages and avoid confusion later.

Python reads your file and turns it into bytecode. Bytecode is a list of small instructions for the Python virtual machine, which is the part of the interpreter that carries them out. The standard Python program, called CPython, does this for you. When a file is imported by another file, Python also saves the bytecode in a cache folder named __pycache__, so the next import can skip the translation step. You never need to look at the cache.

When def greet(): runs, Python creates a function object. That object holds the body's bytecode, the name and a few other details. The name greet is then a label that points at this object. Calling greet() tells Python to run the bytecode in the object.

Each call creates a new frame. A frame is a small record that holds the local variables of one call and the line to return to. The frames form a stack. When a function calls another, a new frame is added on top. When a function returns, its frame is removed, and the frame below continues. This stack is the reason a function can be called from many places and still return to the right spot. The stack has a size limit, and very deep recursion hits it. The recursion lesson covers that limit, which Python calls the recursion limit.

Reading a call without running it

Much of programming is reading code that someone else wrote, and most of that reading is done without running anything. You open a file, see a call such as print_summary(), and need to know what happens next. A reliable way to do this is to ask three questions in order.

First, where is the definition? Search the project for def print_summary with your editor's search. In a small file you will find it within a few lines. In a large project the definition may be in another file, so your editor's go-to-definition feature is the quickest route.

Second, what does the definition do, in order? Read the body from top to bottom. Note every print, every change to a value, and every call to another function. Those calls need the same three questions, one level deeper. Stop when you reach a function whose body you understand.

Third, what does the caller expect to happen after the call returns? For a function that returns None, the answer is usually nothing, except for the printed text or the change it makes to shared data. For a function that returns a value, the caller probably stores the result, and you should check what it does with it.

A small example makes this clear. Suppose you see this at the bottom of a file:

print_summary()
print("Done")

You open print_summary and find that it calls load_items and then prints a line for each item. Now you know the program prints the summary lines, and then Done. You also know that load_items runs before any line is printed. Without opening load_items you would not know what the items are, but you would know the order of the output, which is often the question that matters most.

Practise this habit on purpose. Pick a program from this course, and before you run it, write down the order of the output by following the calls with your finger on the screen. Then run it and compare. Each mismatch shows a call you misread, and fixing those misreadings is the fastest way to learn how functions work.

Common mistakes and the messages you will see

Most early errors in Python come from a small set of causes. Here are the usual ones with the messages that Python 3.14 prints. The line number in each message tells you where to look. Paths in the traceback depend on where your file is saved, so they will differ on your machine.

Forgetting the colon. You write def greet() without the colon at the end. Python says:

SyntaxError: expected ':'

The caret points at the end of the header, which is where the colon belongs.

Forgetting the indentation. The body of the function is not indented. Python says:

IndentationError: expected an indented block after function definition on line 1

Indent every line of the body by the same amount, usually four spaces. Do not mix tabs and spaces.

Forgetting the brackets in the call. You write greet instead of greet(). Python does not complain at all. It evaluates the name, finds the function object, and throws it away. Nothing prints. This is one of the hardest mistakes to see, because there is no message. If a function seems to do nothing, check that the call has brackets.

Calling a function that does not exist. You write greeting() but defined greet(). Python says:

NameError: name 'greeting' is not defined

If the name is close to another one, Python adds a hint, such as Did you mean: 'greet'? for gret(). It adds none for greeting. Compare the spelling character by character with the definition. Python is case sensitive, so Greet and greet are different names.

Spelling a name differently inside a body. The call sits inside another function, and a typo such as printLIne() appears in the body of print_header. The error appears only when that line runs, not when the file is read. The message is the same NameError, and the traceback shows the line inside the function.

Calling before the definition. The call is above the def. The message is NameError: name 'main' is not defined. Move the call below the definition, at the top level of the file.

Defining the same name twice. Two def greet() lines in one file give no error. The second definition replaces the first, and every call uses the second. Python does not warn you. Check for duplicate names if a function behaves as if it were a different one.

Expecting a definition to run. Defining greet and never calling it does nothing. The program runs with no error, and the body never prints. Check that every function you wrote is called somewhere.

Reading an error message step by step

When Python reports an error, follow the same four steps every time.

First, read the file name and line number in the traceback. Go to that line in your editor. The interpreter usually points at the first place where it became confused, not necessarily the place where you made the mistake.

Second, read the last line of the message. It names the kind of error, such as NameError, SyntaxError or IndentationError, and then gives the details.

Third, look at the caret. The small ^ under the code shows the part of the line that failed. Python 3.14 underlines the part it was looking at.

Fourth, look at the line above. Many syntax errors come from the line before the one named, especially a missing colon or bracket.

Try this on purpose. Take the greet program and remove the colon after def greet(). Run it. Python reports expected ':' with the caret at the end of the header. Put the colon back and the error goes away.

A debugging walkthrough

Reading error messages is a skill, and it improves fastest when you follow one bug from start to finish. Here is a program with two separate problems. Read it first, and try to find them before you read on.

def print_header():
    print("Sales report")
    printLIne()
 
def print_line():
    print("============")
 
def print_footer():
    print("Thank you")
 
print_header()
print("Total: 42")
print_footer

Running it prints the first line and then stops with this error:

Sales report
Traceback (most recent call last):
  File "/path/to/main.py", line 11, in <module>
    print_header()
    ~~~~~~~~~~~~^^
  File "/path/to/main.py", line 3, in print_header
    printLIne()
    ^^^^^^^^^
NameError: name 'printLIne' is not defined. Did you mean: 'print_line'?

The message says that the name printLIne does not exist. The function is called print_line, with a lower case l in line. The capital I in printLIne looks almost like a lower case l on screen, which is why this kind of bug is hard to spot by eye. Python's hint points at the right name. Fix the spelling and run again. The path in your traceback will show where your file is saved.

The second problem is not reported at all. print_footer is defined, but the last line names it without brackets. The program runs without error, and the line Thank you never prints. You find this kind of bug by reading the output and comparing it with what you expected. The expected output had a Thank you line, and it is missing. Change the last line to print_footer() and the line appears.

After both fixes the output is:

Sales report
============
Total: 42
Thank you

The ============ line comes from print_header, which calls print_line(). That call was already in the code, so the spelling fix is the only change the header needs.

This three-step pattern is the one to follow when a program misbehaves. Fix errors the interpreter names, starting from the top. Then compare the real output with the output you expected, line by line. Most bugs in functions are a spelling problem, a missing call, or a call in the wrong place.

Variations and edge cases

A function name can be reused for a value. greet = "hi" replaces the function with a string, and calling greet() then fails with TypeError: 'str' object is not callable. A name holds one thing at a time, so avoid reusing function names for variables.

A function body may be empty, but Python needs something in it. Write pass as a placeholder. The word pass does nothing, and it lets the file run while you plan. An empty body with no pass gives the IndentationError shown above.

A function can call itself. This is called recursion, and it is covered in the recursion lesson. For now, know that a function calling its own name is legal. Only the danger of a function calling itself without end deserves a warning, and you will meet it later.

A function can be defined inside another function. The inner one exists only while the outer one runs. This is legal and sometimes useful, and it is a difference from Java, where a method cannot be placed inside another method. The scope lesson shows when this helps.

A function with many lines is not wrong, but it is a sign that the function may be doing more than one job. If a function is longer than a screen, look for a good place to split it.

Interview-style questions

An interviewer might ask, "What is the difference between defining a function and calling it?" A strong answer uses the card and cook picture. Defining stores the steps as an object under a name. Calling runs them, and it can happen many times from many places.

They might also ask, "Why do we split code into functions?" Give the four reasons: no repetition, readability, testing and change. Add one concrete example from your own code.

A third question is, "What happens if a function is never called?" The answer is that its body is never executed. Only a call runs a function's body. Lines outside any function run in order from the first line to the last.

Real-world uses

Every app you have used is built from functions. A login form checks the password with one function, shows an error with another and moves to the home page with a third. A game's main loop calls update_player, draw_screen and check_collisions many times a second. A bank program calls calculate_interest at the end of each month.

In professional code, function names are how teams talk. A reviewer reading send_receipt(order) knows what the line does, and can open the function only if they doubt its details. Good function names reduce the number of lines a team needs to read.

Practice

  1. Write a function print_stars() that prints a line of 10 stars, then call it three times. Predict the output before you run it.

Show the answer

def print_stars():
    print("**********")
 
print_stars()
print_stars()
print_stars()

The output is three lines of ten stars each. Each call runs the body once.

  1. Write print_banner() that prints your name between two lines of 20 dashes. Make it call a separate line() function for the dashes, so that line is used twice.

Show the answer

def line():
    print("--------------------")
 
def print_banner():
    line()
    print("Asha")
    line()
 
print_banner()

print_banner calls line twice, and the last line calls print_banner once.

  1. Remove the colon from def greet(): in the first program and run it. Write down the exact error message. Then put the colon back.

Show the answer

The message is SyntaxError: expected ':'. Adding the colon back fixes it.

  1. Write a function print_line() that prints ForgeStack and call it from a second function print_twice(). Then call print_twice() at the bottom of the file. Predict how many lines print.

Show the answer

Two lines print, both ForgeStack. Inside print_twice, write print_line() twice. Each call prints one line, and the last line calls print_twice once.

  1. Write a program with a function draw_rule() that prints ===== and a function draw_frame() that calls draw_rule(), prints Inside, and calls draw_rule() again. Call draw_frame() at the bottom. Write the exact output.

Show the answer

=====
Inside
=====

draw_frame calls draw_rule first, prints Inside, then calls draw_rule again.

  1. Predict the output of this program, then check it:
def a():
    print("A")
    b()
 
def b():
    print("B")
 
a()
b()
print("end")

Show the answer

A
B
B
end

The first call runs a, which prints A and then calls b, which prints B. The second call runs b directly, which prints a second B. The last line is end.

  1. A student writes def print_report(): and calls it as printreport(). Describe the error and how to fix it.

Show the answer

Python says NameError: name 'printreport' is not defined. Did you mean: 'print_report'?. Python is case sensitive, and the call uses a different spelling from the definition. Change the call to print_report().

  1. Explain in two sentences why the body of a function is not copied each time the function is called.

Show the answer

The body is stored once, in the function object. A call records where the program is, runs the stored body, and then the program returns to the saved place.

  1. Write a function print_divider() that prints a line of 30 equal signs, and use it between two headings. Count how many times the function appears in the source and how many times it runs.

Show the answer

The function appears once in the source. If it is called between two headings, it runs once. A function written once can run many times, and that is the reason functions exist.

  1. Refactor this code so that the repeated pair of lines becomes one function. The original prints Name: Asha, Age: 20, Name: Ravi, Age: 31.
print("Name: Asha")
print("Age: 20")
print("Name: Ravi")
print("Age: 31")

Show the answer

def show_person(name, age):
    print("Name: " + name)
    print("Age: " + str(age))
 
show_person("Asha", 20)
show_person("Ravi", 31)

The solution uses parameters, which the next lesson covers. If you wrote the four-line version with no parameters, that is also correct for a first draft.

What you now know

  • A function is a named block of code that does one job. A definition with def stores the steps, and a call runs them.
  • The header def name(): has parts: the keyword def, the name, the parentheses for parameters and a colon. The body is indented.
  • Calls can nest: one function can call another, and the caller waits until the called function returns.
  • A definition must run before a call to it. Inside one file, the order of calls matters.
  • Splitting code into functions gives no repetition, readability, testing and easy change.
  • The common errors are SyntaxError: expected ':', IndentationError: expected an indented block, NameError: name ... is not defined, and a silent error where a function name is written without brackets.
Practice this topic: coding problems for Functions and Scope →

Stuck? Ask the tutor

Ask about anything in this lesson. Answers are short and use simple words.

Sign in to ask the tutor.