1 00:00:00,004 --> 00:00:11,530 In this HTDF example problem, you're going to see a case where the problem 2 00:00:11,530 --> 00:00:15,182 statement isn't very specific about the function that wee need to design. 3 00:00:15,182 --> 00:00:19,220 That's going to happen more and more as we go foward in the course. 4 00:00:20,260 --> 00:00:25,000 Remember what I said in the first video. Design is the process of going from a 5 00:00:25,000 --> 00:00:28,590 poorly formed problem, to a well structured solution. 6 00:00:29,660 --> 00:00:33,340 So, making the problem more specific is part of the design process. 7 00:00:34,540 --> 00:00:38,650 In this video I'm also going to talk, about how many tests you need for a 8 00:00:38,650 --> 00:00:42,500 function. And we'll see another example of a case 9 00:00:42,500 --> 00:00:45,070 where you get part way through the recipe. 10 00:00:45,070 --> 00:00:49,190 And realize that you need to go back and refine some work that you did in an 11 00:00:49,190 --> 00:00:54,150 earlier step of the recipe. In this problem we're asked to design a 12 00:00:54,150 --> 00:00:58,730 function that consumes an image and determines whether the image is tall. 13 00:00:59,880 --> 00:01:02,910 So let's see, it seems clear that it consumes an image. 14 00:01:02,910 --> 00:01:05,560 [SOUND]. But what does it mean to determine 15 00:01:05,560 --> 00:01:10,290 whether the image is tall? Well, we're asking, is this image tall? 16 00:01:10,290 --> 00:01:14,470 So that's kind of a yes, no question. By convention, whenever we design a 17 00:01:14,470 --> 00:01:20,030 function that produces the answer to a yes, no or true, false question. 18 00:01:20,030 --> 00:01:26,750 We designed that function to produce a Boolean, so we'll say Boolean here, okay? 19 00:01:26,750 --> 00:01:30,630 And now what's the purpose going to be? The purpose is going to be something 20 00:01:30,630 --> 00:01:37,630 about, if the image is tall. And the key thing is so far, I've only 21 00:01:37,630 --> 00:01:41,290 said it produces a boolean, but I haven't said what true means. 22 00:01:41,290 --> 00:01:46,690 So you want to say in the purpose, produce true if the image is tall. 23 00:01:46,690 --> 00:01:49,290 You need to distinguish which does true mean. 24 00:01:49,290 --> 00:01:51,910 Does true mean that its tall or that its not tall? 25 00:01:51,910 --> 00:01:57,190 So whenever you got a function producing a, a boolean, your purpose has to be very 26 00:01:57,190 --> 00:02:01,350 clear about what true means, and by implication, what false means. 27 00:02:01,350 --> 00:02:08,120 So let's see, here's a stub. And this didn't tell us what name of a 28 00:02:08,120 --> 00:02:10,860 function to use. The problem statement didn't tell us what 29 00:02:10,860 --> 00:02:14,070 name to use. That's usually going to be the case. 30 00:02:14,070 --> 00:02:16,890 You're usually going to have to invent the name of a function when you design 31 00:02:16,890 --> 00:02:19,770 it. And it turns out that in the programming 32 00:02:19,770 --> 00:02:25,680 language we're using, there's a convention that functions that produce a 33 00:02:25,680 --> 00:02:27,682 boolean. Functions that produce an answer to a 34 00:02:27,682 --> 00:02:31,870 yes, no question or a true, false question, have a name that ends in 35 00:02:31,870 --> 00:02:35,000 question mark. So we're going to call this function tall 36 00:02:35,000 --> 00:02:40,990 question mark. It's going to consume image and a good 37 00:02:40,990 --> 00:02:46,060 dummy answer is false. So that would be the stub. 38 00:02:46,060 --> 00:02:52,689 And now we can write some tests. So let's see, check, expect, tall 39 00:02:52,689 --> 00:03:01,480 question mark, let's see I need an image, so let's take a rectangle. 40 00:03:01,480 --> 00:03:04,172 Oh, wait a minute, before I forget here, I'm using rectangle. 41 00:03:04,172 --> 00:03:11,329 So let me quickly go up top here and say require 2htdp/image. 42 00:03:11,329 --> 00:03:22,470 So I'm going to make a rectangle that let's say, is 2 wide and 3 high, and is 43 00:03:22,470 --> 00:03:25,010 red. The color doesn't really matter here but, 44 00:03:25,010 --> 00:03:29,160 rectangle needs the arguments. Let's see, it seems to me that rectangle 45 00:03:29,160 --> 00:03:32,740 that's 3 high and 2 wide is tall, so, we'll say true. 46 00:03:32,740 --> 00:03:38,990 Now, I want you to ask yourself right now. 47 00:03:38,990 --> 00:03:44,880 How many tests does this function need? The right number of tests for a function, 48 00:03:44,880 --> 00:03:47,220 is going to be an issue we talk about more, and more during the course. 49 00:03:48,250 --> 00:03:50,750 How many do you think this function needs? 50 00:03:53,500 --> 00:03:58,850 Write down your answer, or just remember it, and, we'll see where we end up. 51 00:03:58,850 --> 00:04:03,360 For now I'm just going to kind of, assume that it only needs this one test. 52 00:04:03,360 --> 00:04:05,811 That won't turn out to be right but we'll see what happens. 53 00:04:05,811 --> 00:04:12,225 Let me run the test and there's one test and it runs and fails. 54 00:04:12,225 --> 00:04:21,770 So it's well formed, so we can keep going. 55 00:04:21,770 --> 00:04:28,070 Let's see, this is the stub, we'll comment it out, all right, the template, 56 00:04:28,070 --> 00:04:37,990 the template is tall? img...img, we'll make a copy of that. 57 00:04:37,990 --> 00:04:53,080 And we'll comment out the original template, we'll label it as the template. 58 00:04:53,080 --> 00:04:59,740 And now let's see what does it mean the function let's see these functions have 59 00:04:59,740 --> 00:05:03,320 two cases right? Sometimes its tall and sometimes its not 60 00:05:03,320 --> 00:05:09,075 tall. So when you have two cases you can use an 61 00:05:09,075 --> 00:05:13,510 if because that be the case where it is tall and the case where it isn't. 62 00:05:13,510 --> 00:05:17,616 And what I like to do whenever I add an if to my template. 63 00:05:17,616 --> 00:05:28,480 Is I put in the f, and then I make myself three copies of the rest of the template. 64 00:05:28,480 --> 00:05:31,660 As a way of saying, okay, now I've got the if in there and I need to decide what 65 00:05:31,660 --> 00:05:41,470 happens here. Now let's see , tall involves comparing 66 00:05:41,470 --> 00:05:53,480 the width to the height, so let's see. If the image height of the image is 67 00:05:53,480 --> 00:05:59,890 greater than the image width of the image. 68 00:05:59,890 --> 00:06:06,370 Let's see, if that's true, then the image is tall, and so I should produce true, 69 00:06:06,370 --> 00:06:23,452 and otherwise, I should produce false. Well, let's try running that. 70 00:06:23,452 --> 00:06:29,400 Okay the test passed, the test passed, the test passed, but are we done? 71 00:06:31,710 --> 00:06:36,970 Have we really tested this function? Well one clue that we haven't Dr Racket 72 00:06:36,970 --> 00:06:40,570 is giving right here in the way it's colored this false. 73 00:06:41,600 --> 00:06:44,910 Depending on how you have your DrRacket configured, it might actually just 74 00:06:44,910 --> 00:06:50,050 highlight this false with black. But in both cases, what it's saying is 75 00:06:50,050 --> 00:06:55,960 it's saying, hey, this expression here was never evaluated. 76 00:06:55,960 --> 00:07:00,800 There's this concept called code coverage for a test, or test coverage, which says, 77 00:07:00,800 --> 00:07:05,230 given all my tests, how much of the code is actually being evaluated? 78 00:07:06,610 --> 00:07:12,270 And if the answer is not all of the code, then you don't have enough tests, because 79 00:07:12,270 --> 00:07:15,309 what if the piece of code that isn't evaluated is wrong? 80 00:07:16,430 --> 00:07:22,020 You haven't tested that piece of code. So whenever you run your tests, if you 81 00:07:22,020 --> 00:07:26,720 see code that's highlighted that says that it didn't get evaluated, then you 82 00:07:26,720 --> 00:07:30,920 know for sure you need more tests. And what's happening, of course, in this 83 00:07:30,920 --> 00:07:35,535 case is we tested the case where it is tall But we didn't test the case where it 84 00:07:35,535 --> 00:07:38,650 isn't tall. In this case we do that fairly 85 00:07:38,650 --> 00:07:45,290 straightforwardly by copying the first test, and just swapping these two around. 86 00:07:45,290 --> 00:07:50,620 And saying, well in that case, it's false. 87 00:07:50,620 --> 00:07:56,760 Now let's run it, both tests pass. But are we really done? 88 00:07:56,760 --> 00:07:59,340 Let me make this a little bit, give us a bit more room here. 89 00:07:59,340 --> 00:08:03,420 Are we really done? At this point, what you might think of 90 00:08:03,420 --> 00:08:08,635 is, hey, wait a minute. There's one more case. 91 00:08:08,635 --> 00:08:14,070 What if,it's the image width and the height are the same? 92 00:08:14,070 --> 00:08:18,380 What should happen then? And this is a thing that happens in 93 00:08:18,380 --> 00:08:22,950 function and program design all the time. You realize partway through the design 94 00:08:22,950 --> 00:08:26,050 process that there's a boundary condition, or sometimes we call it a 95 00:08:26,050 --> 00:08:30,110 corner case, that you hadn't quite thought of. 96 00:08:30,110 --> 00:08:34,200 It's perfectly fine for that to happen, but when it happens, when you say to 97 00:08:34,200 --> 00:08:37,290 yourself, wait a minute, what if the width and height are the same? 98 00:08:37,290 --> 00:08:41,000 You need to immediately do a couple of things. 99 00:08:41,000 --> 00:08:47,040 First, write an example for. Then decide what the behavior is. 100 00:08:47,040 --> 00:08:50,909 And I'm going to decide in this case that if your width and height are the same, 101 00:08:50,909 --> 00:08:57,550 you're not tall. So write the example, write the expected 102 00:08:57,550 --> 00:09:02,022 result, fix the purpose, height is greater than width. 103 00:09:02,022 --> 00:09:14,100 So that's unambiguous in the purpose, and if what you decided required you to 104 00:09:14,100 --> 00:09:17,640 change the function, change the function. In this case it didn't. 105 00:09:17,640 --> 00:09:21,080 But if I had decided this the other way, I would have to change that to a greater 106 00:09:21,080 --> 00:09:23,070 than or equal. And now, run the tests again. 107 00:09:23,070 --> 00:09:28,860 Now all three tests are passing. So that's the design effect function, 108 00:09:28,860 --> 00:09:32,270 that works. When I run it and the tests pass, all my 109 00:09:32,270 --> 00:09:36,320 code is evaluated, so I've got good test coverage. 110 00:09:36,320 --> 00:09:39,640 So, I'm pretty good here. At this point, I just want to make one 111 00:09:39,640 --> 00:09:44,420 minor detail point, which is whenever you have an expression of the form, if 112 00:09:44,420 --> 00:09:52,975 something, true, false. You can also replace that by just this 113 00:09:52,975 --> 00:10:03,110 simpler thing. Let me comment this one out, Racket > 114 00:10:03,110 --> 00:10:08,280 Comment Out with Semicolons. Why are these two the same? 115 00:10:08,280 --> 00:10:12,970 Well, look this one says if this expression evaluates to true, then 116 00:10:12,970 --> 00:10:16,050 produce true. Otherwise, if this expression evaluates 117 00:10:16,050 --> 00:10:19,550 to false, then produce false. So that's really just the same as the 118 00:10:19,550 --> 00:10:23,100 expression itself. Either this expression evaluates to true 119 00:10:23,100 --> 00:10:28,866 or it evaluates to false. So whenever you have, if something true, 120 00:10:28,866 --> 00:10:33,830 false, you can just replace it with the question itself. 121 00:10:33,830 --> 00:10:37,145 And in a normal program, once you've done something like that, you would clean this 122 00:10:37,145 --> 00:10:42,940 up, you'd Delete that out from there. And in a couple weeks, you also won't 123 00:10:42,940 --> 00:10:47,650 leave the stub and template behind. So now you've seen the How To Design 124 00:10:47,650 --> 00:10:50,300 Functions recipe. And you've seen me work through four 125 00:10:50,300 --> 00:10:54,000 examples of it, where each example showed some more wrinkles to the process. 126 00:10:55,350 --> 00:10:59,510 What you should do now is go work through all the practice problems for this week 127 00:10:59,510 --> 00:11:01,370 and then do the homework problems and the quiz. 128 00:11:03,000 --> 00:11:04,810 Let me stress sometrhing about this material. 129 00:11:04,810 --> 00:11:08,060 I ja, I just can't make this point strongly enough. 130 00:11:08,060 --> 00:11:11,660 This is the kind of material that you learn by doing. 131 00:11:11,660 --> 00:11:15,850 I really want to encourage you, don't look at the problem and then look at the 132 00:11:15,850 --> 00:11:18,840 solution. If you do that, you're going to say to 133 00:11:18,840 --> 00:11:23,790 yourself, oh I know how to do this. You need to actually take the blank 134 00:11:23,790 --> 00:11:28,190 starter file and work through the problem yourself from beginning to end. 135 00:11:28,190 --> 00:11:30,260 That's the only way to learn this kind of material. 136 00:11:31,790 --> 00:11:35,050 At any rate, have fun with the practice problems and the homework and I'll see 137 00:11:35,050 --> 00:11:35,600 you next week.