Project: the patrol

A complete program built a function at a time: patrol to the wall and come home.

F4.6Functions and structured codeGCSE25 min

Do this lesson in the simulator

This is the last project of the programming foundations, and it is built the way real programs are: decomposed into functions, each piece tested before the next, with the details hidden behind good names. The robot patrols up the mat in steps, reports as it goes, stops at the wall, and then comes home by itself.

The brief

The robot patrols towards the wall in 10 cm steps, printing a report after each step, until the wall is 30 cm away or less. It says arrived and turns its light green. Then it returns to where it started, using the number of steps it took, and prints how many steps each way.

Decompose it

patrol and return
├── patrol(stop_at)             returns the number of steps
│   ├── step(n)                 drive 10 cm, print a report
│   └── repeat while the wall is further than stop_at
├── arrive()                    say arrived, light green
└── go_home(steps)              drive back the same number of steps

Three functions under the main program, and one of them uses a fourth. Each has a single job, and patrol returns the one value go_home needs.

Piece 1: one step

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

def step(n):
    """Drive one 10 cm step and report it."""
    forward(50, distance=10)
    print(f"step {n}: {distance()} cm")

step(1)
step(2)

Run this in the simulator

Test it on its own. Two calls, two report lines, and the robot moved twice. If the report looked wrong, this is the moment to fix it, while the program is five lines long.

Piece 2: the patrol

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

STOP_AT = 30          # cm from the wall

def step(n):
    """Drive one 10 cm step and report it."""
    forward(50, distance=10)
    print(f"step {n}: {distance()} cm")

def patrol(stop_at):
    """Step towards the wall until it is stop_at cm away. Returns how many steps."""
    n = 0
    while distance() > stop_at:
        n = n + 1
        step(n)
    return n

steps = patrol(STOP_AT)
print("arrived after", steps, "steps")
led("green")

Run this in the simulator

n is local to patrol, and the main program gets the count through return. Run it and check the last report says the wall is under 30 cm.

Piece 3: coming home

Going home is the patrol in reverse: the same number of steps, backwards. Write go_home(steps) yourself, test it by calling go_home(2) after two calls of step, and then put all the pieces together in the task.

Check the whole program

Read your finished program top to bottom. It should have this shape: a constant, the functions, then a short main program that reads like the brief. Almost every program you will write from now on has that shape.

  • Does each function do one job, with a docstring that says what?
  • Does any function use a global variable it could have been given as a parameter?
  • Could someone change the step size by changing one line?

Task: patrol

Build the patrol against the wall: drive in 10 cm steps while the wall is more than 30 cm away, printing step <n>: <distance> cm each time; then print arrived, turn the LED green, and be inside the green zone.

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

def step(n):
    forward(50, distance=10)
    print(f"step {n}: {distance()} cm")

# the loop, then the ending

Task: patrol and return

Decompose the whole brief into functions: patrol(stop_at) must return the number of steps, and go_home(steps) must bring the robot back. After arriving (LED green), drive home and print steps each way: <n>. The robot must end near where it started.

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

STOP_AT = 30

def step(n):
    """Drive one 10 cm step and report it."""
    forward(50, distance=10)
    print(f"step {n}: {distance()} cm")

Where next

That is the programming spine of the Foundations stage: F1 to F4. From here the modules use these tools for bigger ideas: algorithms, defensive programs and testing, and how the robot's computer works inside.

Challenges

  1. Make the step size a parameter of step, and a constant at the top.
  2. Store every distance reading in a list inside patrol, and return the list as well as the count.
  3. Add a beep_count to go_home that beeps once per step, without any global variables.