All 2.4 26 min read 10 question quiz 19 exam marks

Functions and Structure

Writing your own functions, parameters and return values, scope, default arguments, and structuring a program that stays readable at 300 lines.

Defining and calling

Python
def greet(name):
    print(f"Hello, {name}!")

greet("Aisha")
greet("Ben")
  • def starts the definition
  • name is a parameter, a value the function needs
  • "Aisha" is an argument, the actual value passed in

Returning a value

Python
def area_of_rectangle(width, height):
    return width * height

a = area_of_rectangle(5, 3)
print(a)                          # 15
print(area_of_rectangle(2, 8))    # 16

A function that returns gives a value back so it can be used in a calculation, stored, or printed. A function that only prints has thrown the answer away.

print is not return

print shows something to the user. return hands a value back to the program. A function that calculates something should almost always return it.

Multiple return values

Python
def stats(numbers):
    return min(numbers), max(numbers), sum(numbers) / len(numbers)

lowest, highest, mean = stats([4, 8, 15, 16, 23])
print(lowest, highest, mean)

Default and named arguments

Python
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Aisha")                      # Hello, Aisha!
greet("Ben", "Good morning")        # Good morning, Ben!
greet(greeting="Hi", name="Chloe")  # Hi, Chloe!
A function takes values in and hands a value backA function drawn as a machine. The code defines area with two parameters, w and h, and returns w times h. The line x equals area of 3, 4 calls it: the two arguments, 3 and 4, drop into the machine through the hopper, and the result, 12, comes out of the chute and is stored in x, so print of x shows 12. Parameters are the names the function uses for what it is given, and arguments are the actual values supplied when it is called. Below, a procedure and a function are compared: a procedure does a job, such as printing a greeting, and gives nothing back, while a function hands a value back to the caller with return.area.py1def area(w, h):2    return w * h34x = area(3, 4)5print(x)output12A function is a machinearea(w, h)34arguments in12returnedw and h:parametersProceduredef hello():    print("Hi")does a job, givesnothing backFunctiondef double(n):    return n * 2hands a value backwith return1234
  1. Define it once with def, naming the parameters it will be given.
  2. Call it with arguments. They fill the parameters, w = 3 and h = 4.
  3. return hands the result back to the line that called it.
  4. A procedure does a job. A function also gives a value back.
Parameters are the names in the definition. Arguments are the values in the call.

Scope

A local variable exists only inside the function that created it.

Python
def calculate():
    result = 42          # local
    return result

calculate()
print(result)            # NameError, result does not exist out here

A global variable exists everywhere.

Python
TAX_RATE = 0.2           # global constant

def add_tax(amount):
    return amount * (1 + TAX_RATE)

Reading a global is fine. Changing one from inside a function requires the global keyword and is almost always a sign the design could be better.

Python
score = 0

def add_point():
    global score         # avoid this where you can
    score += 1

Better:

Python
def add_point(score):
    return score + 1

score = add_point(score)

Why local is better

  • Nothing outside the function can change it by accident
  • Two functions can use the same name without interfering
  • The function's behaviour depends only on what you pass in, so it is far easier to test
Local and global variables as the rooms of a houseScope shown as a house. The whole program is the house, and the variable score equals 10, declared in the hallway, is global: every room, which is to say every function, can read it. Each function is a room with its own local variables on the wall: bonus has extra equals 5 and reset has temp equals 0. A local variable exists only inside its own room and is gone when the function ends. The code on the right defines bonus, which prints score plus extra, giving 15, and then tries to print extra from outside, which fails with a NameError because extra is not visible out there. In the picture a person standing outside the house asks for extra and is refused.The program: global scopescore = 10global: every function can read itbonus()extra = 5local: only inthis roomreset()temp = 0local: only inthis roomprint(extra)NameErrorthe room's variables are not visible from outsidescope.py1score = 10          # global23def bonus():4    extra = 5       # local5    print(score + extra)67bonus()             # 158print(extra)        # erroroutput15NameError: name 'extra' is not defineda function can read a global variablea local variable dies when the function ends123
  1. The program is the house. A variable made in the hallway is global, and any function can read it.
  2. Each function is a room. Variables made inside it are local and live only in that room.
  3. Outside code cannot see a room's local variables: asking for one gives a NameError.
