← Teacher guide

Events

Students write programs that wait for clicks, keys and timers, and run a function (a callback) each time something happens.

Python functions and events · Interaction · about 50 minutes · Open the student lesson

Classroom resources

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.

Students will be able to

Timing

Predict and Run 10 min · Investigate 15 min · Modify 10 min · Make 10 min · Counter 5 min

Before class

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.

Running the lesson

  1. Predict: the program reaches its last line, then waits. Ask what happens on a click, and why the program does not just end.
  2. Say it plainly: onscreenclick(stamp) means 'when someone clicks, run stamp'. Nothing runs until the event happens.
  3. Investigate: the bug task is the most common mistake. stamp() with brackets runs the function now, once, instead of handing it over.
  4. Modify: change what the function does, not the event line. That separation is the point.
  5. Make: three small functions, three onkey lines, then listen() and mainloop(). Remind students to click the picture before pressing keys.
  6. Counter: global score lets the function change the score made outside it. Read the Behind the code note together.

The hard part (on purpose)

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.

When students get stuck

What you will seeA question to askThe 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.

Answers to the checks

  1. Predict: What happens when you click on the picture?
    An orange dot appears at the spot you clicked. Each click runs the stamp function with the position of the click.
  2. Match the lines: Match each line with what it does.
    onscreenclick(stamp) → B. runs stamp each time the picture is clicked; onkey(go_up, "Up") → C. runs go_up each time the Up arrow is pressed; ontimer(step, 50) → D. runs step once, after 50 milliseconds; mainloop() → A. keeps the program waiting for events
  3. Count the presses: The program above is running. You press the Up arrow 5 times. How many times does go_up run?
    5
    The handler runs once for every press: it is called for you each time the event happens.
  4. Spot the bug: This program should stamp a dot where you click, but it stops with an error. Click the wrong line.
    line 7
    stamp() with brackets runs the function straight away, before any click. Handing it over needs the name only: onscreenclick(stamp).
  5. Mix it up: The student clicks the screen 5 times. What is score afterwards?
    5
    Each click calls add_point once, and each call adds 1. Because of global score, the change is kept between clicks, so score is 5.

Solutions

One possible solution for each task. Other correct programs are fine.

Modify › Restyle the stamp

from turtle import *

speed(0)
penup()


def stamp(x, y):
    goto(x, y)
    dot(50, "purple")


onscreenclick(stamp)
listen()
mainloop()

Modify › Stamp a square

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()

Make

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()

Count the clicks

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 and support

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.

Exit ticket

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.

What each step is for

Where it leads

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.