Writing Your Own
Two lines of grammar and one rule of indentation. The grammar is def, a name, brackets and a colon; the rule is that everything belonging to the function is indented under it. What catches people out is not the writing — it is remembering that writing a function and running it are two separate events.
1The anatomy of a definition
def welcome():
print('Welcome to Class 12 Computer Science')
print('Today we begin functions')
welcome()Welcome to Class 12 Computer Science Today we begin functions
def — the keyword that says “a definition follows”.
welcome — the name you are storing the code under. Same rules as a variable name.
() — where parameters go. Empty here, because this function needs nothing from the caller.
: — the colon that opens the block, exactly as it does after if and for.
def welcome():The header. Running this line stores the function under the name and moves on — it prints nothing.
print('Welcome to Class 12 Computer Science')The body, indented four spaces. Everything at this indentation belongs to the function; the first line back at the margin does not.
welcome()The call. Now the two prints run, in order, and then the program carries on from here.
2A function you never call does nothing
This is the part worth seeing rather than being told. The function below is complete and correct, and the program prints nothing from it:
def welcome():
print('this never runs')
print('The program ran, and nothing was printed by the function.')The program ran, and nothing was printed by the function.
def is a storing instruction, not a doing instruction. Python reads the header, keeps the body aside under that name, and skips past to the next line at the margin. The body is not run, not checked for sense, and not looked at again until something calls it.3Define it before you call it
Since def is what puts the name into existence, a call placed above the definition is asking for a name that does not exist yet:
greet()
def greet():
print('hello')Traceback (most recent call last):
File "order_error.py", line 1, in <module>
greet()
^^^^^
NameError: name 'greet' is not definedMove the def above the call and it works. In practice this means definitions go at the top of a program and the lines that actually do things go at the bottom — which is how nearly every Python program you meet is laid out.
def in the file has been read.# a() mentions b() before b exists — and that is fine,
# because nothing is called until the last line
def a():
b()
def b():
print('b ran')
a()b ran
4Naming a function
The rules are exactly the rules for a variable name: letters, digits and underscores, not starting with a digit, and not a keyword. The convention is lowercase_with_underscores, and the name should say what the function does:
def print_bill_header():
print('LAMBDALAB STORES')
print_bill_header()LAMBDALAB STORES
def print bill(): gives SyntaxError: expected '(' — Python read print as the whole name and then wanted the brackets, and found bill instead. Use an underscore.5The body must exist, and must be indented
def nothing():
print('x') File "empty_body.py", line 2
print('x')
^
IndentationError: expected an indented block after function definition on line 1Python is telling you it opened a block and found nothing in it. If you genuinely want a function that does nothing yet — a placeholder you will fill in later — the body is pass:
def compute_gst():
pass # to be written tomorrow
compute_gst()
print('the program still runs')the program still runs
6Several functions in one program
def stars():
print('*' * 20)
def title():
print('MARKS REPORT')
stars()
title()
stars()******************** MARKS REPORT ********************
Two definitions, three calls, and the output follows the calls rather than the definitions. This is modularity in its smallest form: two named jobs, and a main program that reads as a list of them.
7Recap
The colon opens the block and the indentation says what belongs to it, exactly as with if and for.
def stores the body under the name and moves on. A function that is never called never runs.
The name does not exist until the def has run, so calling first raises NameError. Definitions at the top, actions at the bottom.
IndentationError: expected an indented block. Use pass for a placeholder you intend to fill in.
- 1
Write
print_menu(), which prints three dishes, and call it once.Hint · Three
print()lines, all indented under the header. - 2
Write two functions,
header()andfooter(), and use them around a line of your own text.Hint · Both definitions first, then the three calls in the order you want the output.
- 3
Deliberately call a function one line above its
defand read the error.Hint ·
NameError. Worth doing once so you recognise it when it happens by accident. - 4
Write a function whose body is only
pass, call it, and check that the program still runs.Hint · Nothing is printed and nothing breaks — which is what a placeholder is for.
What is printed by a program that defines a function and never calls it?
Why does calling greet() on the line above its def raise NameError?
What does Python say about `def nothing():` with no indented body?