1 00:00:05,910 --> 00:00:08,770 Now I'm going to make another change to the cat program. 2 00:00:09,850 --> 00:00:12,794 We're going to change it so that when we press the space key the cat resets back 3 00:00:12,794 --> 00:00:18,234 to the edge of the box. So, this will be more practice with using 4 00:00:18,234 --> 00:00:22,260 the How to Design World's Recipe and more practice with using a well structured 5 00:00:22,260 --> 00:00:26,910 design to work through making a change to that design. 6 00:00:28,670 --> 00:00:32,682 Another technical point we'll see in this recipe is how to use the on-key option to 7 00:00:32,682 --> 00:00:36,458 Big Bang and how to template a function that operates on what's called a large 8 00:00:36,458 --> 00:00:41,324 enumeration. And that will be something that will be 9 00:00:41,324 --> 00:00:45,380 useful for on-key options as well as on-mouse options that you'll see later. 10 00:00:46,500 --> 00:00:51,130 What we're starting with here is the cat program from the last video. 11 00:00:51,130 --> 00:00:55,095 And what we've got from the end of that video is we've changed the cat program so 12 00:00:55,095 --> 00:01:00,111 that the cat walks across the screen more quickly, which is nice. 13 00:01:01,370 --> 00:01:04,674 What I want to do now is go back to one of the original goals in the problem 14 00:01:04,674 --> 00:01:07,946 statement. Which is for this program to have the 15 00:01:07,946 --> 00:01:11,642 functionality that if I press the space bar, the cat jumps back to the beginning 16 00:01:11,642 --> 00:01:16,272 of the screen and starts walking. So you're kind of picking the kitten up, 17 00:01:16,272 --> 00:01:19,129 putting the kitten back at the left edge of the screen. 18 00:01:20,190 --> 00:01:22,995 Now, this is going to end up being a fairly simple change. 19 00:01:22,995 --> 00:01:25,827 But we've got this domain analysis and it's good idea to keep the domain 20 00:01:25,827 --> 00:01:29,820 analysis in sync with the program. So, the first thing I'm going to do is 21 00:01:29,820 --> 00:01:33,700 grab the domain analysis and make the required change there. 22 00:01:33,700 --> 00:01:36,945 In this case, there's no constants that change and there's no changing 23 00:01:36,945 --> 00:01:41,469 information that changes. All that changes is we're going to add 24 00:01:41,469 --> 00:01:45,110 one more big bang option, which is the on key option. 25 00:01:46,170 --> 00:01:49,952 And that allows us to give special behavior to our world program when a key 26 00:01:49,952 --> 00:01:54,468 on the keyboard is pressed. So, I'm going to add on key here, and now 27 00:01:54,468 --> 00:01:58,841 I'm going to jump over into the code. Nothing changed in the constants, so 28 00:01:58,841 --> 00:02:02,310 nothing changes here. Nothing changed in the changing world 29 00:02:02,310 --> 00:02:07,716 information, so nothing changes here. But we are going to use one more Big Bang 30 00:02:07,716 --> 00:02:10,971 option. And what I'm going to do is I'm going to 31 00:02:10,971 --> 00:02:14,952 go to the HTDW page. Go to the How to Design Worlds page. 32 00:02:14,952 --> 00:02:20,300 And I'm going to scroll down to get the template for world programs. 33 00:02:20,300 --> 00:02:24,670 And I'm just going to look at the template for the on key option. 34 00:02:24,670 --> 00:02:29,262 Here it is here. And I'll just copy this from here right 35 00:02:29,262 --> 00:02:36,120 over into my main function here. Paste it there. 36 00:02:36,120 --> 00:02:38,020 Now, I've got some parentheses problems here. 37 00:02:38,020 --> 00:02:40,860 Let me see. I'll get rid of both of those. 38 00:02:40,860 --> 00:02:50,680 And WS in this program is called cat, and that's a WS. 39 00:02:53,180 --> 00:03:01,800 And I'll decide right now that I'm going to call this function handle-key. 40 00:03:01,800 --> 00:03:05,230 So now that I've added that there, I've wished for this handle-key function. 41 00:03:06,280 --> 00:03:09,269 So, what I'm going to do is I'm going to grab the signature of it and go make a 42 00:03:09,269 --> 00:03:17,000 wish list entry. Here it is, let's see its cat key of 43 00:03:17,000 --> 00:03:27,740 event to cat reset cat to left edge when space key is pressed. 44 00:03:27,740 --> 00:03:35,600 And I'll make a stub handle key. And this functions takes two arguments. 45 00:03:35,600 --> 00:03:38,160 I'm going to talk about that a bit more in a minute, but it takes two arguments. 46 00:03:38,160 --> 00:03:41,680 One is the actual world state, the cat, and the other is a key event, and that's 47 00:03:41,680 --> 00:03:46,784 going to describe which key was pressed. This is just the stub. 48 00:03:46,784 --> 00:03:52,619 It'll produce 0. And I'll put bang bang bang to remind 49 00:03:52,619 --> 00:03:57,457 myself I still need to do this function. I updated the analysis to say that big 50 00:03:57,457 --> 00:04:03,120 bang needed the on key option. I updated main, so that that big bang 51 00:04:03,120 --> 00:04:08,083 specifies on key. And tells big bang to call a handler 52 00:04:08,083 --> 00:04:11,371 called handle key. And I've made the wish list entry for the 53 00:04:11,371 --> 00:04:14,976 handler. So, I've got the signature purpose and 54 00:04:14,976 --> 00:04:17,688 stub. Now I need to work on the examples. 55 00:04:17,688 --> 00:04:20,775 And what I'm going to do is I'm going to explain about key event while I work on 56 00:04:20,775 --> 00:04:30,790 the examples. This function consumes two arguments. 57 00:04:30,790 --> 00:04:36,140 And the first argument is a cat. It's a representation of the cat's x 58 00:04:36,140 --> 00:04:40,133 coordinate. So, a reasonable value for a cat might be 59 00:04:40,133 --> 00:04:42,380 10. The second argument is a key event. 60 00:04:43,440 --> 00:04:47,240 And what key event is is it's a primitive type in racket. 61 00:04:47,240 --> 00:04:50,240 And it's what's called a large enumeration. 62 00:04:51,360 --> 00:04:55,260 There's one distinct value in key event for each of the many different keys you 63 00:04:55,260 --> 00:05:00,130 can press on the keyboard. So there's a distinct value for the space 64 00:05:00,130 --> 00:05:03,380 key, and a distinct value for the A key, and a distinct value for the one key, and 65 00:05:03,380 --> 00:05:08,140 a distinct value for the left arrow key. There's a lot of them. 66 00:05:08,140 --> 00:05:09,930 That's why it's called a large enumeration. 67 00:05:11,560 --> 00:05:15,590 Now, in order to make this simple, what Racket does is it uses simple strings to 68 00:05:15,590 --> 00:05:21,229 be those distinct values. So, the distinct value that represents 69 00:05:21,229 --> 00:05:25,600 that the space key was pressed is a string with a space in it. 70 00:05:25,600 --> 00:05:31,242 So, that's the way big bang would call handle key if the current state of the 71 00:05:31,242 --> 00:05:37,700 world is 10 and the space key is pressed. Now we understand key event. 72 00:05:37,700 --> 00:05:41,810 Now, we're back to the standard HTTF generation of examples. 73 00:05:41,810 --> 00:05:45,779 Well, what is handle key supposed to do if the current world state is 10 if the 74 00:05:45,779 --> 00:05:51,190 cat is at x coordinate 10 and the space key is pressed. 75 00:05:51,190 --> 00:05:54,042 Well, it's supposed to reset the cat to the left edge so that should produce 76 00:05:54,042 --> 00:05:58,785 zero. Let's do another example now. 77 00:05:59,980 --> 00:06:07,050 What happens if we have handle key of ten, and the A key is pressed? 78 00:06:07,050 --> 00:06:10,802 Because, remember, we've told the user that they're supposed to set the cat back 79 00:06:10,802 --> 00:06:14,924 to the beginning by pressing space. But they might accidentally press 80 00:06:14,924 --> 00:06:19,304 something else. Well, what happens in that case is 81 00:06:19,304 --> 00:06:23,006 nothing's supposed to happen. The cat's supposed to stay where it is. 82 00:06:23,006 --> 00:06:28,690 So, that'll be 10. Now let's see. 83 00:06:28,690 --> 00:06:35,094 What other tests might we need? Well, you might also want to say well 84 00:06:35,094 --> 00:06:39,910 what happens if the cat happens to already be at zero and space key is 85 00:06:39,910 --> 00:06:44,900 pressed. I'll line this up this way. 86 00:06:44,900 --> 00:06:48,705 I'll indulge by inner Virgo. Well, if it's already at zero, and space 87 00:06:48,705 --> 00:06:53,727 key is pressed, it should stay at zero. You might even want to do that for this 88 00:06:53,727 --> 00:06:57,090 example. Which is to say, I start at zero. 89 00:06:57,090 --> 00:07:00,070 I press A. In that case, I should still be at zero. 90 00:07:00,070 --> 00:07:09,720 Now you might say, wait a minute, there's a whole bunch of possible keys. 91 00:07:10,800 --> 00:07:15,580 It's a very large enumeration. Do I need to test every single case? 92 00:07:17,020 --> 00:07:20,704 This is an example of white-box testing. What we're going to do is we're going to 93 00:07:20,704 --> 00:07:25,115 say to ourselves, you know, we don't need to test every single case. 94 00:07:25,115 --> 00:07:28,763 Because we kind of know how this function is going to work except you don't yet 95 00:07:28,763 --> 00:07:33,531 know how this function is going to work. So, now I have to start talking about how 96 00:07:33,531 --> 00:07:36,741 we template. Funcitons that operate on large 97 00:07:36,741 --> 00:07:40,160 enumerations. So, let's jump ahead to the template 98 00:07:40,160 --> 00:07:44,255 step, and then you'll see why it's okay to have used this small number of test 99 00:07:44,255 --> 00:07:48,436 cases. One way to get the template for a handle 100 00:07:48,436 --> 00:07:53,219 key function would be to go to the How to Design Worlds page. 101 00:07:54,300 --> 00:07:58,843 And at the bottom of the page, it includes templates for handle-key and 102 00:07:58,843 --> 00:08:04,436 handle-mouse, which are quite similar. Handle-key consumes a key event, and 103 00:08:04,436 --> 00:08:07,802 handle-mouse consumes a mouse event, which is a large enumeration describing 104 00:08:07,802 --> 00:08:12,210 all the possible mouse events. I'll copy it from here. 105 00:08:12,210 --> 00:08:15,752 And then, I'll explain how it works when we get back over to Racket. 106 00:08:15,752 --> 00:08:20,840 So, let's see. I've got to comment out the stub. 107 00:08:20,840 --> 00:08:23,060 It already happens to have the same name I'm using. 108 00:08:23,060 --> 00:08:26,956 That's a stroke of luck. But WS, is, in this program, world state 109 00:08:26,956 --> 00:08:31,203 is a CAT. So let me just, for consistency, rename 110 00:08:31,203 --> 00:08:34,971 WS to cat. And now, it turns out that this template 111 00:08:34,971 --> 00:08:40,200 happens to be right for this particular case but let's talk about why. 112 00:08:42,300 --> 00:08:46,119 Because it's an enumeration and a large enumeration, if you followed the normal 113 00:08:46,119 --> 00:08:50,600 data template rule you'd end up with a very large cond. 114 00:08:50,600 --> 00:08:54,960 There'd be one case in this cond for every possible key event. 115 00:08:54,960 --> 00:08:59,962 So, this first case says if the key is equal to space key equals is a special 116 00:08:59,962 --> 00:09:04,990 function that checks equality of key events. 117 00:09:04,990 --> 00:09:09,212 If the key is a space do this. And then, you have one if the key is an A 118 00:09:09,212 --> 00:09:12,922 do this, and if the key is a B do this and da da da you'd have a lot of them. 119 00:09:12,922 --> 00:09:18,170 But when we template a large numeration, what we're allowed to do is say look, 120 00:09:18,170 --> 00:09:23,682 there's going to be a small number of special cases. 121 00:09:23,682 --> 00:09:29,070 And then, all the other keys are going to be handled similarly. 122 00:09:29,070 --> 00:09:32,206 Or sometimes what happens is, if for example you're building a world program 123 00:09:32,206 --> 00:09:35,048 that does a text editor, there's whole groups of keys that are handled 124 00:09:35,048 --> 00:09:39,276 similarly. All the keys that insert text are handled 125 00:09:39,276 --> 00:09:42,426 similarly. Whereas the arrow keys are handled 126 00:09:42,426 --> 00:09:46,586 similarly, and so you might have larger groups than, than groups of one key and 127 00:09:46,586 --> 00:09:50,904 all the rest. But the basic idea here, this is how we 128 00:09:50,904 --> 00:09:54,414 template a large numeration, we identify the special cases and then we have an 129 00:09:54,414 --> 00:09:58,950 else for every thing else. So, let's see now. 130 00:09:58,950 --> 00:10:02,731 Completing the code against the examples and the purpose. 131 00:10:02,731 --> 00:10:06,823 If the key is equal to space then these two examples and the purpose, tell me 132 00:10:06,823 --> 00:10:12,633 that I'm supposed to produce zero. And if the key is anyting else, then 133 00:10:12,633 --> 00:10:19,280 these two examples and the purpose tell me that cat shouldn't change. 134 00:10:19,280 --> 00:10:21,475 I should just produce whatever the cat currently is. 135 00:10:21,475 --> 00:10:26,307 Let's test that. And now, you see why when I wrote thet 136 00:10:26,307 --> 00:10:31,744 est I was allowed to do it this way. I'm allowed to just test the special case 137 00:10:31,744 --> 00:10:36,099 space and one example of all the other cases. 138 00:10:37,340 --> 00:10:40,623 Because I know that I'm going to end up having this special constructure in which 139 00:10:40,623 --> 00:10:44,018 there are only two cases. Again, this is what's called white box 140 00:10:44,018 --> 00:10:46,457 testing. Where, when I write the tests, I allow 141 00:10:46,457 --> 00:10:50,390 myself to know something about the structure of the function. 142 00:10:50,390 --> 00:10:54,482 White box testing is something you'll talk more about in software engineering 143 00:10:54,482 --> 00:10:59,450 courses, if you take those, but this is an example of why we do it. 144 00:10:59,450 --> 00:11:02,867 It lets us test what a function is really doing without having to create anywhere 145 00:11:02,867 --> 00:11:09,000 near as elaborate a set of tests. So, let's see all my tests pass. 146 00:11:09,000 --> 00:11:11,983 Let me actually try running the program. Main and 0. 147 00:11:13,560 --> 00:11:18,126 You know, I'll try to type very loudly here. 148 00:11:18,126 --> 00:11:22,374 You hear whenever I press the space key, the cat is resetting back to the 149 00:11:22,374 --> 00:11:27,412 beginning. So just a quick summary, we kind of 150 00:11:27,412 --> 00:11:34,480 replayed the whole how to design worlds recipe. 151 00:11:34,480 --> 00:11:39,520 We, in the analysis, identified a new option to big bang. 152 00:11:39,520 --> 00:11:43,080 There were no changes to constants there we no changes to the data definitions. 153 00:11:44,440 --> 00:11:50,340 We added one new option to big bang that made us wish for a new handler. 154 00:11:50,340 --> 00:11:54,102 We did the signature purpose and stub for the new handler, then we went ahead and 155 00:11:54,102 --> 00:11:58,531 did the examples on the template. There was a special rule for templating 156 00:11:58,531 --> 00:12:01,201 this function, because it's a large enumeration. 157 00:12:01,201 --> 00:12:04,846 Most of what we did here is something we've done before. 158 00:12:04,846 --> 00:12:07,810 We followed the various pieces of the recipe. 159 00:12:07,810 --> 00:12:10,780 Really, the large enumeration rule is the only new thing we did here. 160 00:12:12,460 --> 00:12:16,428 What I suggest you do now is try adding another piece of functionality to this 161 00:12:16,428 --> 00:12:20,334 program which is to make it that whenever I click the mouse the cat goes to the 162 00:12:20,334 --> 00:12:27,900 current exposition of the mouse. That'll be an exercise very much like the 163 00:12:27,900 --> 00:12:31,740 one we just did except that instead of adding a key handler, you'll be adding a 164 00:12:31,740 --> 00:12:35,410 mouse handler. Have some fun with that.