Make variables local by default. Reach for a global only when many functions truly share it.

Structuring a program

One function, one job

Python
def load_scores(filename):
    ...

def calculate_average(scores):
    ...

def find_top_student(scores):
    ...

def display_report(scores):
    ...

def main():
    scores = load_scores("scores.txt")
    display_report(scores)

main()

The main() function at the bottom reads like a summary of the program. That is the goal.

A complete example

Python
def get_valid_number(prompt, low, high):
    # Keep asking until the answer is a whole number in range
    while True:
        entry = input(prompt).strip()
        if entry.lstrip("-").isdigit():
            value = int(entry)
            if low <= value <= high:
                return value
        print(f"Please enter a whole number between {low} and {high}.")


def grade_for(mark):
    if mark >= 70:
        return "Distinction"
    elif mark >= 50:
        return "Merit"
    elif mark >= 40:
        return "Pass"
    return "Fail"


def summarise(marks):
    return {
        "count": len(marks),
        "mean": sum(marks) / len(marks),
        "highest": max(marks),
        "lowest": min(marks),
    }


def main():
    marks = []
    how_many = get_valid_number("How many marks? ", 1, 30)

    for i in range(how_many):
        mark = get_valid_number(f"Mark {i + 1}: ", 0, 100)
        marks.append(mark)

    stats = summarise(marks)
    print(f"\n{stats['count']} marks entered")
    print(f"Mean:    {stats['mean']:.1f} ({grade_for(stats['mean'])})")
    print(f"Highest: {stats['highest']} ({grade_for(stats['highest'])})")
    print(f"Lowest:  {stats['lowest']} ({grade_for(stats['lowest'])})")


main()

Every function does one thing, is named after what it does, and can be tested on its own. That is what makes a program maintainable.

Docstrings

Python
def area_of_circle(radius):
    '''Return the area of a circle with the given radius.'''
    return 3.14159 * radius ** 2

help(area_of_circle)

Key terms you must be able to define

Function
A named block of code that performs a task and can be called from anywhere.
Parameter
A variable in a function definition that receives a value when it is called.
Argument
The actual value passed to a function when it is called.
return
A statement that sends a value back to the code that called the function.
Local variable
A variable that exists only within the function where it was created.
Global variable
A variable accessible from anywhere in the program.
Scope
The region of a program in which a variable can be accessed.
Default argument
A parameter given a value in the definition, used when no argument is supplied.
Docstring
A string at the top of a function describing what it does.

Flashcards

Say the definition out loud before you flip the card. Retrieving it from memory is what builds recall, reading it again is not.

DefineFunction
AnswerA named block of code that performs a task and can be called from anywhere.
DefineParameter
AnswerA variable in a function definition that receives a value when it is called.
DefineArgument
AnswerThe actual value passed to a function when it is called.
Definereturn
AnswerA statement that sends a value back to the code that called the function.
DefineLocal variable
AnswerA variable that exists only within the function where it was created.
DefineGlobal variable
AnswerA variable accessible from anywhere in the program.
DefineScope
AnswerThe region of a program in which a variable can be accessed.
DefineDefault argument
AnswerA parameter given a value in the definition, used when no argument is supplied.

Reach the top grade on this topic

  • Write functions that return rather than print, so results can be reused
  • Give every function one job and a name that says exactly what that job is
  • Keep variables local, and pass values in as parameters instead of using globals
  • Write a main() function that reads like a summary of the whole program
  • Add a docstring to any function whose purpose is not obvious from its name

Mistakes that cost marks here

Avoid these
  • Printing inside a function that should return, so the value cannot be reused.
  • Forgetting return entirely, so the function silently gives back None.
  • Using global variables to pass values around instead of parameters.
  • Writing one function that does five things, which then cannot be tested or reused.
  • Calling a function before defining it.
Fun fact

A function that does one thing and has a name that says what it does is the single most powerful tool in programming. Almost every difficult codebase in the world got that way because someone stopped doing this.

Knowledge check

