Students write programs that wait for clicks, keys and timers, and run a function (a callback) each time something happens.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict and Run 10 min · Investigate 15 min · Modify 10 min · Make 10 min · Counter 5 min
Until now programs ran top to bottom and stopped. An event-driven program sets up what should happen, then waits (mainloop()). A callback is a function you hand over by name, which the computer runs for you later, every time the event happens. Try the stamp program: click the picture, then press Stop. Keys only work after the picture has been clicked once.
Handing a function over (no brackets) instead of calling it. When the error appears, ask whether the line runs the function now or hands it over for later.
| What you will see | A question to ask | The fix |
|---|---|---|
| An error on the onscreenclick line: stamp() missing 2 required positional arguments. | Does the line hand over the function's name, or call it? | Remove the brackets, onscreenclick(stamp). The computer adds the click position when it calls it. |
| Nothing happens when keys are pressed. | Have you clicked the picture since pressing Run? Is listen() there? | Click the picture first, and make sure listen() and mainloop() are the last lines. |
| An UnboundLocalError (or 'referenced before assignment') when the score changes. | Which variables does this function change that were made outside it? | Add global score as the first line inside the function. |
One possible solution for each task. Other correct programs are fine.
from turtle import *
speed(0)
penup()
def stamp(x, y):
goto(x, y)
dot(50, "purple")
onscreenclick(stamp)
listen()
mainloop()
from turtle import *
speed(0)
penup()
def stamp(x, y):
goto(x, y)
pendown()
for i in range(4):
forward(30)
right(90)
penup()
onscreenclick(stamp)
listen()
mainloop()
from turtle import *
speed(0)
def go_up():
forward(20)
def turn_left():
left(30)
def turn_right():
right(30)
onkey(go_up, "Up")
onkey(turn_left, "Left")
onkey(turn_right, "Right")
listen()
mainloop()
from turtle import *
hideturtle()
score = 0
penup()
goto(-20, 0)
def show():
clear()
write(score, False, "left", ("Arial", 40, "normal"))
def add_point(x, y):
global score
score = score + 5
show()
def reset():
global score
score = 0
show()
def tick():
global score
score = score + 1
show()
ontimer(tick, 1000)
show()
onscreenclick(add_point)
onkey(reset, "r")
ontimer(tick, 1000)
listen()
mainloop()
Stretch: Add a timer that moves the turtle forward every half second, so it drives by itself while the keys steer it.
Support: Give students the three key functions already written and ask them only to connect each one with an onkey line.
What is the difference between onscreenclick(stamp) and onscreenclick(stamp())?
onscreenclick(stamp) hands the function over to run on each click. stamp() with brackets runs it straight away, once, which is wrong here.
Next lesson builds a button from scratch: a drawn rectangle plus a click check. Every app waits for events: taps, keys and timers. Class ideas: a stamp painting the class designs together; steering a turtle through a maze drawn on paper; a timer-based animation.