Now I'm going to make another change to the cat program. We're going to change it so that when we press the space key the cat resets back to the edge of the box. So, this will be more practice with using the How to Design World's Recipe and more practice with using a well structured design to work through making a change to that design. Another technical point we'll see in this recipe is how to use the on-key option to Big Bang and how to template a function that operates on what's called a large enumeration. And that will be something that will be useful for on-key options as well as on-mouse options that you'll see later. What we're starting with here is the cat program from the last video. And what we've got from the end of that video is we've changed the cat program so that the cat walks across the screen more quickly, which is nice. What I want to do now is go back to one of the original goals in the problem statement. Which is for this program to have the functionality that if I press the space bar, the cat jumps back to the beginning of the screen and starts walking. So you're kind of picking the kitten up, putting the kitten back at the left edge of the screen. Now, this is going to end up being a fairly simple change. But we've got this domain analysis and it's good idea to keep the domain analysis in sync with the program. So, the first thing I'm going to do is grab the domain analysis and make the required change there. In this case, there's no constants that change and there's no changing information that changes. All that changes is we're going to add one more big bang option, which is the on key option. And that allows us to give special behavior to our world program when a key on the keyboard is pressed. So, I'm going to add on key here, and now I'm going to jump over into the code. Nothing changed in the constants, so nothing changes here. Nothing changed in the changing world information, so nothing changes here. But we are going to use one more Big Bang option. And what I'm going to do is I'm going to go to the HTDW page. Go to the How to Design Worlds page. And I'm going to scroll down to get the template for world programs. And I'm just going to look at the template for the on key option. Here it is here. And I'll just copy this from here right over into my main function here. Paste it there. Now, I've got some parentheses problems here. Let me see. I'll get rid of both of those. And WS in this program is called cat, and that's a WS. And I'll decide right now that I'm going to call this function handle-key. So now that I've added that there, I've wished for this handle-key function. So, what I'm going to do is I'm going to grab the signature of it and go make a wish list entry. Here it is, let's see its cat key of event to cat reset cat to left edge when space key is pressed. And I'll make a stub handle key. And this functions takes two arguments. I'm going to talk about that a bit more in a minute, but it takes two arguments. One is the actual world state, the cat, and the other is a key event, and that's going to describe which key was pressed. This is just the stub. It'll produce 0. And I'll put bang bang bang to remind myself I still need to do this function. I updated the analysis to say that big bang needed the on key option. I updated main, so that that big bang specifies on key. And tells big bang to call a handler called handle key. And I've made the wish list entry for the handler. So, I've got the signature purpose and stub. Now I need to work on the examples. And what I'm going to do is I'm going to explain about key event while I work on the examples. This function consumes two arguments. And the first argument is a cat. It's a representation of the cat's x coordinate. So, a reasonable value for a cat might be 10. The second argument is a key event. And what key event is is it's a primitive type in racket. And it's what's called a large enumeration. There's one distinct value in key event for each of the many different keys you can press on the keyboard. So there's a distinct value for the space key, and a distinct value for the A key, and a distinct value for the one key, and a distinct value for the left arrow key. There's a lot of them. That's why it's called a large enumeration. Now, in order to make this simple, what Racket does is it uses simple strings to be those distinct values. So, the distinct value that represents that the space key was pressed is a string with a space in it. So, that's the way big bang would call handle key if the current state of the world is 10 and the space key is pressed. Now we understand key event. Now, we're back to the standard HTTF generation of examples. Well, what is handle key supposed to do if the current world state is 10 if the cat is at x coordinate 10 and the space key is pressed. Well, it's supposed to reset the cat to the left edge so that should produce zero. Let's do another example now. What happens if we have handle key of ten, and the A key is pressed? Because, remember, we've told the user that they're supposed to set the cat back to the beginning by pressing space. But they might accidentally press something else. Well, what happens in that case is nothing's supposed to happen. The cat's supposed to stay where it is. So, that'll be 10. Now let's see. What other tests might we need? Well, you might also want to say well what happens if the cat happens to already be at zero and space key is pressed. I'll line this up this way. I'll indulge by inner Virgo. Well, if it's already at zero, and space key is pressed, it should stay at zero. You might even want to do that for this example. Which is to say, I start at zero. I press A. In that case, I should still be at zero. Now you might say, wait a minute, there's a whole bunch of possible keys. It's a very large enumeration. Do I need to test every single case? This is an example of white-box testing. What we're going to do is we're going to say to ourselves, you know, we don't need to test every single case. Because we kind of know how this function is going to work except you don't yet know how this function is going to work. So, now I have to start talking about how we template. Funcitons that operate on large enumerations. So, let's jump ahead to the template step, and then you'll see why it's okay to have used this small number of test cases. One way to get the template for a handle key function would be to go to the How to Design Worlds page. And at the bottom of the page, it includes templates for handle-key and handle-mouse, which are quite similar. Handle-key consumes a key event, and handle-mouse consumes a mouse event, which is a large enumeration describing all the possible mouse events. I'll copy it from here. And then, I'll explain how it works when we get back over to Racket. So, let's see. I've got to comment out the stub. It already happens to have the same name I'm using. That's a stroke of luck. But WS, is, in this program, world state is a CAT. So let me just, for consistency, rename WS to cat. And now, it turns out that this template happens to be right for this particular case but let's talk about why. Because it's an enumeration and a large enumeration, if you followed the normal data template rule you'd end up with a very large cond. There'd be one case in this cond for every possible key event. So, this first case says if the key is equal to space key equals is a special function that checks equality of key events. If the key is a space do this. And then, you have one if the key is an A do this, and if the key is a B do this and da da da you'd have a lot of them. But when we template a large numeration, what we're allowed to do is say look, there's going to be a small number of special cases. And then, all the other keys are going to be handled similarly. Or sometimes what happens is, if for example you're building a world program that does a text editor, there's whole groups of keys that are handled similarly. All the keys that insert text are handled similarly. Whereas the arrow keys are handled similarly, and so you might have larger groups than, than groups of one key and all the rest. But the basic idea here, this is how we template a large numeration, we identify the special cases and then we have an else for every thing else. So, let's see now. Completing the code against the examples and the purpose. If the key is equal to space then these two examples and the purpose, tell me that I'm supposed to produce zero. And if the key is anyting else, then these two examples and the purpose tell me that cat shouldn't change. I should just produce whatever the cat currently is. Let's test that. And now, you see why when I wrote thet est I was allowed to do it this way. I'm allowed to just test the special case space and one example of all the other cases. Because I know that I'm going to end up having this special constructure in which there are only two cases. Again, this is what's called white box testing. Where, when I write the tests, I allow myself to know something about the structure of the function. White box testing is something you'll talk more about in software engineering courses, if you take those, but this is an example of why we do it. It lets us test what a function is really doing without having to create anywhere near as elaborate a set of tests. So, let's see all my tests pass. Let me actually try running the program. Main and 0. You know, I'll try to type very loudly here. You hear whenever I press the space key, the cat is resetting back to the beginning. So just a quick summary, we kind of replayed the whole how to design worlds recipe. We, in the analysis, identified a new option to big bang. There were no changes to constants there we no changes to the data definitions. We added one new option to big bang that made us wish for a new handler. We did the signature purpose and stub for the new handler, then we went ahead and did the examples on the template. There was a special rule for templating this function, because it's a large enumeration. Most of what we did here is something we've done before. We followed the various pieces of the recipe. Really, the large enumeration rule is the only new thing we did here. What I suggest you do now is try adding another piece of functionality to this program which is to make it that whenever I click the mouse the cat goes to the current exposition of the mouse. That'll be an exercise very much like the one we just did except that instead of adding a key handler, you'll be adding a mouse handler. Have some fun with that.