Writing functions

def, calling, and why subprograms help.

F4.1Functions and structured codeGCSE12 min

Covers OCR J277 2.2.3 Additional programming techniques · AQA 8525 3.2.10 Structured programming and subroutines (procedures and functions) · Edexcel 1CP2 1.1.2 Benefits of subprograms · Edexcel 1CP2 6.6.2 Writing functions and procedures

Do this lesson in the simulator

You have been calling functions since lesson F1.3: print, forward, distance. Now you write your own. A function is a named block of code you can run whenever you like, as often as you like, by calling its name. Exams call it a subprogram.

Defining a function

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

def report():
    x, y = position()
    print(f"at x={x} y={y}, wall in {distance()} cm")

report()
forward(60, distance=20)
report()

Run this in the simulator

def report(): defines a function called report. The indented block is its body, and nothing in it runs yet. Defining is like writing a recipe: nothing is cooked. report() calls it, and only then does the body run. Here it is called twice, so the report prints twice, and you wrote it once.

Define first, then call

Python reads a program top to bottom, so a function must be defined before the line that calls it runs:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

signal()

def signal():
    led("red")
    tone(880, 0.2)
    led("off")

Run this in the simulator

NameError: name 'signal' is not defined. Move the call below the def and run again. This is why programs usually put all their functions near the top, and the main steps underneath.

What happens when a function is called

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

def signal():
    print("  signal starts")
    led("red")
    tone(880, 0.2)
    led("off")
    print("  signal ends")

print("before")
signal()
print("between")
signal()
print("after")

Run this in the simulator

Watch the order of the lines in the console. At each call, the program jumps into the function, runs its body, then comes back to the line after the call. Press Debug and step through it to see the jumps happen line by line.

Time runs down the page. At each call to signal the program jumps into the function's body, runs it, then comes back to the line after the callmain programinside signal()time runs down the pageprint("before")signal()print(" signal starts")led("red")tone(880, 0.2)led("off")print(" signal ends")jumps inwaits herecomes backprint("between")signal()the same 5 lines againjumps incomes backprint("after")
Each call jumps into the body and comes back to the next line of the main program. The body is written once but runs twice, so the console shows its two lines twice, in between "before", "between" and "after".

A function can call other functions

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

def signal():
    led("red")
    tone(880, 0.2)
    led("off")

def side():
    forward(60, distance=20)
    signal()
    turn_right(30, angle=90)

side()
side()
side()
side()

Run this in the simulator

side uses signal, and the main program uses side. Each function is small and does one job, and the four side() calls read almost like English: drive a square, signalling at each corner.

The main program calls side four times; side calls forward, signal and turn_right; signal calls led, tone and ledmain programside()calls it 4 timesforward(...)signal()turn_right(...)led("red")tone(880, 0.2)led("off")a function you wrotea robot command
Read the layers from the top: the main program only knows side, and side only knows signal and two robot commands. Each side() runs signal() once, so the square plays its note 4 times, from one note written in one place.

Why write functions?

  • No repetition. The signal is written once. Change it once and every corner changes.
  • Names explain. side() says what four lines do.
  • Small pieces are easier to test. You can run signal() on its own until it is right, then build on it.
  • Teams can split the work. One person writes signal, another writes side, as long as they agree what each one does.

Task: signal at the corners

Write a function signal() that turns the LED red, plays a short note, and turns the LED off. Then drive a square of 25 cm sides, calling signal() at every corner. Call your function; do not repeat its lines.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

def signal():
    led("red")

forward(60, distance=25)
turn_right(30, angle=90)

Challenges

  1. Write siren() that alternates two notes four times, and call it at the start and the end of a drive.
  2. Put the four side() calls inside a function square(), and call square() twice.
  3. What happens if you call a function inside itself? Try it with a function that only prints, and read the error.

Past paper questions on this

Real exam questions that test this, each worked through with a program you can run.