1 00:00:00,008 --> 00:00:09,910 I'm going to end the week with our most elaborate world program yet. 2 00:00:11,430 --> 00:00:14,620 What we saw earlier was that cats have a mind of their own. 3 00:00:14,620 --> 00:00:18,610 When they get to the edge of the box, they just keep walking off the screen. 4 00:00:19,720 --> 00:00:23,230 Cows on the other hand, cows are a docile creature. 5 00:00:23,230 --> 00:00:27,640 When they get to the fence they turn around and they go back the other way. 6 00:00:28,770 --> 00:00:30,740 So, we're going to do a cow animation now. 7 00:00:31,770 --> 00:00:35,290 And you can kind of see the key way it's going to be different, right? 8 00:00:35,290 --> 00:00:39,322 A cat only has a position, it always goes the same direction, but a cow has two 9 00:00:39,322 --> 00:00:44,290 changing properties. Its position and its direction. 10 00:00:45,400 --> 00:00:47,540 So, this is going to be a compound data problem. 11 00:00:47,540 --> 00:00:52,070 It's going to be a how to design worlds problem with compound data. 12 00:00:52,070 --> 00:00:55,945 This is a long video, you may not want to watch it all at one sitting. 13 00:00:55,945 --> 00:00:59,575 But a world problem is a long problem and compound data makes it a bit longer, and 14 00:00:59,575 --> 00:01:05,330 there is a couple of very interesting points that happen here along the way. 15 00:01:05,330 --> 00:01:08,380 So, I would encourage you to be sure to watch this whole video through. 16 00:01:08,380 --> 00:01:11,448 Again, a good thing to do might be to stop it every now and then, and try to 17 00:01:11,448 --> 00:01:15,360 work a bit of it on your own, getting ahead of the video. 18 00:01:16,680 --> 00:01:20,338 But don't do that when you get to the render cow function, because there's a 19 00:01:20,338 --> 00:01:24,570 special thing going on there that we need to talk about. 20 00:01:24,570 --> 00:01:27,900 What I have open here in Doctor Racket is the starter file. 21 00:01:27,900 --> 00:01:31,356 We're also providing intermediate solutions at different points along the 22 00:01:31,356 --> 00:01:36,278 way of developing the whole solution. And as I said, I'll be dropping into 23 00:01:36,278 --> 00:01:40,538 different places in this as we go. So, here's the problem statement worked 24 00:01:40,538 --> 00:01:44,194 out in a bit more detail. We're going to have a cow that walks back 25 00:01:44,194 --> 00:01:47,054 and forth across the screen, and when it gets to the edge, it changes direction 26 00:01:47,054 --> 00:01:51,752 and goes back the other way. And we're giving you a couple nice images 27 00:01:51,752 --> 00:01:57,216 of cows, which we got from Brown. Of course, with any world program, the 28 00:01:57,216 --> 00:02:02,710 first step is to do an analysis. I have the analysis already worked out. 29 00:02:02,710 --> 00:02:07,009 And here it is, and mostly it's like the analysis of a cat program. 30 00:02:07,009 --> 00:02:11,233 A lot of the constant information is the same: the width, the height, the center 31 00:02:11,233 --> 00:02:14,923 y, the background. One difference is here the cow has two 32 00:02:14,923 --> 00:02:18,223 images: the image where it's facing to the right and the image where it's facing 33 00:02:18,223 --> 00:02:21,610 to the left. That's one difference. 34 00:02:21,610 --> 00:02:25,002 The most important difference is is reflected in the center picture and also 35 00:02:25,002 --> 00:02:28,419 in the changing information, which is the key here. 36 00:02:28,419 --> 00:02:31,930 There are two changing information values associated with the cow. 37 00:02:31,930 --> 00:02:36,650 The cow's x coordinates and the cow's direction and speed. 38 00:02:38,230 --> 00:02:43,110 We're going to call the direction edx for the change in x. 39 00:02:44,260 --> 00:02:47,127 So, that is how we're going to name label the velocity, which is, which is the 40 00:02:47,127 --> 00:02:51,201 change in the position. Another difference shows up here in the 41 00:02:51,201 --> 00:02:55,755 third image, where I've made a detailed note to myself describing what's going to 42 00:02:55,755 --> 00:03:02,455 happen when the cow gets to the edge. So, what I'm saying here is that if the 43 00:03:02,455 --> 00:03:07,215 cows center, cow x, tries to go past width or past 0, then we're going to 44 00:03:07,215 --> 00:03:11,716 reset it. So, here the decision I'm making, is that 45 00:03:11,716 --> 00:03:14,362 I'm going to let the cow get all the way up to the edge of the box but not 46 00:03:14,362 --> 00:03:19,087 outside. The big-bang options are relatively 47 00:03:19,087 --> 00:03:23,200 straight forward, there's on-tick, to-draw, and on-key. 48 00:03:23,200 --> 00:03:26,740 So, now I'm going to jump to the v zero solution, and in all of these solution 49 00:03:26,740 --> 00:03:31,290 files, you can see a list of kind of where each one is in it. 50 00:03:31,290 --> 00:03:35,380 You might choose not to read that, so that you don't get too far ahead. 51 00:03:35,380 --> 00:03:38,743 What you might want to do now is try to do some of this yourself and then use 52 00:03:38,743 --> 00:03:42,505 these solution files to catch yourself up, or watch the video to catch yourself 53 00:03:42,505 --> 00:03:47,824 up, or follow along with me either way. So, look here is the constants, and the 54 00:03:47,824 --> 00:03:51,340 constants are relatively straightforward. There's the width, the height, the center 55 00:03:51,340 --> 00:03:53,555 y. There's two cow images and the 56 00:03:53,555 --> 00:03:56,760 background. Nothing really new there. 57 00:03:56,760 --> 00:04:03,510 Now, I'm going to go on to the data definition for the changing world state. 58 00:04:03,510 --> 00:04:06,246 On looking at the analysis, I see that there's two pieces of changing 59 00:04:06,246 --> 00:04:09,506 information. Two changing information values that 60 00:04:09,506 --> 00:04:13,990 naturally belong together. And so, that tells me that I want to use 61 00:04:13,990 --> 00:04:18,342 a compound data definition. So, when you use a compound data 62 00:04:18,342 --> 00:04:22,611 definition, the first thing we have to do is a structure definition for it. 63 00:04:22,611 --> 00:04:25,746 So, let me make a structure, and I guess I'll just call it cow. 64 00:04:25,746 --> 00:04:31,186 And it has two fields, and I'll call one x for the x coordinate and one dx for the 65 00:04:31,186 --> 00:04:36,472 current rate of change in the x coordinate. 66 00:04:36,472 --> 00:04:43,024 And I will say cow is make cow. Now, we know that this cow nicely stays 67 00:04:43,024 --> 00:04:46,725 in the box. So, that means we know that the 68 00:04:46,725 --> 00:04:50,433 x-coordinate is bounded a certain way in this world program. 69 00:04:50,433 --> 00:04:55,641 So, what I'm going to do here is I'm going to say, Natural 0, width, as a way 70 00:04:55,641 --> 00:05:04,343 of saying that the cow's x-coordinate stays within the boundaries of the box. 71 00:05:05,750 --> 00:05:09,715 Now, we don't know of any bounds on dx, on the velocity of the cow, but let's 72 00:05:09,715 --> 00:05:14,780 just decide that it's going to be at least be an an integer. 73 00:05:14,780 --> 00:05:18,380 That'll make some things simpler. So, we'll say that this is an integer. 74 00:05:18,380 --> 00:05:27,246 We'll say that the interpretation of a cow is that, if you have a cow make cow 75 00:05:27,246 --> 00:05:37,020 with an x and a dx. Then that's a cow with x coordinate x and 76 00:05:37,020 --> 00:05:46,448 velocity dx. We'll say that the x is the center of the 77 00:05:46,448 --> 00:05:54,720 cow. We'll say that x is in screen coordinates 78 00:05:54,720 --> 00:06:01,840 or pixels. And we'll say that dx is in pixels per 79 00:06:01,840 --> 00:06:07,245 tick. So that if dx is three, for example, that 80 00:06:07,245 --> 00:06:12,430 means that on each clock tick the cow moves three pixels, where its x value 81 00:06:12,430 --> 00:06:18,673 gets bigger by three. Now, here we're to start to see with some 82 00:06:18,673 --> 00:06:23,395 examples get a bit more interesting. I'm going to make a couple of them, let's 83 00:06:23,395 --> 00:06:27,030 say C1. Let's say this is a cow that its current 84 00:06:27,030 --> 00:06:32,008 position is 10, and that its current dx is 3. 85 00:06:32,008 --> 00:06:38,468 And I'll just label this one to help me understand the interpretation at position 86 00:06:38,468 --> 00:06:45,564 10 moving left to right. And here's another one. 87 00:06:52,200 --> 00:06:56,600 And this one is at 20, and it's moving the other way. 88 00:06:56,600 --> 00:07:00,696 So, this is a case where as the data definition becomes more complicated, the 89 00:07:00,696 --> 00:07:05,048 examples become more useful to really understand how the data definition works, 90 00:07:05,048 --> 00:07:10,322 and what the interpretation is. Now, of course, I have to do the template 91 00:07:10,322 --> 00:07:13,710 and template rules used. But what I'm going to do to speed this 92 00:07:13,710 --> 00:07:16,710 video up a little bit, is I'm kind of going to pull, pull the next stage of the 93 00:07:16,710 --> 00:07:22,435 roast out of the oven ready done. I'll go to cowabunga v1. 94 00:07:22,435 --> 00:07:26,855 And it already has the complete data definition here, everything that we just 95 00:07:26,855 --> 00:07:30,980 did plus the template and template rules used. 96 00:07:30,980 --> 00:07:35,995 Next step is going to be to set up the main function, and all the wish list 97 00:07:35,995 --> 00:07:43,295 entries for the big bang option handlers. And since that's straightforward again, 98 00:07:43,295 --> 00:07:47,740 I'm going to jump ahead to go to cowabunga V2 that has all that. 99 00:07:47,740 --> 00:07:50,668 You might want to not do that, and go ahead and develop that yourself as a way 100 00:07:50,668 --> 00:07:56,880 of checking your work. I'm going to jump ahead now though. 101 00:07:56,880 --> 00:08:01,200 So, here I'm in cowabunga V2, and it's got the data definition we did before. 102 00:08:01,200 --> 00:08:05,160 And it's got a main function that calls big bang with the three handlers: 103 00:08:05,160 --> 00:08:10,390 on-tick, to-draw, and on-key. And I've given those functions the names: 104 00:08:10,390 --> 00:08:15,900 next cow, render cow, and handle key. And here's the wish list entries. 105 00:08:15,900 --> 00:08:21,238 The signatures are formulaic, of course. Once we know that the changing real state 106 00:08:21,238 --> 00:08:26,043 is represented by type called cow, all these signatures come automatically. 107 00:08:26,043 --> 00:08:30,250 But I did spend some time thinking about the purposes that I put in here. 108 00:08:30,250 --> 00:08:34,030 So, I said for next cow that it increases the cow x by dx, and it bounces off the 109 00:08:34,030 --> 00:08:40,070 edges just to remind me that when the cow gets to the edge it has to turn around. 110 00:08:41,540 --> 00:08:46,699 In this one I said, place the appropriate cow image on MTS at its current position 111 00:08:46,699 --> 00:08:50,615 and center-Y. And appropriate here is reminding me that 112 00:08:50,615 --> 00:08:53,670 sometimes I use the cow that faces right, and sometimes I use the cow that faces 113 00:08:53,670 --> 00:08:57,457 left. And for handle-key, I put reverse the 114 00:08:57,457 --> 00:09:02,080 direction of cow travel when the Spacebar is pressed. 115 00:09:02,080 --> 00:09:05,924 At this point we're set up to go, and all that has to happen is to complete the 116 00:09:05,924 --> 00:09:10,728 design of these three functions. There are a couple of interesting things 117 00:09:10,728 --> 00:09:13,698 that happen in the design of these functions though. 118 00:09:13,698 --> 00:09:16,776 So, I'm going to go ahead and work through next cow and render cow in more 119 00:09:16,776 --> 00:09:20,259 detail, so that you could see how that plays out. 120 00:09:20,259 --> 00:09:26,935 So, now I need to work my wish list until it's done. 121 00:09:26,935 --> 00:09:31,386 And the first WishList entry is for next cow, so let me start with that. 122 00:09:31,386 --> 00:09:36,066 I've already got the signature, purpose, and stub, I need to work on the examples. 123 00:09:36,066 --> 00:09:39,775 So, let's see, examples are going to look something like this. 124 00:09:39,775 --> 00:09:45,215 Next-cow, they're always going to consume some sort of cow, and they're always 125 00:09:45,215 --> 00:09:52,570 going to produce some sort of cow. So, that's kind of the skeleton of an 126 00:09:52,570 --> 00:09:56,349 example. Let's try to fill them in some. 127 00:09:58,210 --> 00:10:02,840 Let's see, a simple case is that the cow is somewhere in the middle of the screen. 128 00:10:02,840 --> 00:10:06,490 Let's just assume that 20 is less than the full width. 129 00:10:06,490 --> 00:10:11,235 And it's moving at a velocity of three, which means it's moving three pixels to 130 00:10:11,235 --> 00:10:17,111 the right each time. And that means that on the next tick that 131 00:10:17,111 --> 00:10:24,680 cow should be at 20 plus 3, and still moving at the same velocity. 132 00:10:24,680 --> 00:10:28,990 So, that's a cow in the middle moving left to right. 133 00:10:28,990 --> 00:10:35,500 Let's do a cow in the middle that's moving right to left. 134 00:10:35,500 --> 00:10:41,285 Let's see that cow would just be at minus 20 and three, and still moving right to 135 00:10:41,285 --> 00:10:46,603 left. So, that's those two cases, these are 136 00:10:46,603 --> 00:10:50,292 middle cases. I said in the analysis that we would let 137 00:10:50,292 --> 00:10:54,772 the cow go all the way up to the edge of the box but without changing direction. 138 00:10:54,772 --> 00:10:58,457 So, let's do that case next. Let me make some copies of this x before 139 00:10:58,457 --> 00:11:01,903 I added it. So, let's see, we might have a cow moving 140 00:11:01,903 --> 00:11:06,343 from left to right that's just about to get all the way to to the edge of the 141 00:11:06,343 --> 00:11:11,093 box. So, that might be a cow for example 142 00:11:11,093 --> 00:11:18,214 that's at width minus three and moving three pixels to the right per tick. 143 00:11:18,214 --> 00:11:23,947 So, that cow after this tick will be all the way to width, and still think it's 144 00:11:23,947 --> 00:11:28,940 moving towards the right. It hasn't bounced yet, because we said 145 00:11:28,940 --> 00:11:31,100 were going to let it get all the way to the edge. 146 00:11:33,240 --> 00:11:38,542 It'll bounce the next time. And another cow might be, let's see, it 147 00:11:38,542 --> 00:11:44,898 might be at three moving with speed minus three. 148 00:11:44,898 --> 00:11:50,266 And that means that when this tick is done it will be all the way at zero, and 149 00:11:50,266 --> 00:11:57,670 still think it's going to head towards the left even though its not. 150 00:11:57,670 --> 00:12:02,904 You know, bounce on the next tick. So, these are somewhere, these were, how 151 00:12:02,904 --> 00:12:07,950 we would describe these cases. These are cases where it's going to 152 00:12:07,950 --> 00:12:15,389 reaches, the cow reaches the very edge. And now it seems like there's going to be 153 00:12:15,389 --> 00:12:18,120 two more cases for when the cow would actually pass the edge. 154 00:12:18,120 --> 00:12:24,878 Let's see, there's a case where the cow might be at, let's say width minus 2, 155 00:12:24,878 --> 00:12:33,558 moving 3 to the right each time. And what are we going to do with that 156 00:12:33,558 --> 00:12:39,027 cow? Well, let's put it all the way at the 157 00:12:39,027 --> 00:12:43,500 edge but now headed back towards the center. 158 00:12:43,500 --> 00:12:47,826 It needs to change its direction now. So, we'll change its direction to that. 159 00:12:47,826 --> 00:12:51,666 Basically make it reverse its direction, because it was, it had, it would, it 160 00:12:51,666 --> 00:12:56,429 actually tried to leave the box. So now, its going to be at the edge, but 161 00:12:56,429 --> 00:13:00,630 its going to be headed towards the center of the box again. 162 00:13:00,630 --> 00:13:06,805 And the corresponding case of course is that there's a cow at two that's headed 163 00:13:06,805 --> 00:13:12,112 towards the left. And we'll say no, no, no, you can't leave 164 00:13:12,112 --> 00:13:17,928 the box, you stay at the edge of the box, and now you're heading the other way. 165 00:13:17,928 --> 00:13:27,794 So, these are cows that these two counts. They try these cases, try to pass the 166 00:13:27,794 --> 00:13:33,797 edge. And let's see all those are well formed. 167 00:13:33,797 --> 00:13:39,050 They are well formed. And you can see that it's a little bit 168 00:13:39,050 --> 00:13:43,339 complicated. That's a feature of this design method, 169 00:13:43,339 --> 00:13:47,292 which is that I'm working out all these complex boundary cases before I actually 170 00:13:47,292 --> 00:13:51,225 get to coding the general purpose function. 171 00:13:51,225 --> 00:13:55,246 I've got some concrete examples to help me understand the function. 172 00:13:55,246 --> 00:13:59,342 And, I've got tests for when I get the function going. 173 00:13:59,342 --> 00:14:02,390 So, now let's see, let's go get the template. 174 00:14:02,390 --> 00:14:15,695 There's the template for a cow. And I've got these notes here in the 175 00:14:15,695 --> 00:14:23,606 template. I'll make a note to myself it says I took 176 00:14:23,606 --> 00:14:31,741 template from Cow. I'll rename this function to next cow. 177 00:14:31,741 --> 00:14:35,186 And I've got note for myself that it says the template has two fields and it also 178 00:14:35,186 --> 00:14:39,582 tells me the types of fields to remind me what's going on there. 179 00:14:39,582 --> 00:14:44,541 Now, let's think about the examples for a second. 180 00:14:44,541 --> 00:14:49,190 What do the examples tell us in terms of how many cases of examples are there are. 181 00:14:49,190 --> 00:14:57,640 In all four of these cases, the cow really keeps doing whatever it was doing. 182 00:14:57,640 --> 00:15:01,620 Here it goes from 20 to 23, and its direction doesn't change. 183 00:15:01,620 --> 00:15:05,690 Here it goes from 20 to 17, and its direction doesn't change. 184 00:15:05,690 --> 00:15:10,420 Here it goes from width minus three to width, its direction doesn't change. 185 00:15:10,420 --> 00:15:15,370 Here it goes from 3 to 0, but its direction doesn't change. 186 00:15:15,370 --> 00:15:18,406 These four are all really the same case, they're just the keep doing what you're 187 00:15:18,406 --> 00:15:23,933 doing case. But these two are different, this is the 188 00:15:23,933 --> 00:15:27,730 case where the cow tries to leave the right hand edge of the box. 189 00:15:29,050 --> 00:15:32,590 And this is the case where the cow tries to leave the left hand edge of the box. 190 00:15:32,590 --> 00:15:38,323 So, my next step in building the template for this function is I'm going to give 191 00:15:38,323 --> 00:15:42,960 myself a three case cond. Okay. 192 00:15:42,960 --> 00:15:47,460 I'm going to say cond, and then in each case, now that I know what these types 193 00:15:47,460 --> 00:15:53,327 are, I'll just delete this note. And then in each case, I'll give myself 194 00:15:53,327 --> 00:15:57,611 two copies of the template to work with, the question version and the answer 195 00:15:57,611 --> 00:16:04,117 version. And I'll have three of these. 196 00:16:04,117 --> 00:16:11,149 So now, let me see how do I think about these cases. 197 00:16:11,149 --> 00:16:15,885 Well, this case here is the case where if the cow kept going, it would leave the 198 00:16:15,885 --> 00:16:21,000 box by the right edge. It would go too far. 199 00:16:21,000 --> 00:16:26,745 What does that mean it we go too far? Well, it means that if I took the cow's 200 00:16:26,745 --> 00:16:33,015 current x position and I added the dx to it, this expression here is what the cows 201 00:16:33,015 --> 00:16:41,676 position would be if it just kept going. In, in this case, what happens is that, 202 00:16:41,676 --> 00:16:47,785 if the cow just kept going, then it's position would be greater than width. 203 00:16:47,785 --> 00:16:53,115 The cow would leave the right edge of the box, and of course we don't want the cow 204 00:16:53,115 --> 00:16:57,285 to do that. We want the cow to be a nice docile 205 00:16:57,285 --> 00:17:02,954 creature that stays inside the box. And so, instead of letting it leave the 206 00:17:02,954 --> 00:17:07,826 box, we're going to say, no, no, no, no, you're going to be a new cow that is 207 00:17:07,826 --> 00:17:15,262 going to be right at the edge of the box in your new velocity. 208 00:17:15,262 --> 00:17:18,770 We will basically do the opposite of your current velocity. 209 00:17:18,770 --> 00:17:23,506 And in Racket, if you call the minus primitive with a single argument, it just 210 00:17:23,506 --> 00:17:28,539 changes the sign of the number. So, if you call minus with three, it 211 00:17:28,539 --> 00:17:33,051 gives you minus three. If you call minus with minus six, it 212 00:17:33,051 --> 00:17:37,595 gives you six. So, this changes the direction of the 213 00:17:37,595 --> 00:17:41,949 cow, and this puts it right at the edge of the box. 214 00:17:41,949 --> 00:17:48,280 So, that's this case here. So now, let's look at this case here. 215 00:17:48,280 --> 00:17:52,564 Well, this is the case where if you let the cow just keep going, this is the cow 216 00:17:52,564 --> 00:17:59,070 that just keeps going, then it would end up outside the left edge of the box. 217 00:17:59,070 --> 00:18:02,766 Its position would end up less than zero, and of course we don't want the cow to do 218 00:18:02,766 --> 00:18:05,925 that. We want it to stay in the box. 219 00:18:05,925 --> 00:18:11,985 So, we're going to say, no, instead we're going to have a cow that's at the very 220 00:18:11,985 --> 00:18:21,363 left edge of the box. And once again, we're just going to flip 221 00:18:21,363 --> 00:18:31,520 its direction around. So, that's this case. 222 00:18:31,520 --> 00:18:34,326 And now, all these other cases are just the cow keeps doing whatever it was 223 00:18:34,326 --> 00:18:36,680 doing. So, we don't need a question here, we'll 224 00:18:36,680 --> 00:18:43,480 just put an else. And we'll say, well the new cow is a cow 225 00:18:43,480 --> 00:18:51,790 that keeps doing whatever it was doing, that's plus cow of x and cow dx. 226 00:18:51,790 --> 00:18:56,210 This is the same expression used here and here to see where will the cow end up if 227 00:18:56,210 --> 00:19:00,225 we just let it keep going. Well, this cow is going to just keep 228 00:19:00,225 --> 00:19:02,620 going. And its new dx is just going to be the 229 00:19:02,620 --> 00:19:07,128 same as its old dx, because it's just going to keep going. 230 00:19:07,128 --> 00:19:15,143 Let's try all our tests now. Whoops, make is wrong, this is supposed 231 00:19:15,143 --> 00:19:22,383 to be make cow. All six test paths. 232 00:19:22,383 --> 00:19:29,511 Now look, this is in some sense the most complicated function we've designed so 233 00:19:29,511 --> 00:19:33,832 far. Now, it's complicated entirely due to 234 00:19:33,832 --> 00:19:37,842 domain knowledge. It's complicated, because the geometry of 235 00:19:37,842 --> 00:19:42,522 an object moving back and forth across a box, and handling the edge conditions 236 00:19:42,522 --> 00:19:49,330 right is a bit complicated. But notice something important. 237 00:19:49,330 --> 00:19:53,677 If you break it down into all of these six examples, and then you realize that 238 00:19:53,677 --> 00:20:00,000 those six examples are really just three cases, then it isn't complicated. 239 00:20:00,000 --> 00:20:02,400 The design method really worked for us here. 240 00:20:02,400 --> 00:20:06,873 It told us to do the examples first, which broke the problem down, and helped 241 00:20:06,873 --> 00:20:11,750 us then take the template and put structure onto it. 242 00:20:13,780 --> 00:20:17,674 Here's an example of the design method making a moderately difficult problem a 243 00:20:17,674 --> 00:20:22,261 lot easier. What I've done now is to jump to the v3 244 00:20:22,261 --> 00:20:29,560 version of the cowabunga solution. That has the next-cow solution, which we 245 00:20:29,560 --> 00:20:34,526 just developed a few minutes ago. And I've actually done a bit more than 246 00:20:34,526 --> 00:20:37,585 that. I've started doing the design for the 247 00:20:37,585 --> 00:20:41,221 render-cow function. Just to save time, I did the first part 248 00:20:41,221 --> 00:20:46,317 of the design already. So I've got the signature, the purpose, 249 00:20:46,317 --> 00:20:52,096 the stab, and I did the examples. And the examples for this function are 250 00:20:52,096 --> 00:20:57,053 actually relatively straightforward. If I render a cow that's at position 99 251 00:20:57,053 --> 00:21:02,475 and has a positive velocity. In other words, it's, it's facing towards 252 00:21:02,475 --> 00:21:08,570 the right edge of the screen. Then, what this function needs to do is 253 00:21:08,570 --> 00:21:13,690 to place an image of the right facing cow at x position 99 at y position center y 254 00:21:13,690 --> 00:21:19,384 onto the background MTS. And I need two tests for this function, 255 00:21:19,384 --> 00:21:22,660 because sometimes it places a cow facing right and sometimes it places a cow 256 00:21:22,660 --> 00:21:26,374 facing left. And so, I've got a second test here where 257 00:21:26,374 --> 00:21:29,529 the cow is going in the different direction. 258 00:21:30,650 --> 00:21:33,954 And to be honest, this test would actually be a little bit better if I 259 00:21:33,954 --> 00:21:37,907 changed the x coordinate just to be sure that I couldn't accidentally have put in 260 00:21:37,907 --> 00:21:44,323 by accident 99 into the actual solution. So, let's just make this be you know, 33, 261 00:21:44,323 --> 00:21:48,519 and we'll make that be 33. And now those are two pretty good 262 00:21:48,519 --> 00:21:52,521 examples, they vary both the direction that the cow is facing and the x 263 00:21:52,521 --> 00:21:57,013 coordinate. So, I've already got the template, let's 264 00:21:57,013 --> 00:22:00,980 just start filling this in. Let's see, both examples tell me that I'm 265 00:22:00,980 --> 00:22:05,965 going to place an image. And sometimes it's one image and 266 00:22:05,965 --> 00:22:12,110 sometimes it's another image. Let me just put dots there for a second. 267 00:22:12,110 --> 00:22:16,900 And I always place the image at the cow's x coordinate. 268 00:22:18,510 --> 00:22:24,416 And I always place the image at center y. And I always place the image on the 269 00:22:24,416 --> 00:22:28,133 background. That's all of it, except for this part 270 00:22:28,133 --> 00:22:33,280 here where I have to decide exactly which image to place. 271 00:22:33,280 --> 00:22:37,619 Now, there's two choices here. One choice is I could Start to put an if 272 00:22:37,619 --> 00:22:42,410 expression here that would choose which cow image to use. 273 00:22:42,410 --> 00:22:45,725 Well, I'm going to do something slightly different, and it's going to be something 274 00:22:45,725 --> 00:22:49,406 that we'll talk a lot about in the course as we go forward. 275 00:22:49,406 --> 00:22:53,246 Which is I'm going to say to myself you know, this function is actually doing two 276 00:22:53,246 --> 00:22:57,344 things. This function is deciding which image to 277 00:22:57,344 --> 00:23:01,890 use and putting it in the proper place. Two tasks. 278 00:23:01,890 --> 00:23:07,090 And as a general rule, we don't want functions that do two tasks. 279 00:23:07,090 --> 00:23:13,066 We want each function to do one task. So, what I'm going to do is I'm going to 280 00:23:13,066 --> 00:23:16,742 wish for a helper. I'm going to say you know, it really 281 00:23:16,742 --> 00:23:21,725 would be great here if there was a function called choose-image. 282 00:23:21,725 --> 00:23:25,941 And I could call that function with a cow, and it would give me back the right 283 00:23:25,941 --> 00:23:30,683 image to use. If I had that, then I would be done. 284 00:23:30,683 --> 00:23:34,597 And so, I'm just going to wish for that to exist. 285 00:23:34,597 --> 00:23:38,305 And I have to wish in a little bit more detail. 286 00:23:38,305 --> 00:23:44,279 I'll wish in a little more detail by writing a WishList entry for it. 287 00:23:44,279 --> 00:23:50,073 So I'll say cow to image, produce. Now, what does it need to do, well, it 288 00:23:50,073 --> 00:23:58,307 needs to choose the right cow. Produce RCOW or LCOW depending on 289 00:23:58,307 --> 00:24:05,078 direction cow is going. And the reason I write this signature on 290 00:24:05,078 --> 00:24:08,606 purpose right now, and I write it in detail right now, is that right now after 291 00:24:08,606 --> 00:24:13,940 I just finished wishing for this function, I know what I want it to do. 292 00:24:13,940 --> 00:24:17,220 So, I'm going to take the trouble to write down what I want it to do. 293 00:24:17,220 --> 00:24:19,770 And then I'm going to say, oh, but this doesn't exist yet. 294 00:24:19,770 --> 00:24:22,878 I hope it will some day, and I'll make a stub. 295 00:24:22,878 --> 00:24:32,280 Choose-image and sends a cow, and it's got to produce some image. 296 00:24:32,280 --> 00:24:36,310 I could make it produce the blank image. In this case, I'll just make the stub 297 00:24:36,310 --> 00:24:40,465 produce the right cow. And now I run this to see if it's 298 00:24:40,465 --> 00:24:43,300 well-formed. And it is well-formed. 299 00:24:43,300 --> 00:24:47,656 And what we're going to see paradoxically is that one of these two render cow tests 300 00:24:47,656 --> 00:24:51,444 actually passed. The first one actually passed just 301 00:24:51,444 --> 00:24:55,630 because it's choose image stub always produces the right facing cow. 302 00:24:55,630 --> 00:25:03,931 So now, I've basically done render-cow. If somebody goes and fulfills this wish 303 00:25:03,931 --> 00:25:08,226 that I made for choose image. And that somebody is going to be me a 304 00:25:08,226 --> 00:25:14,078 little bit later when I say to myself, hey, what what work remains to be done. 305 00:25:14,078 --> 00:25:19,960 Let me search for bang, bang, bang, oh, I need this function choose-image. 306 00:25:19,960 --> 00:25:21,323 Okay, great. Let me do it. 307 00:25:21,323 --> 00:25:25,206 Lets see what does it do, it consumes a cow, it produces an image. 308 00:25:25,206 --> 00:25:28,261 It produces either the right cow or the left cow depending on the direction the 309 00:25:28,261 --> 00:25:33,826 cow is going. So, I'm going to speed this up a bit. 310 00:25:33,826 --> 00:25:38,253 I've got two examples. One example for when the cow is moving 311 00:25:38,253 --> 00:25:41,252 left to right so, it's facing toward the right. 312 00:25:41,252 --> 00:25:45,095 Another example for when the cow is moving the other way, and so, I need the 313 00:25:45,095 --> 00:25:57,879 left cow image. I'm going to go and get the template from 314 00:25:57,879 --> 00:26:04,592 cow. And now, let's see, there's two cases. 315 00:26:04,592 --> 00:26:08,624 So I'll use an if, and the question is whether the dx of the cow is greater than 316 00:26:08,624 --> 00:26:12,690 zero. If it is, I use the right-facing cow, 317 00:26:12,690 --> 00:26:17,130 otherwise I use the left-facing cow. And there's a bit of an issue here I have 318 00:26:17,130 --> 00:26:20,910 to deal with, which is what to do if cow dx is actually zero. 319 00:26:20,910 --> 00:26:26,766 And in that case, I'm just going to go ahead and decide to use the left-facing 320 00:26:26,766 --> 00:26:30,236 cow. Now when I run it, I get that all my 321 00:26:30,236 --> 00:26:33,434 tests pass. And that includes the three tests for 322 00:26:33,434 --> 00:26:37,088 choose-image, but it also includes the two tests for render-cow, because 323 00:26:37,088 --> 00:26:42,672 choose-image is a helper for render-cow. So now, render-cow is working completely, 324 00:26:42,672 --> 00:26:45,270 because choose-image is working completely. 325 00:26:46,980 --> 00:26:51,780 Let me just recap what happened there. We were in the middle of coding the 326 00:26:51,780 --> 00:26:55,802 function render-cow. And we knew it had to place an image, and 327 00:26:55,802 --> 00:26:58,608 we knew where it was going to place the image, and we knew it had to decide what 328 00:26:58,608 --> 00:27:03,360 image it was going to place. And that's when this idea about each 329 00:27:03,360 --> 00:27:09,085 function should only do one task came up. What I did was I decided you know, 330 00:27:09,085 --> 00:27:13,645 deciding where to put the image, and deciding what the image is, it's two 331 00:27:13,645 --> 00:27:17,615 tasks. I'm going to delegate one of the tasks to 332 00:27:17,615 --> 00:27:20,790 a new helper function, choose-image in this case. 333 00:27:20,790 --> 00:27:25,875 We're going to talk a lot more about this idea of helper functions as we go along. 334 00:27:25,875 --> 00:27:30,015 And in some cases, we're going to give you very clear cut and dried rules for 335 00:27:30,015 --> 00:27:34,380 when to use helper function. This is not one of those cut and dried 336 00:27:34,380 --> 00:27:38,064 cases. In this case, you have to kind of decide 337 00:27:38,064 --> 00:27:42,940 that choose image is its own separate task. 338 00:27:42,940 --> 00:27:46,783 And some programmers wouldn't make a separate function for choose-image, 339 00:27:46,783 --> 00:27:51,306 because it's so small. But this is a reasonable place to use a 340 00:27:51,306 --> 00:27:57,460 helper function, because there really is a separate task here. 341 00:27:57,460 --> 00:28:01,000 And as we work through this part of this course, we want you to look out for 342 00:28:01,000 --> 00:28:04,540 places where there is a separate task and it makes sense to use a separate 343 00:28:04,540 --> 00:28:08,850 function. What is clear is that when I go back to 344 00:28:08,850 --> 00:28:13,755 read this function, and I go to read render cow, it says okay, let's see. 345 00:28:13,755 --> 00:28:17,595 I'm going to place an image and somebody else is going to choose the image, and 346 00:28:17,595 --> 00:28:22,530 I'm going to put it at the cow's x coordinate, Center Y and MTS. 347 00:28:22,530 --> 00:28:25,008 That's very clear to me. It says, I'm placing the image and 348 00:28:25,008 --> 00:28:29,430 somebody else is choosing the image. And now, when I go down here and 349 00:28:29,430 --> 00:28:32,902 re-choose the image, it says, well. If the dx is greater than zero, it's 350 00:28:32,902 --> 00:28:37,943 right facing, otherwise it's left facing. This code is easy to read. 351 00:28:37,943 --> 00:28:44,492 And at this point, I have all of my handlers done except for handle key. 352 00:28:44,492 --> 00:28:49,182 So, I actually can run this program at this point. 353 00:28:49,182 --> 00:28:53,836 And I could say, main, make cow. The cow that starts at the left edge and 354 00:28:53,836 --> 00:28:56,700 is moving three ticks, three pixels per tick. 355 00:28:56,700 --> 00:29:03,038 And there's our little cow. I'll leave it to you to finish the key 356 00:29:03,038 --> 00:29:10,628 handler, as I said the solution is there in cowabunga v five. 357 00:29:10,628 --> 00:29:15,278 And the problem description also talks about a fun little thing you can do, 358 00:29:15,278 --> 00:29:19,928 where if you take the cow image and you take each image and rotate it a couple 359 00:29:19,928 --> 00:29:27,632 degrees left and a couple degrees right. And then you take a speed that's for 360 00:29:27,632 --> 00:29:31,670 example, an odd number. And you arrange to use different cow 361 00:29:31,670 --> 00:29:35,950 images depending on whether the position is an odd or an even number. 362 00:29:35,950 --> 00:29:39,415 You can make the cow appear to waddle as it crosses the screen, and that looks 363 00:29:39,415 --> 00:29:42,405 kind of neat. And there's all sorts of other fun stuff 364 00:29:42,405 --> 00:29:45,123 you can do here. Just go ahead and have some fun with this 365 00:29:45,123 --> 00:29:48,132 cow program, that will be good practice for doing this week's homework 366 00:29:48,132 --> 00:29:49,820 assignment.