Note - This Unit has an optional Lesson at the end of it which requires students to have access to the code they've written for previous Lessons. If you would like to do this optional Lesson, have students save their work in a text editor. Alternatively, students can create a Quorum account and save their projects to the website.
In this lesson students will learn how to create User Interface (UI) elements and add event-handlers to a program. Students also explore some common errors that come up in event-driven programming and will learn some important skills for debugging programs.
Students will be able to:
Most modern applications are interactive, responding to when users press a key on a keyboard, click buttons, type in a text-box, tilt the screen, swipe between screens, etc. In every instance, the user's action is generating some kind of event and the program responds by running an associated block of code. Programming a modern application is therefore typically an exercise in creating a user interface and then defining what will happen when the user interacts with that interface.
The "event-driven" mindset of programming can take a little getting used to. Often when learning, you write sequential programs that run from the start (usually the first line of the program) to the end, or to some point when the program terminates. In an event-driven program your code must always be ready to respond to user events, like clicking a button, which may happen at any time, or not at all. More complex event-driven programs require interplay and coordination between so-called "event handlers" - which are actions that the programmer writes, but are triggered by the system in response to certain events. This lesson is a first step toward getting into this mindset.
Modern programming is often event-driven rather than sequential. Sequential programs start at a beginning point and progress to the end point in a way that can be perfectly predicted when the program begins running. Event-driven programs on the other hand do not progress in a predictable order. User-generated events (e.g. mouse clicks, button press, key presses, etc.) are each handled individually. For example, a program may have two buttons, one to start a timer and one to stop the timer. In the program's code each button would have a different block of code to implement the separate and different action that the user expects the button to produce. Event-driven programs like these are dynamic, but also bring challenges since you don't know the order in which user-events may occur. This can lead to unpredictable program execution and another set of challenges.
Ask students to think of a favorite app and make a quick list of everything in that app that they would "interact" with as a user. Then have your students write down one action-and-reaction of the app; one thing you do, and how the app responds. Likely events will include things like:
Modern apps are interactive because they can respond to this and other forms of user input (i.e., human-generated events). We may not understand all the technical details yet, but it seems clear that most applications we use respond to events of some kind. Whether we're clicking a button or pressing a key, the computer is sensing events that we generate in order to determine how the application should run. Today, we're going to start exploring how event-driven programming makes this possible.
Technical knowledge of how modern applications work is not necessary to run this discussion, and the conversation itself should avoid being overly technical. For now, the point is to get the language of events out in the open. Apps have elements on the screen that you can interact with (i.e. cause user-generated events) and respond to these events in various ways. You want to be on the lookout for types of events we can program with like: mouse click or movement, typing keys on the keyboard, etc. in combination with types of screen elements you can perform those actions on like: buttons, menus, text fields, images, etc.
For this activity students will be using the Quorum Turtle Module within the Quorum Game Engine to experience "Event-Driven Programming" first hand. Students will learn the common types of errors that come up in programming and how to find and fix those problems using a technique called "Debugging." Understanding that debugging is part of the problem solving process is an important step in becoming a better computer programmer.
The Quorum Game Engine (QGE) creates an environment for events and event listeners. The Quorum Game Engine (QGE) looks, on the programmers side, like a simple preset template. It is actually supported by hundreds - if not thousands - of files (called "classes") in the Quorum Standard Libraries which run in the background. Although we call it a "game" engine, this engine can be used to create a variety of event-driven programs seen on the screens of computers, tablets, mobile phones, etc.
Quorum Game Engine apps work by adding code to respond to certain events that occur in a program. It's a way of saying "Hey! Something just happened!" Your code can then respond to each of these events. Collectively, the coding tasks involved in making your app respond to events by triggering actions are called Event Handlers. Any user input - such as clicking buttons, swiping the screen, tilting the device, etc. are "events." In this lesson we will have our program respond to a common form of user input - the keyboard - using Keyboard Events (if a user pushes a specified button, the program will execute the associated block of code).
We can use the Quorum Turtle Module that was introduced in Unit 3 to learn event-driven programming.
In order to make the Quorum Turtle Module an Event Driven Program, we need to add some code to tell it when and how to respond to certain events - in this cause user input from the keyboard. The template below provides a layout that we can build from.
At the top of the code above, notice the use Libraries.Interface.Events.KeyboardEvent and use Libraries.Interface.Events.KeyboardListener. Each of these lines makes it possible for you to use a specified file (called a class) in Quorum Programming Language's Standard Libraries.
In order for us to make our program an "Event Driven Program," we need to use the two classes - KeyboardEvent and KeyboardListener. The KeyboardEvent class allows the programmer to create an "action" that can make use of the keyboard input. We use the KeyboardListener class to have the program itself keep track of which keys are pressed or released on the keyboard.
Because we have included the KeyboardEvent and KeyboardListener classes the action PressedKey(KeyboardEvent event) becomes available for us to use in our program. Since it is an action with a parameter, we need to specify the type of parameter this action takes (KeyboardEvent) and give the parameter a name (event). In this case the KeyboardEvent is the type of parameter, and event is the name for the KeyboardEvent. Since this is a separate action we will need to use an end statement to specify which part of the code is associated with this action.
In the PressedKey action code block, we use the "if-statement structure" to control the "KeyboardEvent - event". The "if-statement structure" will be explained in detail throughout this unit. For now, we will just describe what each line of the "if-statement structure" does to our program:
This block of code is essential for us to transform the Quorum Turtle Module into an "Event Driven Program". In the following activities, we will be adding lines of code below each "elseif" statement which will give our turtle options to move in different directions in response to specific keyboard events (such as the UP arrow being pressed).
Here are the commands that the turtle can follow:
In the PressedKey action, each "elseif" statement corresponds to a specific key being pressed on the keyboard. Remember that the turtle will turn based on the direction in which the turtle is facing at the time - not based of the direction of the screen. Here is an example of what the code block should look like in the "event" that the LEFT arrow key is pressed.
elseif event:keyCode = event:LEFT TurnLeft() MoveForward()
After you have added in all of the missing code blocks under each "elseif" statement, try running your program. Does each key press work in the way you predicted that it would? If not, don't worry, this is common in computer programming and leads us to the topic of "Debugging" - the art of finding and fixing problems in your code.
Debugging is a skill and an art. With practice, you'll learn how to write relatively bug-free code and more importantly you'll learn about yourself and the kinds of errors you typically make. But learning how to debug takes some time and getting used to, and you will learn about the different kinds of things that can go wrong when you write programs.
Remind students that:
In the next few sections we'll practice debugging a few common types of errors. They generally fall in two categories:
Programming and debugging is like getting dressed up to go out. You put on some clothes that you think will look good but then you have to look in the mirror, make some adjustments and decisions, maybe even realize you need to go a different direction entirely, and so on -- you are debugging your outfit. Writing a program initially is like throwing on some clothes, and running the program is like looking in the mirror for the first time. You do it to see what it looks like, knowing that you're going to have to make some adjustments. But looking in the mirror frequently to see what everything looks like together actually speeds up the process. Getting ready to go out, putting on makeup or combing your hair without looking in the mirror would not only slow things down, it's foolish. The Run. Test. Debug. pattern of behavior is part of the programming process, just like using a mirror is part of making yourself presentable.
There is (are) syntax error(s) in the Quorum Turtle Module code block below. Can you find them? Remember a Syntax error is when your computer can't understand something, like a misspelled word or a missing end statement.
use Libraries.Curriculum.TurtleProgram.TurtleGame use Libraries.Interface.Events.KeyboardEvent use Libraries.Interface.Events.KeyboardListener class Main is TurtleGame action Main StartGame() end action TurtleCommands end action PressedKey(KeyboardEvent event) if event:keyCode = event:UP Forward() elseif event:keyCode = event:LEFT elseif event:keyCode = evnt:RIGHT elseif event:keyCode = event:DOWN end end
If you try to build and run this code, the IDE will find the errors, and display the lines where it "thinks" that the error occurred in the output area. However, the computer doesn't recognize which block of code is missing the corresponding "end statement." It only sees that overall there is a missing "end statement" and applies that "error" to the end of your program. With experience in debugging you will eventually get used to how the computer logically analyzes your code and you will quickly be able to pinpoint your syntax errors by remembering the pattern of error messages.
To understand a new piece of code good programmers often try to first make a prediction about what will happen before running the program. By forcing yourself to make a prediction first (it doesn't matter if you are right or not) you are immediately alerted to any unusual or unexpected behavior and you can ask yourself "Huh? Why did it do that? Was that supposed to happen?". It might not be an error, but you gain invaluable insight and actually learn faster.
Predict: For the code below, what will happen when the DOWN arrow key is pressed?
Here are some options to think about:
Observe: Once you have made a prediction, run the program to observe what happens.
Reflect: Was your prediction correct? If not what about your mental model might need to change? Talk about it with a classmate and experiment with the code to make sure you understand what is happening.
Sometimes you can write a program that generates no errors but still does not work as intended. This is the result of logical errors in your code, and making a prediction can help find these kind of bugs too.
Today we were actually introduced to two tools that will help us build increasingly complex applications. The first was Quorum Game Engine, and hopefully it was quickly apparent how powerful this tool is for creating appealing and intuitive user interfaces without cluttering up your code. The second tool was KeyboardEvent handling which is the one of the actions that can handle user input elements in Quorum programming language.
Event-driven programs are an important concept in programming, but we've just gotten our feet wet. In the next lesson we'll learn a little more of the basic knowledge that is required to write an Event-Driven Program from scratch!