0 of 10 answered
1What keyword defines a function in Python?
2What is the difference between a parameter and an argument?
3What does a function return if it has no return statement?
4Why should a calculation function return rather than print?
5What is a local variable?
6In def greet(name, greeting="Hello"), what is greeting?
7What happens if you access a local variable outside its function?
8Why are globals usually avoided?
9What does return min(x), max(x) do?
10What is a docstring?
Score 0 / 10

Exam-style questions

Five written questions in the style of the real paper. Write a full answer, then let the marker check it against the mark scheme.

19 marks
1Explain the difference between print and return in a function.3 marks
Explain

Mark scheme0 / 3
  • Lprint displays a value to the user
  • Lreturn sends a value back to the code that called the function
  • LA returned value can be stored or used again, a printed value cannot
Model answer

The print function displays a value on the screen for the user to read, and once it has been displayed the program has no further access to it. The return statement sends a value back to whatever code called the function, so it can be stored in a variable, passed into another function or used in a further calculation. A function that calculates something should almost always return it, because a function that only prints has effectively thrown the result away and cannot be used as a building block anywhere else in the program.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
2Write a function called convert_to_celsius that takes a temperature in Fahrenheit as a parameter and returns the equivalent in Celsius. The formula is (F - 32) multiplied by 5 divided by 9.4 marks
Write

Mark scheme0 / 4
  • LUses def with a suitable name and a parameter
  • LApplies the subtraction of 32 first
  • LMultiplies by 5 and divides by 9
  • LReturns the result rather than printing it
Model answer

def convert_to_celsius(fahrenheit): return (fahrenheit - 32) * 5 / 9 print(convert_to_celsius(212)) # 100.0 The brackets around the subtraction are essential, because without them Python would multiply by 5 before subtracting 32 and give the wrong answer. The function returns the value rather than printing it, so the result can be stored, rounded, or used in a further calculation by whatever called it.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
3Explain what is meant by the scope of a variable and why local variables are usually preferred.4 marks
Explain

Mark scheme0 / 4
  • LScope is the region of the program where a variable can be accessed
  • LA local variable exists only inside its function
  • LA global variable can be accessed from anywhere
  • LLocal variables cannot be changed accidentally elsewhere, so bugs are easier to avoid
Model answer

The scope of a variable is the part of the program in which that variable can be accessed. A local variable is created inside a function and exists only while that function is running, so nothing outside can see or alter it. A global variable is created outside all functions and can be read and modified from anywhere in the program. Local variables are usually preferred because their limited scope means no other part of the program can change them by accident, which removes a very common and difficult to trace source of bugs. It also means two different functions can safely use the same variable name without interfering, and it makes each function far easier to test, because its behaviour depends only on the arguments passed into it rather than on the state of the rest of the program.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
4Explain two benefits of splitting a program into several functions.4 marks
Explain

Mark scheme0 / 4
  • LCode that is needed more than once is written only once
  • LA change only needs to be made in one place
  • LEach function can be tested on its own
  • LThe program becomes easier to read and understand
Model answer

The first benefit is the removal of duplication. Code that is needed in several places can be written once as a function and called wherever it is required, so the program is shorter, and crucially any correction or improvement only has to be made in one place rather than being repeated in every copy, which removes the risk of leaving an old version behind. The second benefit is that a program built from small functions is far easier to develop, test and read. Each function does one clearly defined job and can be tested independently with a range of inputs until it is known to be correct, and the main program then reads as a sequence of well named steps that describe what the program does without the reader having to follow every line of detail.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
5Write a function that takes a list of numbers and returns the mean, and explain why it should return rather than print the result.4 marks
Write

Mark scheme0 / 4
  • LDefines a function with a list parameter
  • LCalculates the total and divides by the number of items
  • LUses return
  • LExplains that returning allows the value to be reused elsewhere
Model answer

def mean(numbers): return sum(numbers) / len(numbers) average = mean([4, 8, 15, 16, 23]) print(f"The mean is {average:.2f}") The function should return the value rather than printing it because returning keeps the function general and reusable. The calling code can then decide what to do with the answer: display it, round it, compare it with another average, store it in a file or use it in a further calculation. A function that printed the mean directly would be locked to one use and could not be built on, and it would also be far harder to test automatically, because a test can compare a returned value against an expected one but cannot easily check what was printed.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.
Machine mark 0 / 19