1 00:00:00,000 --> 00:00:02,400 ANNOUNCER: Open content is provided under creative 2 00:00:02,400 --> 00:00:03,830 commons license. 3 00:00:03,830 --> 00:00:06,840 Your support will help MIT OpenCourseWare continue to 4 00:00:06,840 --> 00:00:10,510 offer high-quality educational resources for free. 5 00:00:10,510 --> 00:00:13,380 To make a donation, or view additional materials from 6 00:00:13,380 --> 00:00:17,490 hundreds of MIT courses, visit MIT OpenCourseWare at 7 00:00:17,490 --> 00:00:19,930 ocw.mit.edu . 8 00:00:19,930 --> 00:00:23,130 PROFESSOR ERIC GRIMSON: As I've done in the previous 9 00:00:23,130 --> 00:00:25,810 lectures, let me set the stage for what we've been doing, so 10 00:00:25,810 --> 00:00:30,080 we can use that to talk about what we're going to do today. 11 00:00:30,080 --> 00:00:35,840 So far, we have the following in our language. 12 00:00:35,840 --> 00:00:41,760 Right, we have assignment. 13 00:00:41,760 --> 00:00:46,190 We have conditionals. 14 00:00:46,190 --> 00:00:47,520 We have input/output. 15 00:00:47,520 --> 00:00:55,350 And we have looping constructs. 16 00:00:55,350 --> 00:01:00,850 These are things like FOR and WHILE loops. 17 00:01:00,850 --> 00:01:04,430 And of course we've got some data to go with that. 18 00:01:04,430 --> 00:01:07,650 One of the things we said last time was, with that set of 19 00:01:07,650 --> 00:01:11,160 things, the ability to give values-- sorry, to give names 20 00:01:11,160 --> 00:01:14,480 to values-- the ability to make decisions, the ability to 21 00:01:14,480 --> 00:01:16,890 loop as a function of that, the ability get things in and 22 00:01:16,890 --> 00:01:21,260 out, we said that that actually gave us a language we 23 00:01:21,260 --> 00:01:26,640 said was Turing-complete. 24 00:01:26,640 --> 00:01:30,480 And that meant, in English, that this was enough to write 25 00:01:30,480 --> 00:01:32,590 any program. 26 00:01:32,590 --> 00:01:34,600 Now that's a slight lie-- or actually in these days of 27 00:01:34,600 --> 00:01:37,890 political debates, a slight misspeaking, a wonderful 28 00:01:37,890 --> 00:01:40,700 word-- it is technically correct. 29 00:01:40,700 --> 00:01:43,310 It is enough to allow us to write any program, but it's 30 00:01:43,310 --> 00:01:47,620 not enough to allow us to easily write any program. 31 00:01:47,620 --> 00:01:50,990 And so I joked, badly, I'll agree, at the end of last 32 00:01:50,990 --> 00:01:52,990 lecture, that we can just stop now, go straight to the final 33 00:01:52,990 --> 00:01:54,700 exam, because this is all you need to know. 34 00:01:54,700 --> 00:01:58,000 The point is, yes it's enough to start with, but we want to 35 00:01:58,000 --> 00:02:00,730 add things to this that let us problem solve well. 36 00:02:00,730 --> 00:02:03,970 And one of the things to think about is, even though I've got 37 00:02:03,970 --> 00:02:06,730 all of that, let's think about what I could do, if I wanted 38 00:02:06,730 --> 00:02:09,450 to write a piece of code. 39 00:02:09,450 --> 00:02:11,820 Right now, you've got to write it in one file. 40 00:02:11,820 --> 00:02:14,570 It's a long sequence of instructions, it starts at the 41 00:02:14,570 --> 00:02:17,520 beginning, walks through, may jump around a little bit, but 42 00:02:17,520 --> 00:02:19,830 eventually comes down at the end. 43 00:02:19,830 --> 00:02:21,660 It's okay for the things you're doing for the early 44 00:02:21,660 --> 00:02:23,110 problem sets. 45 00:02:23,110 --> 00:02:24,320 Ten lines of code. 46 00:02:24,320 --> 00:02:25,900 Twenty lines of code. 47 00:02:25,900 --> 00:02:27,970 Imagine instead, you're writing code that's a hundred 48 00:02:27,970 --> 00:02:31,130 thousand lines, a million lines, of code. 49 00:02:31,130 --> 00:02:34,050 You don't want to write it in this form. 50 00:02:34,050 --> 00:02:36,400 All right, and the reason you don't want to do that is, 51 00:02:36,400 --> 00:02:37,020 well, several. 52 00:02:37,020 --> 00:02:39,240 First of all, it's really hard to figure out where everything 53 00:02:39,240 --> 00:02:40,840 is, where everything goes, making sure I'm 54 00:02:40,840 --> 00:02:42,370 in the right place. 55 00:02:42,370 --> 00:02:45,760 To use an ancient expression from the 1970's, which only 56 00:02:45,760 --> 00:02:48,700 John and I will appreciate, it's really hard to grok what 57 00:02:48,700 --> 00:02:50,950 that code is doing, to understand what it's trying to 58 00:02:50,950 --> 00:02:52,370 make happen. 59 00:02:52,370 --> 00:02:55,830 And the reason that that's the case is, what we don't have, 60 00:02:55,830 --> 00:03:00,520 are two important things. 61 00:03:00,520 --> 00:03:12,460 We don't have decomposition, and we don't have abstraction. 62 00:03:12,460 --> 00:03:13,360 And that's what we're going to add today. 63 00:03:13,360 --> 00:03:14,160 So what does that mean? 64 00:03:14,160 --> 00:03:18,880 Those are fancy terms. Decomposition is a way of 65 00:03:18,880 --> 00:03:20,710 putting structure onto the code. 66 00:03:20,710 --> 00:03:23,650 It's a way of breaking the code up into modules. 67 00:03:23,650 --> 00:03:25,580 Modules that makes sense on their own. 68 00:03:25,580 --> 00:03:28,010 Modules that we can reuse in multiple places. 69 00:03:28,010 --> 00:03:29,950 Modules that, if you like, isolate 70 00:03:29,950 --> 00:03:32,960 components of the process. 71 00:03:32,960 --> 00:03:35,550 And abstraction is related to that, abstraction is going to 72 00:03:35,550 --> 00:03:37,980 let us suppress details. 73 00:03:37,980 --> 00:03:42,420 It's going to let us bury away the specifics of something, 74 00:03:42,420 --> 00:03:44,980 and treat that computation like a black box. 75 00:03:44,980 --> 00:03:47,420 And by black box, I mean, literally behaves like a 76 00:03:47,420 --> 00:03:49,100 mysterious little black box. 77 00:03:49,100 --> 00:03:52,200 You put some inputs in, it has a contract that says if you 78 00:03:52,200 --> 00:03:54,600 put the right kind of inputs in you'll get a specific 79 00:03:54,600 --> 00:03:57,060 output coming out, but you don't have to know what's 80 00:03:57,060 --> 00:03:58,510 inside of that box. 81 00:03:58,510 --> 00:04:01,250 And that abstraction is really important. 82 00:04:01,250 --> 00:04:04,960 Again, imagine if I'm a writing a piece of code. 83 00:04:04,960 --> 00:04:07,710 I want to just use it, I shouldn't have to worry about 84 00:04:07,710 --> 00:04:09,840 what variables I use inside of it, I have shouldn't have to 85 00:04:09,840 --> 00:04:12,060 worry about where that is in the code, I should be able to 86 00:04:12,060 --> 00:04:13,880 just abstract it away. 87 00:04:13,880 --> 00:04:16,950 And that's what we want to add today, are those two things. 88 00:04:16,950 --> 00:04:19,770 Now, our mechanism for doing that-- or at least one 89 00:04:19,770 --> 00:04:23,120 mechanism, I shouldn't say the only one-- one mechanism for 90 00:04:23,120 --> 00:04:30,810 doing that is going to be to add functions to our language. 91 00:04:30,810 --> 00:04:35,250 Now, the point of a function is that it's going to provide 92 00:04:35,250 --> 00:04:37,030 both of these things, so the first thing it's going to do 93 00:04:37,030 --> 00:04:44,730 is, it's going to let us break up into modules. 94 00:04:44,730 --> 00:04:51,060 Second thing they're going to do is let us suppress detail. 95 00:04:51,060 --> 00:04:53,140 And in essence what that does is, the functions, and we're 96 00:04:53,140 --> 00:04:54,920 going to look at a bunch of examples in a second, these 97 00:04:54,920 --> 00:04:58,560 functions are going to give us a way to, in some or in one 98 00:04:58,560 --> 00:05:00,640 way of thinking about it is to create new primitives. 99 00:05:00,640 --> 00:05:10,360 And I'm going to put those in quotes, it's a generalization. 100 00:05:10,360 --> 00:05:12,480 What do I mean by that? 101 00:05:12,480 --> 00:05:14,980 The idea of a function is, that I'm going to capture a 102 00:05:14,980 --> 00:05:17,850 common pattern of computation. 103 00:05:17,850 --> 00:05:18,700 Computing square root. 104 00:05:18,700 --> 00:05:21,100 I'm going to capture it in a piece of code, I'm going to be 105 00:05:21,100 --> 00:05:24,300 able to refer to it by a name, and I'm going to suppress the 106 00:05:24,300 --> 00:05:26,910 details, meaning inside of that computation, you don't 107 00:05:26,910 --> 00:05:27,730 need to know what it does. 108 00:05:27,730 --> 00:05:29,250 You just need to know, if I give it the right kind of 109 00:05:29,250 --> 00:05:31,850 input, it'll give me back an input that satisfies the 110 00:05:31,850 --> 00:05:34,320 contract that I set up. 111 00:05:34,320 --> 00:05:37,555 And that in essence says, I've just created the equivalent of 112 00:05:37,555 --> 00:05:38,840 a new primitive. 113 00:05:38,840 --> 00:05:41,550 Same way that I have multiplication or division as 114 00:05:41,550 --> 00:05:43,940 a primitive, functions are going to give me, or somebody 115 00:05:43,940 --> 00:05:46,430 else who wrote them for me as part of a library, a new 116 00:05:46,430 --> 00:05:48,440 primitive that I'm going to be able to use. 117 00:05:48,440 --> 00:05:50,580 And that gives me a lot of power in terms of what I want 118 00:05:50,580 --> 00:05:52,680 to have inside of the language. 119 00:05:52,680 --> 00:05:55,520 OK. 120 00:05:55,520 --> 00:05:58,390 So, let's look at an example. 121 00:05:58,390 --> 00:06:01,060 To try to see what we're going to do with this. 122 00:06:01,060 --> 00:06:03,240 Before I do that though, let me try and give you an analogy 123 00:06:03,240 --> 00:06:06,060 to keep this in mind of why we want to basically build these 124 00:06:06,060 --> 00:06:08,310 abstractions and what we need in order to 125 00:06:08,310 --> 00:06:10,300 have them work together. 126 00:06:10,300 --> 00:06:13,520 So here's the supposed to say silly analogy. 127 00:06:13,520 --> 00:06:15,030 You can tell my jokes are always bad. 128 00:06:15,030 --> 00:06:17,090 John's are much better, by the way, which is why Thursday 129 00:06:17,090 --> 00:06:19,560 will be a much better lay-- a better lecture. 130 00:06:19,560 --> 00:06:20,380 But here's the example. 131 00:06:20,380 --> 00:06:24,130 You've been hired by PBS to produce a nice thirteen-hour 132 00:06:24,130 --> 00:06:28,310 documentary, or drama, that's going to run. 133 00:06:28,310 --> 00:06:32,220 And, you know, you start by saying, OK, thirteen hours, 134 00:06:32,220 --> 00:06:34,390 I'm going to break it up into thirteen different chunks. 135 00:06:34,390 --> 00:06:37,190 I'm going to assign each chunk to a different writer. 136 00:06:37,190 --> 00:06:39,640 And they're going to go off and write that element, that 137 00:06:39,640 --> 00:06:41,800 hour's worth of stuff. 138 00:06:41,800 --> 00:06:45,620 You can imagine what you get: each hours worth of drama, if 139 00:06:45,620 --> 00:06:49,130 you like, may be great, but it may have absolutely nothing to 140 00:06:49,130 --> 00:06:51,500 do with the other twelve hours. 141 00:06:51,500 --> 00:06:54,470 And unless, you know, you've been hired to do Pirandello's 142 00:06:54,470 --> 00:06:57,420 Six Characters In Search Of An Author, this is not a great 143 00:06:57,420 --> 00:06:58,320 thing, because you get something 144 00:06:58,320 --> 00:07:00,220 that is really confusing. 145 00:07:00,220 --> 00:07:01,690 Now, what's the point of the analogy? 146 00:07:01,690 --> 00:07:03,465 What do I need for those writers to 147 00:07:03,465 --> 00:07:04,910 all interact together? 148 00:07:04,910 --> 00:07:06,880 I need a specification. 149 00:07:06,880 --> 00:07:10,590 I need a contract that says, here's what I want in terms of 150 00:07:10,590 --> 00:07:12,960 things that you're going to take as input, to begin your 151 00:07:12,960 --> 00:07:15,450 part of the drama, here's what you're going to produce at the 152 00:07:15,450 --> 00:07:17,610 output, and the details of what they do 153 00:07:17,610 --> 00:07:20,050 inside are up to them. 154 00:07:20,050 --> 00:07:22,580 An idea of abstraction, that idea of specification, is 155 00:07:22,580 --> 00:07:25,500 exactly what we want to use inside of our functions. 156 00:07:25,500 --> 00:07:27,520 We won't make you write dramas like Pirandello, but we're 157 00:07:27,520 --> 00:07:29,360 going to try make you at least write good code. 158 00:07:29,360 --> 00:07:30,450 And that's we're going to try and do. 159 00:07:30,450 --> 00:07:31,790 All right. 160 00:07:31,790 --> 00:07:33,910 Let's set the stage for it. 161 00:07:33,910 --> 00:07:35,890 Up on the screen, I've got-- 162 00:07:35,890 --> 00:07:39,420 I commented it out, but I've got a piece of code that 163 00:07:39,420 --> 00:07:41,640 you've seen before, right up here. 164 00:07:41,640 --> 00:07:42,440 OK? 165 00:07:42,440 --> 00:07:43,680 What is that? 166 00:07:43,680 --> 00:07:45,120 It's the piece of code we wrote for computing square 167 00:07:45,120 --> 00:07:48,160 roots, square roots of actually perfect squares. 168 00:07:48,160 --> 00:07:48,610 [UNINTELLIGIBLE] 169 00:07:48,610 --> 00:07:51,530 Just to remind you what it does, we bound x to some 170 00:07:51,530 --> 00:07:55,910 value, we set up an initial variable called ANS or answer, 171 00:07:55,910 --> 00:07:57,960 and then we run through a little loop. 172 00:07:57,960 --> 00:07:59,820 All right, we're-- well actually, I should say that 173 00:07:59,820 --> 00:08:02,960 better, we first check to see, is x greater than or equal to 174 00:08:02,960 --> 00:08:05,010 zero, if it's not, then we come down here and we print 175 00:08:05,010 --> 00:08:07,160 something out, otherwise we run through a little loop to 176 00:08:07,160 --> 00:08:09,230 get the answer, and then we check it and we 177 00:08:09,230 --> 00:08:10,700 spit something out. 178 00:08:10,700 --> 00:08:13,340 It does the computation, that's fine. 179 00:08:13,340 --> 00:08:16,450 Suppose I want to compute square roots a lot of places 180 00:08:16,450 --> 00:08:18,490 in a big chunk of code. 181 00:08:18,490 --> 00:08:22,060 Right now, I have to take that piece of code and replicate it 182 00:08:22,060 --> 00:08:24,830 everywhere I want in my larger file. 183 00:08:24,830 --> 00:08:27,920 And I've got to worry about, is somebody else using ANS, 184 00:08:27,920 --> 00:08:30,300 answer, as a variable, in which case I've got to be 185 00:08:30,300 --> 00:08:30,810 really careful. 186 00:08:30,810 --> 00:08:32,950 Is somebody else using x as a variable? 187 00:08:32,950 --> 00:08:35,620 I've got to deal with a lot of those details. 188 00:08:35,620 --> 00:08:36,600 I want to abstract that. 189 00:08:36,600 --> 00:08:40,310 And the abstraction you see, right here. 190 00:08:40,310 --> 00:08:42,580 I'm going to highlight it for a second so you can see it. 191 00:08:42,580 --> 00:08:44,980 I want you to look at it on the handout as well. 192 00:08:44,980 --> 00:08:48,140 This is the creation of a function. 193 00:08:48,140 --> 00:08:51,480 And I want to describe both the syntax, what we're doing, 194 00:08:51,480 --> 00:08:53,350 and then the semantics of how do we use it and 195 00:08:53,350 --> 00:08:54,090 what does that mean. 196 00:08:54,090 --> 00:08:56,320 So. 197 00:08:56,320 --> 00:09:01,150 Here's the syntax of the function. 198 00:09:01,150 --> 00:09:04,490 First of all, we have a keyword. def. 199 00:09:04,490 --> 00:09:07,260 Definition or define, depending on which sort of 200 00:09:07,260 --> 00:09:08,420 piece of history you come from. 201 00:09:08,420 --> 00:09:10,880 This is a keyword to Python that says, when it reads this 202 00:09:10,880 --> 00:09:13,480 in the file, it says, I'm creating a definition. 203 00:09:13,480 --> 00:09:15,050 I'm creating a function. 204 00:09:15,050 --> 00:09:17,520 And that's follow-- so this is, let me say this is a 205 00:09:17,520 --> 00:09:24,450 keyboard-- that is followed immediately by a name. 206 00:09:24,450 --> 00:09:25,260 And this equates to that. 207 00:09:25,260 --> 00:09:28,390 In this case, sqrt, square root. 208 00:09:28,390 --> 00:09:30,170 I'm saying, this is the name I'm going to 209 00:09:30,170 --> 00:09:31,370 give to this function. 210 00:09:31,370 --> 00:09:33,640 This is the name to which I'm going to refer when I want to 211 00:09:33,640 --> 00:09:34,420 use this function. 212 00:09:34,420 --> 00:09:35,910 All right? 213 00:09:35,910 --> 00:09:41,610 And notice, immediately after that name, we have an open and 214 00:09:41,610 --> 00:09:45,370 close paren with another variable name inside of that. 215 00:09:45,370 --> 00:09:56,190 And this defines formal parameters of this function. 216 00:09:56,190 --> 00:09:56,570 Yup. 217 00:09:56,570 --> 00:09:58,350 PROFESSOR JOHN GUTTAG: [INAUDIBLE] 218 00:09:58,350 --> 00:09:59,650 PROFESSOR ERIC GRIMSON: It does indeed, thank you. 219 00:09:59,650 --> 00:10:02,730 This is me being a Scheme hacker, not a Python hacker. 220 00:10:02,730 --> 00:10:04,780 Yes, def has to be lowercase or won't recognize it. 221 00:10:04,780 --> 00:10:06,650 Thank you, John. 222 00:10:06,650 --> 00:10:08,120 OK. def's the keyword. 223 00:10:08,120 --> 00:10:10,600 I'm creating a function. sqrt-- again, I'm being 224 00:10:10,600 --> 00:10:12,760 careful about case-sensitive, I'm using all lowercase here, 225 00:10:12,760 --> 00:10:15,460 followed by an open paren, and I said, formal parameters. 226 00:10:15,460 --> 00:10:17,400 We'll see there could be more than one there. 227 00:10:17,400 --> 00:10:19,520 We're going to come back to what they mean in a second, 228 00:10:19,520 --> 00:10:22,510 but for now, think of them as, or think of x, in this case, 229 00:10:22,510 --> 00:10:23,980 as the place holder. 230 00:10:23,980 --> 00:10:27,540 This place holder is saying, if you give me a value for x, 231 00:10:27,540 --> 00:10:30,510 inside the body of this function I'm going to use that 232 00:10:30,510 --> 00:10:32,380 value everywhere I see x. 233 00:10:32,380 --> 00:10:32,790 Question. 234 00:10:32,790 --> 00:10:36,040 STUDENT: [INAUDIBLE] 235 00:10:36,040 --> 00:10:36,630 PROFESSOR ERIC GRIMSON: Ah, we're going to come back to 236 00:10:36,630 --> 00:10:37,310 this in a second. 237 00:10:37,310 --> 00:10:39,120 But the question was, do I always need an input? 238 00:10:39,120 --> 00:10:42,440 I can have functions with no parameters, that's fine, I 239 00:10:42,440 --> 00:10:45,910 will still need the open and close paren there to identify 240 00:10:45,910 --> 00:10:46,930 that I have no parameters. 241 00:10:46,930 --> 00:10:48,130 We're going to see an example in a second. 242 00:10:48,130 --> 00:10:49,410 Good question. 243 00:10:49,410 --> 00:10:51,240 Actually, I've got to get rid of this candy, so since it was 244 00:10:51,240 --> 00:10:54,700 a good question, here you go. 245 00:10:54,700 --> 00:10:56,280 Nice catch. 246 00:10:56,280 --> 00:10:58,160 Almost. Sorry. 247 00:10:58,160 --> 00:10:59,780 OK. 248 00:10:59,780 --> 00:11:00,420 No, I'm not. 249 00:11:00,420 --> 00:11:00,700 I'm sorry. 250 00:11:00,700 --> 00:11:02,700 I thought you had it, and then I've got the wrong glasses on 251 00:11:02,700 --> 00:11:04,560 and I realized you didn't, so I will, ah come 252 00:11:04,560 --> 00:11:05,420 back to that later. 253 00:11:05,420 --> 00:11:06,070 What are we doing here? 254 00:11:06,070 --> 00:11:08,930 We got definition, we got name, we got a set of formal 255 00:11:08,930 --> 00:11:09,750 parameters. 256 00:11:09,750 --> 00:11:10,390 Right. 257 00:11:10,390 --> 00:11:13,160 If you look at the rest of that code, gee, it looks a lot 258 00:11:13,160 --> 00:11:14,900 like what I had elsewhere. 259 00:11:14,900 --> 00:11:16,100 Of what I had outside of it, right? 260 00:11:16,100 --> 00:11:18,610 It's running through a similar set of loops. 261 00:11:18,610 --> 00:11:21,130 So in some sets, as long as x has the value I want, it ought 262 00:11:21,130 --> 00:11:22,770 to do the right thing. 263 00:11:22,770 --> 00:11:24,810 However, there's a couple of other changes there that we 264 00:11:24,810 --> 00:11:26,280 want to highlight. 265 00:11:26,280 --> 00:11:31,850 In particular, notice-- let me highlight it for you, if I can 266 00:11:31,850 --> 00:11:34,550 find it with the wrong glasses on-- we've got 267 00:11:34,550 --> 00:11:37,860 these return commands. 268 00:11:37,860 --> 00:11:42,040 So return is another keyword. 269 00:11:42,040 --> 00:11:48,710 And it basically says, when you get to this point in the 270 00:11:48,710 --> 00:11:52,390 computation, stop the computation. 271 00:11:52,390 --> 00:11:56,460 Literally, return the control from this function, and take 272 00:11:56,460 --> 00:11:59,480 the value of the next expression, and return that as 273 00:11:59,480 --> 00:12:02,290 the value of the whole computation. 274 00:12:02,290 --> 00:12:04,530 Now, the one that we're most interested in is the one 275 00:12:04,530 --> 00:12:07,340 where, in fact, it gets out ANS, so you see down here in 276 00:12:07,340 --> 00:12:10,310 the code, there's a spot where it's going to return the value 277 00:12:10,310 --> 00:12:12,370 of ANS, which is what we want, right? 278 00:12:12,370 --> 00:12:14,440 That's the thing that holds the value that we intended to 279 00:12:14,440 --> 00:12:15,940 have. 280 00:12:15,940 --> 00:12:17,950 But there's another couple of places in that code where it's 281 00:12:17,950 --> 00:12:20,910 got this funky-looking thing, return none, and notice none's 282 00:12:20,910 --> 00:12:22,830 in a different color. 283 00:12:22,830 --> 00:12:33,830 None is a special value, and it has the following 284 00:12:33,830 --> 00:12:38,300 slightly-odd behavior: it is a value, we can return it-- 285 00:12:38,300 --> 00:12:42,460 God bless-- but what none says is, there is no value coming 286 00:12:42,460 --> 00:12:44,220 back from this computation. 287 00:12:44,220 --> 00:12:46,670 So when it is returned, and we'll see this in a second, to 288 00:12:46,670 --> 00:12:49,180 the interpreter, it doesn't print. 289 00:12:49,180 --> 00:12:49,870 OK. 290 00:12:49,870 --> 00:12:51,150 It simply doesn't print anything. 291 00:12:51,150 --> 00:12:53,950 Nonetheless, it is actually a value and we can use it, for 292 00:12:53,950 --> 00:12:55,860 example, to do comparisons. 293 00:12:55,860 --> 00:12:58,250 If we want to know, did this function return a value or 294 00:12:58,250 --> 00:13:01,620 not, rather than reserving, say, -1 or some other special 295 00:13:01,620 --> 00:13:03,380 thing which you might want to use some other ways, it 296 00:13:03,380 --> 00:13:05,740 literally returns this very special value that says, there 297 00:13:05,740 --> 00:13:09,740 is no actual value return from this computation. 298 00:13:09,740 --> 00:13:11,480 OK. 299 00:13:11,480 --> 00:13:15,270 Note, by the way, if I chase through each possible path, 300 00:13:15,270 --> 00:13:18,790 like there's some IFs in here, there's some places to go, at 301 00:13:18,790 --> 00:13:21,340 least in this piece of code, every possible path through 302 00:13:21,340 --> 00:13:23,800 this code ends in a return. 303 00:13:23,800 --> 00:13:25,700 And that's a good programming discipline, to 304 00:13:25,700 --> 00:13:27,020 make sure that happens. 305 00:13:27,020 --> 00:13:28,900 There's an exception, which we'll see in a second, but 306 00:13:28,900 --> 00:13:30,940 I'll highlight, which is, if we get to the end of the 307 00:13:30,940 --> 00:13:34,170 procedure, there's sort of an implicit return there. 308 00:13:34,170 --> 00:13:36,140 In fact, a return of none, in that case. 309 00:13:36,140 --> 00:13:36,750 It comes out of it. 310 00:13:36,750 --> 00:13:38,060 But if I look at this, right? 311 00:13:38,060 --> 00:13:41,040 If I come into this code, I'm going to check this branch 312 00:13:41,040 --> 00:13:43,790 first, if it's not true, ah, there's a return at the end of 313 00:13:43,790 --> 00:13:44,660 that branch. 314 00:13:44,660 --> 00:13:48,460 If it is true, I do that, and then I've got a second test. 315 00:13:48,460 --> 00:13:50,830 If it's true, I return, otherwise a return. 316 00:13:50,830 --> 00:13:52,960 So there's a return branch on every possible 317 00:13:52,960 --> 00:13:54,350 path through the code. 318 00:13:54,350 --> 00:13:55,870 And that's valuable, it's something you want to think 319 00:13:55,870 --> 00:13:59,120 about as your right your own. 320 00:13:59,120 --> 00:14:00,820 OK. 321 00:14:00,820 --> 00:14:04,140 What do I do to use this, in particular? 322 00:14:04,140 --> 00:14:07,160 How do I invoke this? 323 00:14:07,160 --> 00:14:17,880 OK, so I'm going to invoke a function by passing in values 324 00:14:17,880 --> 00:14:24,100 for the parameters. 325 00:14:24,100 --> 00:14:29,770 And in this case, that literally means typing sqrt, 326 00:14:29,770 --> 00:14:34,650 with some value inside the parens. 327 00:14:34,650 --> 00:14:36,030 OK. 328 00:14:36,030 --> 00:14:38,050 Now, let's just try this out to see what happens. 329 00:14:38,050 --> 00:14:42,440 I'm going to make sure I've got it there, so if I type, 330 00:14:42,440 --> 00:14:50,470 for example, sqrt of 16, ah-ha! 331 00:14:50,470 --> 00:14:51,680 What did it do? 332 00:14:51,680 --> 00:14:53,130 Well, let's talk about what it did. 333 00:14:53,130 --> 00:14:58,810 What this invocation does, is the following: it binds, and 334 00:14:58,810 --> 00:15:01,460 I'm going to say this specifically for this example, 335 00:15:01,460 --> 00:15:06,680 rather than general, it binds x to 16. 336 00:15:06,680 --> 00:15:09,120 Just as you would have done with an assignment statement 337 00:15:09,120 --> 00:15:10,740 up in the top level thing. 338 00:15:10,740 --> 00:15:16,130 But this binding is local. 339 00:15:16,130 --> 00:15:19,810 Meaning it only holds within the confines of the code of 340 00:15:19,810 --> 00:15:22,000 this procedure. 341 00:15:22,000 --> 00:15:24,520 Relative to that, think of that as creating what we, I'm 342 00:15:24,520 --> 00:15:25,700 going to call a new environment. 343 00:15:25,700 --> 00:15:28,960 Relative to that, it does all the other execution we would 344 00:15:28,960 --> 00:15:30,990 do, including, notice the first instruction there is to 345 00:15:30,990 --> 00:15:32,920 the set up a binding for ANS. 346 00:15:32,920 --> 00:15:42,410 So answer, or ANS, is also bound only locally. 347 00:15:42,410 --> 00:15:44,460 Meaning, inside the confines of this 348 00:15:44,460 --> 00:15:46,280 environment of this procedure. 349 00:15:46,280 --> 00:15:49,310 ANS starts off with a value of 0 and now we just run through 350 00:15:49,310 --> 00:15:50,530 that loop just like we did before. 351 00:15:50,530 --> 00:15:53,680 Writing Increments it slowly, checking to see if ANS squared 352 00:15:53,680 --> 00:15:56,020 is bigger than x, and when it gets to that point, it checks 353 00:15:56,020 --> 00:15:58,210 to see, is it actually a perfect square or not, and it 354 00:15:58,210 --> 00:15:58,730 returns it. 355 00:15:58,730 --> 00:16:02,340 And once it returns it, it returns a value from that 356 00:16:02,340 --> 00:16:06,250 return, that in this case is just printed out. 357 00:16:06,250 --> 00:16:07,300 All right. 358 00:16:07,300 --> 00:16:08,550 Now I want to say a couple of things 359 00:16:08,550 --> 00:16:10,920 about these local bindings. 360 00:16:10,920 --> 00:16:12,310 I'm going to repeat this a second time, 361 00:16:12,310 --> 00:16:16,400 because it's important. 362 00:16:16,400 --> 00:16:28,680 These local bindings do not affect any global bindings. 363 00:16:28,680 --> 00:16:30,590 What does that mean? 364 00:16:30,590 --> 00:16:32,700 Let me show you a little example, and then we'll come 365 00:16:32,700 --> 00:16:34,240 back to this. 366 00:16:34,240 --> 00:16:36,980 I've got a little function here. 367 00:16:36,980 --> 00:16:40,670 See, I've defined f of x to be a function that takes a value 368 00:16:40,670 --> 00:16:45,060 of x in, changes x to x+1, and then just returns the value. 369 00:16:45,060 --> 00:16:45,260 OK. 370 00:16:45,260 --> 00:16:47,290 So it's just adding 1 to x. 371 00:16:47,290 --> 00:16:49,940 But I want you to see now what happens if I use this. 372 00:16:49,940 --> 00:16:53,580 Let's bind x to the value of 3. 373 00:16:53,580 --> 00:16:56,710 It's creating a binding for x in this global environment. 374 00:16:56,710 --> 00:16:57,890 This is what the interpreter sees. 375 00:16:57,890 --> 00:16:58,850 All right? 376 00:16:58,850 --> 00:17:01,710 In fact, if I look at x, its value is 3. 377 00:17:01,710 --> 00:17:08,260 Let's bind z eh let's bind z to the-- if I could type it 378 00:17:08,260 --> 00:17:15,780 would help-- say, f of 3. 379 00:17:15,780 --> 00:17:16,260 OK? 380 00:17:16,260 --> 00:17:20,420 So the value is z is 4, it's what I expect, right? 381 00:17:20,420 --> 00:17:22,820 Locally x got bound to 3, I added 1 to it, whoop-dee-doo, 382 00:17:22,820 --> 00:17:24,030 I get back a 4. 383 00:17:24,030 --> 00:17:27,540 But what's the value of x? 384 00:17:27,540 --> 00:17:29,650 It's still 3. 385 00:17:29,650 --> 00:17:32,380 The way to think of this is, again, I've got multiple 386 00:17:32,380 --> 00:17:35,430 scopes, or multiple frames, or if we're going to come back to 387 00:17:35,430 --> 00:17:37,060 those terms, I'm going to use the word environment, because 388 00:17:37,060 --> 00:17:39,750 I'm an old-time Lisp hacker, multiple environments in which 389 00:17:39,750 --> 00:17:40,810 there are bindings. 390 00:17:40,810 --> 00:17:44,680 So let me spell this out in just a little bit more detail. 391 00:17:44,680 --> 00:17:55,760 What this is saying is the following. 392 00:17:55,760 --> 00:17:57,890 When I'm talking to the interpreter, when I'm typing 393 00:17:57,890 --> 00:18:01,600 things in as I just did, to that Python environment, I'm 394 00:18:01,600 --> 00:18:03,970 getting what I'm going to call global bindings. 395 00:18:03,970 --> 00:18:15,220 I'm going to draw a little chart here. 396 00:18:15,220 --> 00:18:17,610 Think of this as the, as the world of the interpreter, in 397 00:18:17,610 --> 00:18:23,750 that I've got things like x bound to the value of 3. 398 00:18:23,750 --> 00:18:30,980 When I call or invoke a function, think of it as 399 00:18:30,980 --> 00:18:41,160 creating a local table. 400 00:18:41,160 --> 00:18:47,330 Inside that local table, I bind the formal parameter, 401 00:18:47,330 --> 00:18:51,970 which is what I do I did 16 right to some value. 402 00:18:51,970 --> 00:18:55,630 This x only gets seen by sqrt. 403 00:18:55,630 --> 00:18:59,050 Inside of there, I can bind other things, like ANS gets 404 00:18:59,050 --> 00:19:02,330 locally bound to 0, and then it increments around and 405 00:19:02,330 --> 00:19:04,520 eventually we return that value out. 406 00:19:04,520 --> 00:19:09,340 When I get to a return from sqrt, some value is returned 407 00:19:09,340 --> 00:19:14,760 back to the interpreter, and that table goes away. 408 00:19:14,760 --> 00:19:18,190 But that table does not affect any bindings for other 409 00:19:18,190 --> 00:19:22,620 instances of the variable like x for ANS. 410 00:19:22,620 --> 00:19:24,320 OK. 411 00:19:24,320 --> 00:19:26,320 Let's look at a couple of examples, just to sort of 412 00:19:26,320 --> 00:19:27,090 stress that. 413 00:19:27,090 --> 00:19:33,970 And one of the things I wanted to show is, OK. 414 00:19:33,970 --> 00:19:37,110 Again, I can now use a function just as if it was a 415 00:19:37,110 --> 00:19:39,260 primitive, so this is just an assignment and I going to take 416 00:19:39,260 --> 00:19:42,270 test to be the value of that, of course nothing gets printed 417 00:19:42,270 --> 00:19:43,850 because that was an assignment statement. 418 00:19:43,850 --> 00:19:44,010 All right? 419 00:19:44,010 --> 00:19:47,100 So if I called sqrt alone, that return value is done, but 420 00:19:47,100 --> 00:19:49,190 in this case I bound it to test, so I can go look at 421 00:19:49,190 --> 00:19:51,720 test, and there it is. 422 00:19:51,720 --> 00:19:58,810 What happens if I do that? 423 00:19:58,810 --> 00:19:59,160 OK. 424 00:19:59,160 --> 00:20:00,910 If you look at the code, it printed out, it's not a 425 00:20:00,910 --> 00:20:03,350 perfect square, which is what I wanted, but now, what's the 426 00:20:03,350 --> 00:20:05,720 value of test? 427 00:20:05,720 --> 00:20:09,230 OK, I bound test to something, if I look at it, it doesn't 428 00:20:09,230 --> 00:20:15,550 print anything, but-- if I could type-- 429 00:20:15,550 --> 00:20:20,080 I can ask, is test bound to that special name none? 430 00:20:20,080 --> 00:20:23,130 The answer is yes. 431 00:20:23,130 --> 00:20:24,570 Boy, this seems like a nuance, right? 432 00:20:24,570 --> 00:20:25,760 But it's a valuable thing. 433 00:20:25,760 --> 00:20:30,880 It says, in each case, I return some useful value from 434 00:20:30,880 --> 00:20:31,520 this procedure. 435 00:20:31,520 --> 00:20:33,270 I can check it, so if this was part of some other 436 00:20:33,270 --> 00:20:35,800 computation, I want to know, did it find a 437 00:20:35,800 --> 00:20:36,700 perfect square or not? 438 00:20:36,700 --> 00:20:39,830 I don't have to go read what it printed out in the screen. 439 00:20:39,830 --> 00:20:41,480 This has returned a value that I can use. 440 00:20:41,480 --> 00:20:44,190 Because I could do a test to say, is this a return value? 441 00:20:44,190 --> 00:20:46,730 If it's not, I'll do something else with it. 442 00:20:46,730 --> 00:20:48,280 So the binding is still there, it simply 443 00:20:48,280 --> 00:20:51,030 doesn't print it out. 444 00:20:51,030 --> 00:20:51,400 OK. 445 00:20:51,400 --> 00:20:53,910 What do we have out of this? 446 00:20:53,910 --> 00:20:56,700 Simple, seems like, at least addition. 447 00:20:56,700 --> 00:20:59,960 We've added this notion of a function. 448 00:20:59,960 --> 00:21:02,090 I've highlighted some of the key things we got here, right? 449 00:21:02,090 --> 00:21:04,740 We have that def keyword, we've got a name, we've got a 450 00:21:04,740 --> 00:21:06,440 list-- or I shouldn't say a word list, we have a 451 00:21:06,440 --> 00:21:08,260 collection of formal parameters that we're going to 452 00:21:08,260 --> 00:21:11,500 use-- we have a body, and the body looks just like the 453 00:21:11,500 --> 00:21:13,640 normal instructions we'd use, although by the way, we ought 454 00:21:13,640 --> 00:21:15,830 to be able to use functions inside the body, which we're 455 00:21:15,830 --> 00:21:18,365 going to do in a second, and then we're going to simply 456 00:21:18,365 --> 00:21:20,460 return some values out of this. 457 00:21:20,460 --> 00:21:23,330 Now I started by saying, build these functions. 458 00:21:23,330 --> 00:21:27,840 I'm trying to get both decomposition and abstraction. 459 00:21:27,840 --> 00:21:29,910 Well, you hopefully can see the decomposition, right? 460 00:21:29,910 --> 00:21:30,970 I now have a module. 461 00:21:30,970 --> 00:21:33,020 OK, let me set the stage. 462 00:21:33,020 --> 00:21:35,410 Imagine I wanted to do sqrt, or square root-- no, I'm going 463 00:21:35,410 --> 00:21:37,710 to use sqrt, that's the name I'm using here-- square root a 464 00:21:37,710 --> 00:21:40,550 hundred different places in some piece of code. 465 00:21:40,550 --> 00:21:43,650 Without function, I'd have to copy that piece of code 466 00:21:43,650 --> 00:21:44,660 everywhere. 467 00:21:44,660 --> 00:21:47,730 Now I got one just simple thing, and I simply have 468 00:21:47,730 --> 00:21:51,650 isolated that module inside of that function. 469 00:21:51,650 --> 00:21:53,550 What about abstraction? 470 00:21:53,550 --> 00:21:56,300 Well, I've got part of what I want for abstraction. 471 00:21:56,300 --> 00:21:58,570 Abstraction, again, says I'm going to suppress details. 472 00:21:58,570 --> 00:22:01,430 Now that I've written sqrt, I can just use it anywhere I 473 00:22:01,430 --> 00:22:02,780 want in the code. 474 00:22:02,780 --> 00:22:05,000 You've got to rely on the fact that I wrote it correctly, but 475 00:22:05,000 --> 00:22:08,380 you can basically suppress the details of how it's used. 476 00:22:08,380 --> 00:22:10,640 There's one more piece that we'd like to get out of that, 477 00:22:10,640 --> 00:22:13,180 and that is-- you may have been wondering, what's with 478 00:22:13,180 --> 00:22:17,140 the funky stuttering here of three double-quotes in a row. 479 00:22:17,140 --> 00:22:17,410 All right? 480 00:22:17,410 --> 00:22:20,640 And that is a specification. 481 00:22:20,640 --> 00:22:22,280 Which is a really valuable thing to have. 482 00:22:22,280 --> 00:22:24,250 So what is the specification going to do? 483 00:22:24,250 --> 00:22:28,740 It is my place, as a programmer, to write 484 00:22:28,740 --> 00:22:30,890 information to the user. 485 00:22:30,890 --> 00:22:33,750 This is me writing one hour of that episode of Pirandello and 486 00:22:33,750 --> 00:22:36,560 telling the other authors, here's what I'm assuming as 487 00:22:36,560 --> 00:22:37,910 you use it. 488 00:22:37,910 --> 00:22:39,810 So it's up to me to do it right, but if I do it, I'm 489 00:22:39,810 --> 00:22:42,660 going to specify, what does this function do? 490 00:22:42,660 --> 00:22:45,200 What does it expect as input, and any other information I 491 00:22:45,200 --> 00:22:46,710 want to pass on. 492 00:22:46,710 --> 00:22:49,360 And notice, by the way, if I do that, I'm going to come 493 00:22:49,360 --> 00:22:56,240 down here, and I type sqrt and open the paren, ah-ha! 494 00:22:56,240 --> 00:23:00,090 It shows me what the creator, in this case actually I stole 495 00:23:00,090 --> 00:23:02,740 this from John so what Professor Guttag put up as his 496 00:23:02,740 --> 00:23:06,220 specification for this piece of code. 497 00:23:06,220 --> 00:23:07,630 Now, it's not guaranteed it's right, right? 498 00:23:07,630 --> 00:23:10,110 You're trusting the programmer did it right, but this now 499 00:23:10,110 --> 00:23:10,820 tells you something. 500 00:23:10,820 --> 00:23:11,310 What is this? 501 00:23:11,310 --> 00:23:13,050 This is a wonderful piece of abstraction. 502 00:23:13,050 --> 00:23:16,040 It is saying, you don't need to know squat about what's 503 00:23:16,040 --> 00:23:18,250 inside the body of this function. 504 00:23:18,250 --> 00:23:19,980 You don't have to worry about the parameter names, because 505 00:23:19,980 --> 00:23:21,490 they're going to be preserved, you don't need to worry about 506 00:23:21,490 --> 00:23:24,530 how I'm doing it, this tells you how you can use this, in 507 00:23:24,530 --> 00:23:26,560 order to use it correctly. 508 00:23:26,560 --> 00:23:30,230 Of course, I can then close it off, and off we go. 509 00:23:30,230 --> 00:23:32,360 All right, so that notion of abstraction and I was going to 510 00:23:32,360 --> 00:23:34,700 come back-- we're going to come back to multiple times 511 00:23:34,700 --> 00:23:37,320 during the term-- and it's not just abstraction, it's the 512 00:23:37,320 --> 00:23:39,430 idea of a specification. 513 00:23:39,430 --> 00:23:41,270 And just to look ahead a little bit, you could easily 514 00:23:41,270 --> 00:23:43,630 imagine that I might want to not just put a statement in 515 00:23:43,630 --> 00:23:45,780 there, what the specs are, I might want to put some 516 00:23:45,780 --> 00:23:46,830 constraints. 517 00:23:46,830 --> 00:23:49,450 Some specific things to check for, to make sure that you're 518 00:23:49,450 --> 00:23:50,780 calling the code right. 519 00:23:50,780 --> 00:23:53,710 And it becomes a powerful way of reasoning about the code, a 520 00:23:53,710 --> 00:23:55,940 powerful way of using the code, so those notions of 521 00:23:55,940 --> 00:23:58,960 specs are really important. 522 00:23:58,960 --> 00:24:03,540 Look, part of the reason I'm flaming at you is, something 523 00:24:03,540 --> 00:24:05,830 like square root, it seems dumb to write specs on it. 524 00:24:05,830 --> 00:24:07,570 Everybody knows what this is going to do. 525 00:24:07,570 --> 00:24:10,380 But you want to get into that discipline of good hygiene, 526 00:24:10,380 --> 00:24:10,880 good style. 527 00:24:10,880 --> 00:24:13,970 You want to write the specs so that everybody does in fact 528 00:24:13,970 --> 00:24:15,880 know what this piece of code is doing, and you're writing 529 00:24:15,880 --> 00:24:18,870 it each time around. 530 00:24:18,870 --> 00:24:20,230 OK. 531 00:24:20,230 --> 00:24:25,690 Now that we've got functions, let's see what we can do as a 532 00:24:25,690 --> 00:24:27,720 problem-solving tool using them. 533 00:24:27,720 --> 00:24:29,810 In a particular, I've already said I want to get this notion 534 00:24:29,810 --> 00:24:32,730 of modularity, it's a module I can isolate, and I want to get 535 00:24:32,730 --> 00:24:35,980 the notion of abstracting away the details, let's see how we 536 00:24:35,980 --> 00:24:39,230 can actually use that to actually write some reasonably 537 00:24:39,230 --> 00:24:42,480 interesting pieces of code, but in particular, to see how 538 00:24:42,480 --> 00:24:45,970 we can use it to capture the ideas of decomposition and 539 00:24:45,970 --> 00:24:47,660 abstraction. 540 00:24:47,660 --> 00:24:49,070 So I'm going to shift gears. 541 00:24:49,070 --> 00:24:57,310 Start with a simple problem. 542 00:24:57,310 --> 00:24:59,520 Boy, we're suddenly be transported to Nebraska. 543 00:24:59,520 --> 00:25:01,550 Or where I grew up, Saskatchewan. 544 00:25:01,550 --> 00:25:03,550 All right, we've got a farm air problem. 545 00:25:03,550 --> 00:25:07,300 I got a farmer, walks out into his yard, one morning. 546 00:25:07,300 --> 00:25:10,896 This farmer has a bunch of pigs in a punch-- it's been a 547 00:25:10,896 --> 00:25:14,120 long day-- a bunch of pigs and a bunch of chickens. 548 00:25:14,120 --> 00:25:17,740 And he walks out into the farmyard and he observes 20 549 00:25:17,740 --> 00:25:22,470 heads and 56 legs. 550 00:25:22,470 --> 00:25:26,970 And for sake of argument, there are no amputees among 551 00:25:26,970 --> 00:25:28,980 the chickens and the pigs. 552 00:25:28,980 --> 00:25:31,160 And the question is, so how many pigs does he have, and 553 00:25:31,160 --> 00:25:33,630 how many chickens does he have? 554 00:25:33,630 --> 00:25:34,480 Wow. 555 00:25:34,480 --> 00:25:36,440 What a deep problem, right? 556 00:25:36,440 --> 00:25:37,200 But you're going to see why we're going to 557 00:25:37,200 --> 00:25:37,910 use this in a second. 558 00:25:37,910 --> 00:25:39,280 So you know how to solve this, this is a 559 00:25:39,280 --> 00:25:40,370 fifth-grade problem, right? 560 00:25:40,370 --> 00:25:41,930 And what's the way to solve this? 561 00:25:41,930 --> 00:25:43,790 System of linear equations. 562 00:25:43,790 --> 00:25:44,820 What are the equations here? 563 00:25:44,820 --> 00:25:48,880 Well, I could say, you know, the number of pigs plus the 564 00:25:48,880 --> 00:25:53,570 number of chickens equals 20, right? 565 00:25:53,570 --> 00:25:54,750 Because we've got 20 heads. 566 00:25:54,750 --> 00:25:55,730 And then what else do I have? 567 00:25:55,730 --> 00:26:00,470 Four times the number of pigs plus two times the number of 568 00:26:00,470 --> 00:26:02,590 chickens, assuming they're not next to a 569 00:26:02,590 --> 00:26:07,700 nuclear reactor, is 56. 570 00:26:07,700 --> 00:26:10,270 And then how would you solve this? 571 00:26:10,270 --> 00:26:11,910 Well, it's, you sort of know how you'd do it if this was 572 00:26:11,910 --> 00:26:12,860 grammar school right? 573 00:26:12,860 --> 00:26:14,830 You'd pull out your pencil and paper, you can do it as a 574 00:26:14,830 --> 00:26:16,740 matrix inversion if you know how to do that, or you can 575 00:26:16,740 --> 00:26:19,360 just simply do substitution of one equation into 576 00:26:19,360 --> 00:26:21,270 another to solve it. 577 00:26:21,270 --> 00:26:24,100 That's certainly one way to do it, but for computers that's 578 00:26:24,100 --> 00:26:26,870 not necessarily the easiest way. 579 00:26:26,870 --> 00:26:29,110 So another way of solving it is to do something we already 580 00:26:29,110 --> 00:26:31,910 saw last time, which is basically, why not simply 581 00:26:31,910 --> 00:26:35,240 enumerate all possible examples and check them? 582 00:26:35,240 --> 00:26:39,120 You could say, I could have zero chickens and 20 pigs, 583 00:26:39,120 --> 00:26:40,110 does that work? 584 00:26:40,110 --> 00:26:41,910 I've got one chicken and nineteen pigs, does that work? 585 00:26:41,910 --> 00:26:43,050 I've got two chickens and eighteen 586 00:26:43,050 --> 00:26:44,460 pigs, you get the idea. 587 00:26:44,460 --> 00:26:52,050 So I'm going to solve this by enumerate and check, which is 588 00:26:52,050 --> 00:27:00,840 an example of what's called a brute-force algorithm. 589 00:27:00,840 --> 00:27:02,010 Meaning, I'm just going to write a little 590 00:27:02,010 --> 00:27:03,700 loop that does that. 591 00:27:03,700 --> 00:27:07,440 All right, so let's go back to our code. 592 00:27:07,440 --> 00:27:10,030 That's right, let me pull this over a little bit, 593 00:27:10,030 --> 00:27:14,320 so I can see it. 594 00:27:14,320 --> 00:27:16,110 And what I'd like you to look at, I'm going to highlight it 595 00:27:16,110 --> 00:27:19,800 just for a second here, is those two pieces of code. 596 00:27:19,800 --> 00:27:20,240 OK? 597 00:27:20,240 --> 00:27:24,170 Let's start with solve. 598 00:27:24,170 --> 00:27:24,610 OK. 599 00:27:24,610 --> 00:27:25,580 Here's the idea of solve. 600 00:27:25,580 --> 00:27:28,520 I'm going to have it take in as input how many legs I got, 601 00:27:28,520 --> 00:27:30,640 how many heads do I have, and I just want to 602 00:27:30,640 --> 00:27:32,160 write a little loop. 603 00:27:32,160 --> 00:27:32,320 OK. 604 00:27:32,320 --> 00:27:34,270 I know how to do that, right? 605 00:27:34,270 --> 00:27:36,580 Write a little loop, all I'm going to do, is 606 00:27:36,580 --> 00:27:37,660 run a FOR loop here. 607 00:27:37,660 --> 00:27:40,910 I'm going to let the number of chickens be in this range. 608 00:27:40,910 --> 00:27:43,730 Remember what range does, it gives me a set or a collection 609 00:27:43,730 --> 00:27:48,010 or a tuple of integers from 0 up to 1 - is the last value, 610 00:27:48,010 --> 00:27:49,770 so it's going to give me everything from 0 up to the 611 00:27:49,770 --> 00:27:51,730 total number of heads. 612 00:27:51,730 --> 00:27:53,310 Knowing that, I'm going to say, OK, how many pigs are 613 00:27:53,310 --> 00:27:55,040 there, well that's just how we're, however many I had 614 00:27:55,040 --> 00:27:58,290 total, minus that amount, and then I can see, how many legs 615 00:27:58,290 --> 00:28:01,190 does that give, and then I can check, that the number of legs 616 00:28:01,190 --> 00:28:03,300 that I would get for that solution, is it even equal to 617 00:28:03,300 --> 00:28:06,330 the number of legs I started with, ah! 618 00:28:06,330 --> 00:28:06,910 Interesting. 619 00:28:06,910 --> 00:28:08,640 A return. 620 00:28:08,640 --> 00:28:10,890 In particular, I'm going to return a tuple. 621 00:28:10,890 --> 00:28:14,420 So, a pair or collection of those two values. 622 00:28:14,420 --> 00:28:17,390 If it isn't, then I'm going to go back around the loop, and 623 00:28:17,390 --> 00:28:18,220 notice what happens. 624 00:28:18,220 --> 00:28:22,100 If I get all the way around the loop, that is, all the way 625 00:28:22,100 --> 00:28:24,830 through that FOR loop and I never find a path that takes 626 00:28:24,830 --> 00:28:27,350 me through here, then the last thing I'm going to do is 627 00:28:27,350 --> 00:28:30,520 return a pair or a tuple with a special 628 00:28:30,520 --> 00:28:32,260 simple number none twice. 629 00:28:32,260 --> 00:28:32,630 Yep. 630 00:28:32,630 --> 00:28:35,870 Are you telling me I want parens there and 631 00:28:35,870 --> 00:28:36,910 not, and not braces? 632 00:28:36,910 --> 00:28:37,650 All right. 633 00:28:37,650 --> 00:28:40,380 I hate this language, because I always want to have parens. 634 00:28:40,380 --> 00:28:42,360 Every time you see a square bracket, put a paren in. 635 00:28:42,360 --> 00:28:44,750 All right? 636 00:28:44,750 --> 00:28:45,850 Thank you, Christy. 637 00:28:45,850 --> 00:28:48,250 I'll get it eventually . 638 00:28:48,250 --> 00:28:51,050 Having done that, right, notice what I've got. 639 00:28:51,050 --> 00:28:53,930 First of all, two parameters. 640 00:28:53,930 --> 00:28:54,760 It's OK. 641 00:28:54,760 --> 00:28:56,910 All it says is, when I call this, I need to pass in two 642 00:28:56,910 --> 00:28:58,650 parameters for this to work. 643 00:28:58,650 --> 00:29:00,100 All right? 644 00:29:00,100 --> 00:29:02,370 Now, if I want to use that, I'm going to use a second 645 00:29:02,370 --> 00:29:03,540 piece of code here, called Barnyard. 646 00:29:03,540 --> 00:29:06,310 I'm going to read in a couple of values, convert them into 647 00:29:06,310 --> 00:29:09,735 integers, and then I'm going to use solve to 648 00:29:09,735 --> 00:29:11,630 get a solution out. 649 00:29:11,630 --> 00:29:12,910 And what do I know about solve? 650 00:29:12,910 --> 00:29:16,130 It is going to give me back a tuple a collection of two 651 00:29:16,130 --> 00:29:19,280 things, and so check out the syntax. 652 00:29:19,280 --> 00:29:22,780 I can give two names, which will get bound to the two 653 00:29:22,780 --> 00:29:25,550 parts of that return tuple. 654 00:29:25,550 --> 00:29:27,550 OK, pigs will be the first part, chickens will be the 655 00:29:27,550 --> 00:29:29,010 second part. 656 00:29:29,010 --> 00:29:31,620 OK, and then once I've got that, well, notice: I can then 657 00:29:31,620 --> 00:29:35,450 check to see, did I return that special symbol none? 658 00:29:35,450 --> 00:29:36,190 Is the first part. 659 00:29:36,190 --> 00:29:38,450 That says, I took the branch through here that eventually 660 00:29:38,450 --> 00:29:41,540 got to the end and said, there wasn't a solution, in which 661 00:29:41,540 --> 00:29:41,886 case I'm 662 00:29:41,886 --> 00:29:44,170 going to print out, there ain't no solution, otherwise 663 00:29:44,170 --> 00:29:47,030 I'll print out the pieces. 664 00:29:47,030 --> 00:29:51,130 All right, let's check it out. 665 00:29:51,130 --> 00:29:51,890 Ah, what did I say? 666 00:29:51,890 --> 00:29:54,800 Twenty and 56, Right? 667 00:29:54,800 --> 00:29:57,300 OK, notice the form. 668 00:29:57,300 --> 00:30:02,930 I've got two parameters, they're separated by a comma. 669 00:30:02,930 --> 00:30:05,460 Ah, right. 670 00:30:05,460 --> 00:30:09,160 Sorry? 671 00:30:09,160 --> 00:30:12,350 Yeah, but I see-- it's legs and heads, but it should not 672 00:30:12,350 --> 00:30:16,790 still have-- 673 00:30:16,790 --> 00:30:17,490 Oh, sorry. 674 00:30:17,490 --> 00:30:18,160 Thank you. 675 00:30:18,160 --> 00:30:19,490 I've been doing the wrong thing. 676 00:30:19,490 --> 00:30:24,420 I want Barnyard this way, and if I had looked when I opened 677 00:30:24,420 --> 00:30:26,500 the paren, it would have shown me a closed paren with no 678 00:30:26,500 --> 00:30:27,610 parameters. 679 00:30:27,610 --> 00:30:29,640 Aren't you glad I make mistakes, so you can see how 680 00:30:29,640 --> 00:30:30,740 well I can fix from these? 681 00:30:30,740 --> 00:30:31,020 All right. 682 00:30:31,020 --> 00:30:33,550 Now I call that, and it says, tell me how many heads you 683 00:30:33,550 --> 00:30:37,086 want, give it a 20, and tell it how many legs you want, 684 00:30:37,086 --> 00:30:43,190 give it 56, and it prints out the answers. 685 00:30:43,190 --> 00:30:43,930 I know, whoop-dee-doo. 686 00:30:43,930 --> 00:30:45,570 But notice what's inside if here. 687 00:30:45,570 --> 00:30:47,420 First of all, notice the modularity. 688 00:30:47,420 --> 00:30:48,830 I've used solve. 689 00:30:48,830 --> 00:30:50,820 All right? 690 00:30:50,820 --> 00:30:51,500 Right there. 691 00:30:51,500 --> 00:30:53,790 I've captured it as a computation. 692 00:30:53,790 --> 00:30:57,720 It's buried away, all the details are suppressed. 693 00:30:57,720 --> 00:31:00,150 I can use that to return values, which I can then use 694 00:31:00,150 --> 00:31:02,330 elsewhere, which I did-- and if I just come back and 695 00:31:02,330 --> 00:31:05,480 highlight this-- inside of that computation. 696 00:31:05,480 --> 00:31:08,950 But I don't have to know, inside of Barnyard, what the 697 00:31:08,950 --> 00:31:11,430 values are used inside of solve. 698 00:31:11,430 --> 00:31:13,290 I don't know what the names of the variables are, I don't 699 00:31:13,290 --> 00:31:17,380 care, I can basically suppress away that detail. 700 00:31:17,380 --> 00:31:20,360 Second thing we saw is, that using this as a computation, I 701 00:31:20,360 --> 00:31:22,030 can return multiple values. 702 00:31:22,030 --> 00:31:23,380 Which is actually of real value to me 703 00:31:23,380 --> 00:31:25,810 here as I use that. 704 00:31:25,810 --> 00:31:26,710 OK. 705 00:31:26,710 --> 00:31:27,040 Yeah. 706 00:31:27,040 --> 00:31:27,360 Question. 707 00:31:27,360 --> 00:31:38,480 STUDENT: [INAUDIBLE] 708 00:31:38,480 --> 00:31:39,192 PROFESSOR ERIC GRIMSON: Ah. 709 00:31:39,192 --> 00:31:41,050 The question was, when it returns, how does it 710 00:31:41,050 --> 00:31:42,770 distinguish between local and other things? 711 00:31:42,770 --> 00:31:43,940 So let me try and answer that. 712 00:31:43,940 --> 00:31:47,960 Inside of solve, solve creates an environment where inside of 713 00:31:47,960 --> 00:31:50,600 that, it has bindings for the parameters it's going to use. 714 00:31:50,600 --> 00:31:51,330 All right? 715 00:31:51,330 --> 00:31:54,150 Like, number of-- wait, what did we call a were solve-- 716 00:31:54,150 --> 00:31:56,560 number of legs and number of heads. 717 00:31:56,560 --> 00:31:58,090 OK, those are bound locally. 718 00:31:58,090 --> 00:32:02,110 When solve is done, it wraps up, if you like, a value that 719 00:32:02,110 --> 00:32:03,510 it returns. 720 00:32:03,510 --> 00:32:04,800 Which is that. 721 00:32:04,800 --> 00:32:09,370 That expression, or that value, or that value, 722 00:32:09,370 --> 00:32:12,930 literally gets passed back out of that local environment to 723 00:32:12,930 --> 00:32:14,700 the value that comes back out of it. 724 00:32:14,700 --> 00:32:18,570 So in particular, what's solved returns is a pair. 725 00:32:18,570 --> 00:32:22,210 It could be the pair of none, none, it could be the pair of, 726 00:32:22,210 --> 00:32:24,820 you know, whatever the answer was that we put up there. 727 00:32:24,820 --> 00:32:28,260 That value comes back out and is now available inside the 728 00:32:28,260 --> 00:32:30,730 scope of Barnyard. 729 00:32:30,730 --> 00:32:31,740 OK. 730 00:32:31,740 --> 00:32:33,800 And Barnyard then uses that. 731 00:32:33,800 --> 00:32:34,190 Question? 732 00:32:34,190 --> 00:32:39,990 STUDENT: [INAUDIBLE] 733 00:32:39,990 --> 00:32:40,270 PROFESSOR ERIC GRIMSON: Here? 734 00:32:40,270 --> 00:32:42,300 So the question is, why is this return on the same level 735 00:32:42,300 --> 00:32:43,460 as the FOR? 736 00:32:43,460 --> 00:32:43,990 Why do you think? 737 00:32:43,990 --> 00:32:56,520 STUDENT: [INAUDIBLE] 738 00:32:56,520 --> 00:32:56,894 PROFESSOR ERIC GRIMSON: No. 739 00:32:56,894 --> 00:32:57,110 Good question. 740 00:32:57,110 --> 00:32:57,380 All right? 741 00:32:57,380 --> 00:32:58,990 So what's going to happen here? 742 00:32:58,990 --> 00:33:02,690 If I'm inside this FOR, OK, and I'm running around, if I 743 00:33:02,690 --> 00:33:06,400 ever hit a place where this test is true, I'm going to 744 00:33:06,400 --> 00:33:08,790 execute that return, that return returns 745 00:33:08,790 --> 00:33:11,330 from the entire procedure. 746 00:33:11,330 --> 00:33:11,850 OK? 747 00:33:11,850 --> 00:33:13,860 So the return comes back from the procedure. 748 00:33:13,860 --> 00:33:17,250 So the question was, why is this return down at this 749 00:33:17,250 --> 00:33:20,130 level, it says, well if I ever execute out of this FOR loop, 750 00:33:20,130 --> 00:33:22,020 I get to the end of the FOR loop without hitting that 751 00:33:22,020 --> 00:33:25,480 branch that took me through the return, then and only then 752 00:33:25,480 --> 00:33:28,410 do I want to actually say, gee, I got to this place, 753 00:33:28,410 --> 00:33:30,050 there isn't any value to return, I'm going to return 754 00:33:30,050 --> 00:33:31,780 none and none. 755 00:33:31,780 --> 00:33:33,660 I'm still trying to get rid of this candy, Halloween's 756 00:33:33,660 --> 00:33:34,560 coming, where were we? 757 00:33:34,560 --> 00:33:36,120 There's one, thank you. 758 00:33:36,120 --> 00:33:38,680 I don't think I'm going to make it, I did. 759 00:33:38,680 --> 00:33:41,030 Thank you. 760 00:33:41,030 --> 00:33:48,540 Make sense? 761 00:33:48,540 --> 00:33:51,240 The answer is no, I want parens to create tuple and I 762 00:33:51,240 --> 00:33:52,630 get really confused about the difference 763 00:33:52,630 --> 00:33:53,700 between lists and tuples. 764 00:33:53,700 --> 00:34:00,550 For now, the code is working. 765 00:34:00,550 --> 00:34:02,560 Yes is the answer, all right? 766 00:34:02,560 --> 00:34:04,450 And we're having a difference of opinion as to whether we 767 00:34:04,450 --> 00:34:06,610 should use a tuple or a list here, right? 768 00:34:06,610 --> 00:34:08,300 But the answer is yes, you can. 769 00:34:08,300 --> 00:34:10,630 And my real answer is, go try it out, because obviously you 770 00:34:10,630 --> 00:34:12,960 can tell I frequently do this the wrong way and the TAs give 771 00:34:12,960 --> 00:34:13,970 me a hard time every time. 772 00:34:13,970 --> 00:34:14,380 John. 773 00:34:14,380 --> 00:34:17,810 PROFESSOR JOHN GUTTAG: Is the microphone on? 774 00:34:17,810 --> 00:34:18,730 PROFESSOR ERIC GRIMSON: Yes. 775 00:34:18,730 --> 00:34:21,020 PROFESSOR JOHN GUTTAG: As you'll see next week, tuples 776 00:34:21,020 --> 00:34:23,620 and lists are very close to the same thing. 777 00:34:23,620 --> 00:34:27,740 In almost any place where you can get away with using tuples 778 00:34:27,740 --> 00:34:29,460 you can use lists. 779 00:34:29,460 --> 00:34:29,680 PROFESSOR ERIC GRIMSON: Yes. 780 00:34:29,680 --> 00:34:31,350 PROFESSOR JOHN GUTTAG: But want to emphasize word is 781 00:34:31,350 --> 00:34:34,970 almost, because we'll see a couple of places where if it 782 00:34:34,970 --> 00:34:37,290 expects a tuple and you use a list you'll 783 00:34:37,290 --> 00:34:38,980 get an error message. 784 00:34:38,980 --> 00:34:40,950 But we'll see all that next week. 785 00:34:40,950 --> 00:34:43,030 PROFESSOR ERIC GRIMSON: Right, when the real pro comes in to 786 00:34:43,030 --> 00:34:46,500 pick up the pieces I'm leaving behind for him. 787 00:34:46,500 --> 00:34:47,970 OK. 788 00:34:47,970 --> 00:34:48,950 Let me pull this back up. 789 00:34:48,950 --> 00:34:51,260 What we're doing now is we're building this encapsulation. 790 00:34:51,260 --> 00:34:53,610 Now one of the things you notice here by the way is, you 791 00:34:53,610 --> 00:34:57,420 know, this in essence just solves the simple problems. 792 00:34:57,420 --> 00:35:01,190 Suppose I now add one other piece to this. 793 00:35:01,190 --> 00:35:04,090 The farmer is not keeping a great set of things so in 794 00:35:04,090 --> 00:35:11,390 addition to pigs, and chickens he raises spiders. 795 00:35:11,390 --> 00:35:14,110 I have no idea why. 796 00:35:14,110 --> 00:35:16,970 He's making silk I guess. 797 00:35:16,970 --> 00:35:17,830 Right? 798 00:35:17,830 --> 00:35:18,860 Why am I giving you this example? 799 00:35:18,860 --> 00:35:20,630 I want to show you how easy it is to change the code. 800 00:35:20,630 --> 00:35:22,130 But, notice, once I've added this I 801 00:35:22,130 --> 00:35:22,820 actually have a problem. 802 00:35:22,820 --> 00:35:24,560 This is now an under-constrained problem. 803 00:35:24,560 --> 00:35:28,530 I have more unknowns than I have equations. 804 00:35:28,530 --> 00:35:30,700 So you know from algebra I can't actually solve this. 805 00:35:30,700 --> 00:35:33,190 There may be multiple solutions to this. 806 00:35:33,190 --> 00:35:35,840 What would I have to do to change my code? 807 00:35:35,840 --> 00:35:38,610 And the answer is fortunately not a lot. 808 00:35:38,610 --> 00:35:41,010 So I'm going to ask you to look now at this set of 809 00:35:41,010 --> 00:35:45,590 things, which is solve 1 and Barnyard 1. 810 00:35:45,590 --> 00:35:47,040 OK. 811 00:35:47,040 --> 00:35:49,110 The change is, well, on Barnyard 1 it looks much the 812 00:35:49,110 --> 00:35:50,630 same as it did for Barnyard. 813 00:35:50,630 --> 00:35:52,480 Right, I'm going to read in the values of the number of 814 00:35:52,480 --> 00:35:53,760 heads and the number of legs. 815 00:35:53,760 --> 00:35:56,280 I'm going to use solve 1 as before, but now I'm going to 816 00:35:56,280 --> 00:35:58,170 bind out three variables. 817 00:35:58,170 --> 00:35:59,540 And then I'm going to do a similar thing to 818 00:35:59,540 --> 00:36:01,020 print things out. 819 00:36:01,020 --> 00:36:02,030 But would the solver do? 820 00:36:02,030 --> 00:36:03,690 Well here what I'd like to do is to run 821 00:36:03,690 --> 00:36:06,240 through a couple of loops. 822 00:36:06,240 --> 00:36:07,820 Right, how would I solve this problem? 823 00:36:07,820 --> 00:36:10,970 You can use the same enumerate and check idea, but now say 824 00:36:10,970 --> 00:36:13,730 gee let me pick how many pigs there are. 825 00:36:13,730 --> 00:36:14,970 Is that the one I used first? 826 00:36:14,970 --> 00:36:18,370 Sorry, let me pick the number of spiders there are. 827 00:36:18,370 --> 00:36:21,980 Having chosen the number of spiders, let me pick how many 828 00:36:21,980 --> 00:36:25,880 chickens I have. With those two in place, I now know how 829 00:36:25,880 --> 00:36:27,470 many pigs I must have and I can run 830 00:36:27,470 --> 00:36:28,490 through the same solution. 831 00:36:28,490 --> 00:36:31,800 The reason I'm showing you this is this is another very 832 00:36:31,800 --> 00:36:32,550 standard structure. 833 00:36:32,550 --> 00:36:35,480 I now have two nested loops. 834 00:36:35,480 --> 00:36:38,590 One running through a choice for one parameter, another one 835 00:36:38,590 --> 00:36:40,630 running through a choice for a second parameter. 836 00:36:40,630 --> 00:36:41,800 And then the rest of the solution 837 00:36:41,800 --> 00:36:42,690 looks much like before. 838 00:36:42,690 --> 00:36:44,140 I'm going to get the total number of legs out. 839 00:36:44,140 --> 00:36:45,930 I'm going to check to see if it's right or not. 840 00:36:45,930 --> 00:36:48,945 And again I'm going to return either a three tuple there or 841 00:36:48,945 --> 00:36:50,420 a three tuple there. 842 00:36:50,420 --> 00:36:52,040 It's part of what I want, because I'm going to bind 843 00:36:52,040 --> 00:36:53,950 those values out. 844 00:36:53,950 --> 00:37:03,120 And if I run that example, Barnyard 1, I don't know we'll 845 00:37:03,120 --> 00:37:09,010 give it 20 heads, 56 legs; and it find a solution. 846 00:37:09,010 --> 00:37:14,520 I ought to be able to run something else. 847 00:37:14,520 --> 00:37:15,470 I don't know, give me some numbers. 848 00:37:15,470 --> 00:37:15,990 How many heads? 849 00:37:15,990 --> 00:37:17,240 Pick an integer, somebody. 850 00:37:17,240 --> 00:37:18,700 STUDENT: 5. 851 00:37:18,700 --> 00:37:19,400 PROFESSOR ERIC GRIMSON: 5. 852 00:37:19,400 --> 00:37:19,830 All right. 853 00:37:19,830 --> 00:37:22,240 How many legs? 854 00:37:22,240 --> 00:37:24,550 10? 855 00:37:24,550 --> 00:37:24,880 All right. 856 00:37:24,880 --> 00:37:26,670 We got an easy one. 857 00:37:26,670 --> 00:37:27,990 Let's just for the heck of it -- 858 00:37:27,990 --> 00:37:29,520 I should have found some better examples 859 00:37:29,520 --> 00:37:37,720 before I tried this. 860 00:37:37,720 --> 00:37:40,230 No mutant spiders here. 861 00:37:40,230 --> 00:37:41,060 OK, so what have I done? 862 00:37:41,060 --> 00:37:42,220 I just added a little bit more now. 863 00:37:42,220 --> 00:37:43,620 I'm now running through a pair of loops. 864 00:37:43,620 --> 00:37:45,480 Again notice the encapsulation, that nice 865 00:37:45,480 --> 00:37:48,450 abstraction going on, which is what I want. 866 00:37:48,450 --> 00:37:50,340 Once I get to this stage though by the way, there might 867 00:37:50,340 --> 00:37:51,740 be more than one solution. 868 00:37:51,740 --> 00:37:53,920 Because in an under-constrained problem 869 00:37:53,920 --> 00:37:55,610 there could be multiple solutions. 870 00:37:55,610 --> 00:37:57,620 So suppose I want to capture all of them or 871 00:37:57,620 --> 00:37:59,060 print all of them out. 872 00:37:59,060 --> 00:38:00,920 Well I ought to be able to do that by simply 873 00:38:00,920 --> 00:38:02,710 generalizing the loop. 874 00:38:02,710 --> 00:38:07,320 And that's what the next piece of code on your a 875 00:38:07,320 --> 00:38:08,550 hand out shows you. 876 00:38:08,550 --> 00:38:09,810 I'm just going to let you look at this. 877 00:38:09,810 --> 00:38:13,360 If you look at solve 2, it's going to run through the same 878 00:38:13,360 --> 00:38:16,050 kind of loop, printing out all of the answers. 879 00:38:16,050 --> 00:38:17,260 But it's going to keep going. 880 00:38:17,260 --> 00:38:19,670 In other words it doesn't just return when it finds one, it's 881 00:38:19,670 --> 00:38:22,410 going to run through all of them. 882 00:38:22,410 --> 00:38:23,270 All right? 883 00:38:23,270 --> 00:38:24,330 Sounds like a reasonable thing to do. 884 00:38:24,330 --> 00:38:26,000 Notice one last piece. 885 00:38:26,000 --> 00:38:30,020 If I'm going to do that, run through all possible answers, 886 00:38:30,020 --> 00:38:31,480 I still want to know, gee, what if 887 00:38:31,480 --> 00:38:32,430 there aren't any answers? 888 00:38:32,430 --> 00:38:35,130 How do I return that case? 889 00:38:35,130 --> 00:38:37,230 And that shows you one other nice little thing we want to 890 00:38:37,230 --> 00:38:40,510 do, which is if I look in this code notice I set up a 891 00:38:40,510 --> 00:38:42,890 variable up here called Solution Found, initially 892 00:38:42,890 --> 00:38:44,760 bound to false. 893 00:38:44,760 --> 00:38:47,110 The rest of that code's a pair of loops. 894 00:38:47,110 --> 00:38:48,110 Pick the number of spiders. 895 00:38:48,110 --> 00:38:49,000 Pick the number of chickens. 896 00:38:49,000 --> 00:38:50,250 That sets up the number of pigs. 897 00:38:50,250 --> 00:38:51,020 Figure out the legs. 898 00:38:51,020 --> 00:38:52,200 See if it's right. 899 00:38:52,200 --> 00:38:55,200 If it is right, I'm going to print out the information but 900 00:38:55,200 --> 00:38:58,720 I'm also going to change that variable to true. 901 00:38:58,720 --> 00:39:01,620 And that allows me then, at the end of that pair of loops 902 00:39:01,620 --> 00:39:05,440 when I get down to this point right here, I can check to see 903 00:39:05,440 --> 00:39:08,980 did I find any solution and if not in that case print out 904 00:39:08,980 --> 00:39:11,040 there is no solution. 905 00:39:11,040 --> 00:39:14,320 So this gives you another nice piece which is I can now look 906 00:39:14,320 --> 00:39:17,140 for first solution, I can look for all solutions, and I can 907 00:39:17,140 --> 00:39:20,010 maintain some internal variables that let me know 908 00:39:20,010 --> 00:39:20,670 what I found. 909 00:39:20,670 --> 00:39:22,770 A trick that you're going to use a lot as you write your 910 00:39:22,770 --> 00:39:24,880 own functions. 911 00:39:24,880 --> 00:39:27,140 All right, I want to end up with the last 10 minutes with 912 00:39:27,140 --> 00:39:30,210 a different variation on how to use functions to think 913 00:39:30,210 --> 00:39:32,510 about problems. And that is to 914 00:39:32,510 --> 00:39:35,890 introduce the idea of recursion. 915 00:39:35,890 --> 00:39:44,240 How many of you have heard the term used before? 916 00:39:44,240 --> 00:39:48,020 How may have you heard the term used before in terms of 917 00:39:48,020 --> 00:39:50,180 programming languages? 918 00:39:50,180 --> 00:39:51,040 Great. 919 00:39:51,040 --> 00:39:52,380 For the rest you, don't sweat it. 920 00:39:52,380 --> 00:39:55,170 This is a highfalutin term that computer scientists use 921 00:39:55,170 --> 00:39:57,010 to try and make them look like they're smarter than they 922 00:39:57,010 --> 00:39:58,810 really are. 923 00:39:58,810 --> 00:40:01,910 But it is a very handy way of thinking about, not just how 924 00:40:01,910 --> 00:40:04,710 to program, but how to break problems down 925 00:40:04,710 --> 00:40:06,880 into nice sized chunks. 926 00:40:06,880 --> 00:40:09,640 And the idea behind recursion I'm going to describe with a 927 00:40:09,640 --> 00:40:11,310 simple example. 928 00:40:11,310 --> 00:40:16,720 And then I'm going to show you how we can actually use it. 929 00:40:16,720 --> 00:40:20,310 The idea of recursion is that I'm going to take a problem 930 00:40:20,310 --> 00:40:23,000 and break it down into a simpler version of the same 931 00:40:23,000 --> 00:40:26,930 problem plus some steps that I can execute. 932 00:40:26,930 --> 00:40:28,590 I'm go to show you an example of a procedure, sorry a 933 00:40:28,590 --> 00:40:29,450 function, in a second. 934 00:40:29,450 --> 00:40:32,830 But let me give you actually an analogy. 935 00:40:32,830 --> 00:40:37,080 If you look at US law, and you look at the definition of the 936 00:40:37,080 --> 00:40:39,040 US legal code that defines the notion of a 937 00:40:39,040 --> 00:40:41,130 natural born US citizen. 938 00:40:41,130 --> 00:40:43,850 It's actually a wonderful recursive definition. 939 00:40:43,850 --> 00:40:45,240 So what's the definition? 940 00:40:45,240 --> 00:40:49,950 If you're born in the United States you are by definition a 941 00:40:49,950 --> 00:40:51,680 natural born US citizen. 942 00:40:51,680 --> 00:40:58,140 We call that a base case. 943 00:40:58,140 --> 00:41:05,030 It's basically the simplest possible 944 00:41:05,030 --> 00:41:07,180 solution to the problem. 945 00:41:07,180 --> 00:41:09,660 Now if you were not born in the United States, you may 946 00:41:09,660 --> 00:41:14,150 still be, under definition, a natural born US citizen if 947 00:41:14,150 --> 00:41:16,900 you're born outside this United States, both of your 948 00:41:16,900 --> 00:41:19,780 parents are citizens of the United States and at least one 949 00:41:19,780 --> 00:41:21,880 parent has lived in the United States. 950 00:41:21,880 --> 00:41:24,450 There's a wonderful legal expression. 951 00:41:24,450 --> 00:41:25,570 But notice what that is. 952 00:41:25,570 --> 00:41:26,830 It's a recursive definition. 953 00:41:26,830 --> 00:41:30,580 How do you know that your parents, at least one of your 954 00:41:30,580 --> 00:41:32,840 parents satisfies the definition? 955 00:41:32,840 --> 00:41:36,970 Well I've reduced the problem from am I a natural born US 956 00:41:36,970 --> 00:41:39,780 citizen to is one of my parents a 957 00:41:39,780 --> 00:41:41,280 natural born US citizen? 958 00:41:41,280 --> 00:41:44,070 And that may generalize again and it keeps going until you 959 00:41:44,070 --> 00:41:46,830 either get back to Adam and Eve, I guess. 960 00:41:46,830 --> 00:41:49,740 I don't think they were born in the US as far as I know, or 961 00:41:49,740 --> 00:41:52,320 you find somebody who satisfies that definition or 962 00:41:52,320 --> 00:41:54,490 you find that none of your parents 963 00:41:54,490 --> 00:41:55,920 actually are in that category. 964 00:41:55,920 --> 00:42:00,540 But that second one is called the inductive step, or the 965 00:42:00,540 --> 00:42:01,630 recursive step. 966 00:42:01,630 --> 00:42:10,340 And in my words it says break the problem into a simpler 967 00:42:10,340 --> 00:42:28,550 version of the same problem and some other steps. 968 00:42:28,550 --> 00:42:31,090 And I think this is best illustrated by giving you a 969 00:42:31,090 --> 00:42:33,350 simple little piece of code. 970 00:42:33,350 --> 00:42:35,450 I use simple advisedly here. 971 00:42:35,450 --> 00:42:38,150 This is actually a piece of code that is really easy to 972 00:42:38,150 --> 00:42:41,010 think about recursively and is much more difficult to think 973 00:42:41,010 --> 00:42:42,320 about in other ways. 974 00:42:42,320 --> 00:42:44,390 And the piece of code is suppose I have a spring and I 975 00:42:44,390 --> 00:42:46,590 want to know if it's a palindrome. 976 00:42:46,590 --> 00:42:48,170 Does it read the same thing left to 977 00:42:48,170 --> 00:42:50,580 right as right to left. 978 00:42:50,580 --> 00:42:51,890 OK? 979 00:42:51,890 --> 00:42:53,960 How would I solve that? 980 00:42:53,960 --> 00:42:58,150 If the string has no elements in it it is obviously a 981 00:42:58,150 --> 00:42:59,160 palindrome. 982 00:42:59,160 --> 00:43:02,990 If the string has one element in it, it's a palindrome. 983 00:43:02,990 --> 00:43:04,650 There's the base case. 984 00:43:04,650 --> 00:43:07,630 If it's longer than one, what do I want to do? 985 00:43:07,630 --> 00:43:10,880 Well I'd like to check the two end points to see are they the 986 00:43:10,880 --> 00:43:12,210 same character? 987 00:43:12,210 --> 00:43:14,800 And if they are, then oh, I just need to know is 988 00:43:14,800 --> 00:43:19,030 everything else in the middle a palindrome? 989 00:43:19,030 --> 00:43:21,020 I know it sounds simple, but notice what I just did. 990 00:43:21,020 --> 00:43:23,320 I just used a recursive definition. 991 00:43:23,320 --> 00:43:27,080 I just reduced it to a smaller version of the same problem. 992 00:43:27,080 --> 00:43:30,970 That is if I can write code that would solve all instances 993 00:43:30,970 --> 00:43:34,560 of smaller size strings, then what I just described will 994 00:43:34,560 --> 00:43:36,940 solve the larger size one. 995 00:43:36,940 --> 00:43:39,300 And in fact that's exactly what I have. I would like you 996 00:43:39,300 --> 00:43:42,020 to look at this piece of code right here called 997 00:43:42,020 --> 00:43:44,510 isPalindrome. 998 00:43:44,510 --> 00:43:46,500 Notice what it says. 999 00:43:46,500 --> 00:43:51,360 I'm going to pass in a string, call it s, binds it locally, 1000 00:43:51,360 --> 00:43:52,360 and it says the following. 1001 00:43:52,360 --> 00:43:57,690 It says if this is a string of length 0 or 1, I'm done. 1002 00:43:57,690 --> 00:44:00,240 I'm going to return the answer true. 1003 00:44:00,240 --> 00:44:04,880 Otherwise I'm going to check to see is the first and last, 1004 00:44:04,880 --> 00:44:07,560 there's that - 1 indexing, is the first and last element of 1005 00:44:07,560 --> 00:44:10,480 the string the same? 1006 00:44:10,480 --> 00:44:14,890 And if that's true is everything in the string, 1007 00:44:14,890 --> 00:44:17,480 starting at the first element and removing the last element, 1008 00:44:17,480 --> 00:44:19,180 a palindrome? 1009 00:44:19,180 --> 00:44:19,630 Let me remind you. 1010 00:44:19,630 --> 00:44:21,780 By saying first element remember we start at 0 as the 1011 00:44:21,780 --> 00:44:24,890 initial indexing point. 1012 00:44:24,890 --> 00:44:27,880 Wonderful recursive definition. 1013 00:44:27,880 --> 00:44:31,110 OK, let's try it out. 1014 00:44:31,110 --> 00:44:35,890 Go back over here and we're going to say isPalindrome. 1015 00:44:35,890 --> 00:44:37,580 How did I actually spell this? 1016 00:44:37,580 --> 00:44:44,470 Palindrome with a capital P. Only in New York, in Canada we 1017 00:44:44,470 --> 00:44:46,260 pronounce it Palindrome. 1018 00:44:46,260 --> 00:44:48,340 When you're teaching it you get to call it your way, I'm 1019 00:44:48,340 --> 00:44:49,610 going to call it my way. 1020 00:44:49,610 --> 00:44:52,600 Sorry John, you're absolutely right. 1021 00:44:52,600 --> 00:44:53,890 OK. 1022 00:44:53,890 --> 00:44:55,740 Notice by the way, there's that nice speck going on 1023 00:44:55,740 --> 00:44:57,080 saying put a string here. 1024 00:44:57,080 --> 00:44:59,230 It's going to return true if it's a PAIL-indrome and false 1025 00:44:59,230 --> 00:45:03,260 if it's a PAL-indrome. 1026 00:45:03,260 --> 00:45:05,530 And it says true. 1027 00:45:05,530 --> 00:45:07,170 Now maybe you're bugged by this. 1028 00:45:07,170 --> 00:45:09,050 I know you're bugged by my bad humor, but too bad. 1029 00:45:09,050 --> 00:45:11,310 Maybe you're bugged by this, saying wait a minute, how does 1030 00:45:11,310 --> 00:45:13,280 this thing stop? 1031 00:45:13,280 --> 00:45:16,520 This is the kind of definition that your high school geometry 1032 00:45:16,520 --> 00:45:17,990 teacher would have rapped your knuckles over. 1033 00:45:17,990 --> 00:45:20,710 You can't define things in terms of themselves. 1034 00:45:20,710 --> 00:45:22,280 This is an inductive definition. 1035 00:45:22,280 --> 00:45:24,140 Actually we could prove inductively that it holds, but 1036 00:45:24,140 --> 00:45:25,790 how do we know it stops? 1037 00:45:25,790 --> 00:45:28,000 Well notice what the computation is doing. it's 1038 00:45:28,000 --> 00:45:31,690 looking first to see am I in the base case, which I'm done. 1039 00:45:31,690 --> 00:45:34,680 If I'm not I'm just going to reduce this to a smaller 1040 00:45:34,680 --> 00:45:35,960 computation. 1041 00:45:35,960 --> 00:45:38,520 And as long as that smaller computation reduces to another 1042 00:45:38,520 --> 00:45:41,220 smaller computation, eventually I ought to get to 1043 00:45:41,220 --> 00:45:43,760 the place where I'm down in that base case. 1044 00:45:43,760 --> 00:45:46,190 And to see that I've written another version of this, which 1045 00:45:46,190 --> 00:45:49,840 I'm going to use here, where I'm going to give it a little 1046 00:45:49,840 --> 00:45:56,110 indentation. 1047 00:45:56,110 --> 00:45:58,080 I'm going to call this palindrome 1. 1048 00:45:58,080 --> 00:45:59,040 Sorry about that. 1049 00:45:59,040 --> 00:45:59,870 Palindrome 1. 1050 00:45:59,870 --> 00:46:03,600 I'm going to give it a little indentation so 1051 00:46:03,600 --> 00:46:07,360 that we can see this. 1052 00:46:07,360 --> 00:46:07,850 OK. 1053 00:46:07,850 --> 00:46:10,130 Code is right here. 1054 00:46:10,130 --> 00:46:13,230 And all it's doing is when I'm getting into the different 1055 00:46:13,230 --> 00:46:15,890 places I'm simply printing out information about where I am. 1056 00:46:15,890 --> 00:46:18,840 What I want you to see is notice what happened here. 1057 00:46:18,840 --> 00:46:19,980 OK. 1058 00:46:19,980 --> 00:46:22,550 I'm calling palindrome with that. 1059 00:46:22,550 --> 00:46:25,080 It first calls it on that problem. 1060 00:46:25,080 --> 00:46:28,280 And the code over here says, OK gee, if I'm in the base 1061 00:46:28,280 --> 00:46:29,060 case do something. 1062 00:46:29,060 --> 00:46:32,400 I'm not, so come down here check that the two end points 1063 00:46:32,400 --> 00:46:38,370 a and a are the same and call this again also. 1064 00:46:38,370 --> 00:46:39,330 Notice what happens. 1065 00:46:39,330 --> 00:46:42,610 There's this nice unwrapping of the problem. 1066 00:46:42,610 --> 00:46:45,480 I just doubled the indentation each time so you can see it. 1067 00:46:45,480 --> 00:46:49,310 So each successive call, notice what's happening. 1068 00:46:49,310 --> 00:46:52,960 The argument is getting reduced. 1069 00:46:52,960 --> 00:46:54,190 And we're going another level in. 1070 00:46:54,190 --> 00:46:56,780 When we get down to this point, we're calling it with 1071 00:46:56,780 --> 00:46:58,510 just a string of length one. 1072 00:46:58,510 --> 00:47:01,720 At that point we're in the base case and we can unwrap 1073 00:47:01,720 --> 00:47:03,000 this computation. 1074 00:47:03,000 --> 00:47:04,570 We say, ah, that's now true. 1075 00:47:04,570 --> 00:47:06,340 So I can return true here. 1076 00:47:06,340 --> 00:47:08,370 Given that that's true and I already checked the two end 1077 00:47:08,370 --> 00:47:10,610 points, that's true, that's true. 1078 00:47:10,610 --> 00:47:14,780 And I unwrap the computation to get back. 1079 00:47:14,780 --> 00:47:16,610 You are going to have to go play with this. 1080 00:47:16,610 --> 00:47:18,590 Rock it if you like to try and see where it goes. 1081 00:47:18,590 --> 00:47:21,800 But I want to stress again, as long as I do the base case 1082 00:47:21,800 --> 00:47:25,070 right and my inductive or recursive step reduces it to a 1083 00:47:25,070 --> 00:47:28,280 smaller version of the same problem, the code will in fact 1084 00:47:28,280 --> 00:47:31,930 converge and give me out an answer. 1085 00:47:31,930 --> 00:47:35,700 All right, I want to show you one last example of using 1086 00:47:35,700 --> 00:47:37,970 recursion because we're going to come back to this. 1087 00:47:37,970 --> 00:47:40,450 This is a classic example of using recursion. 1088 00:47:40,450 --> 00:47:44,255 And that is dating from the 1200s and 1089 00:47:44,255 --> 00:47:46,880 it is due to Fibonacci. 1090 00:47:46,880 --> 00:47:49,090 Does anyone know the history of what Fibonacci 1091 00:47:49,090 --> 00:47:51,270 was trying to do? 1092 00:47:51,270 --> 00:47:52,260 Sorry, let me re-ask that. 1093 00:47:52,260 --> 00:47:56,270 Fibonacci. 1094 00:47:56,270 --> 00:47:58,270 Which actually is son of Bonacci which is the name of 1095 00:47:58,270 --> 00:48:00,970 his father who was apparently a very friendly guy. 1096 00:48:00,970 --> 00:48:05,250 First of all, does anyone know what a Fibonacci number is? 1097 00:48:05,250 --> 00:48:06,290 Wow. 1098 00:48:06,290 --> 00:48:10,690 STUDENT: [INAUDIBLE] 1099 00:48:10,690 --> 00:48:11,275 PROFESSOR ERIC GRIMSON: Right, we're going to do that in a 1100 00:48:11,275 --> 00:48:13,910 second, but the answer is Fibonacci numbers, we define 1101 00:48:13,910 --> 00:48:14,680 the first two. 1102 00:48:14,680 --> 00:48:16,295 Which are both defined to be, or I can define them in 1103 00:48:16,295 --> 00:48:17,660 multiple ways, 0 and 1. 1104 00:48:17,660 --> 00:48:19,660 And then the next Fibonacci number is the sum of the 1105 00:48:19,660 --> 00:48:20,170 previous two. 1106 00:48:20,170 --> 00:48:22,230 And the next number is the sum of the previous two. 1107 00:48:22,230 --> 00:48:23,940 Do you know the history of this? 1108 00:48:23,940 --> 00:48:30,840 STUDENT: [INAUDIBLE]. 1109 00:48:30,840 --> 00:48:32,100 PROFESSOR ERIC GRIMSON: Exactly. 1110 00:48:32,100 --> 00:48:33,060 Thank you. 1111 00:48:33,060 --> 00:48:35,140 Bad throw, I'm playing for the Yankees. 1112 00:48:35,140 --> 00:48:36,290 Sorry John. 1113 00:48:36,290 --> 00:48:38,450 The answer is Fibonacci actually was actually trying 1114 00:48:38,450 --> 00:48:40,570 to count rabbits back in the 1200s. 1115 00:48:40,570 --> 00:48:43,400 The idea was that rabbits could mate after a month, at 1116 00:48:43,400 --> 00:48:44,580 age one month. 1117 00:48:44,580 --> 00:48:47,380 And so he said, if you start off with a male and a female, 1118 00:48:47,380 --> 00:48:49,700 at the end of one month they have an offspring. 1119 00:48:49,700 --> 00:48:52,040 Let's assume they have two offspring. 1120 00:48:52,040 --> 00:48:54,130 At the end of the next month let's assume those offspring 1121 00:48:54,130 --> 00:48:54,680 have offspring. 1122 00:48:54,680 --> 00:48:55,620 Again a male and female. 1123 00:48:55,620 --> 00:48:57,550 The question was how many rabbits do you have at 1124 00:48:57,550 --> 00:48:58,160 the end of a year? 1125 00:48:58,160 --> 00:48:58,860 At the end of two years? 1126 00:48:58,860 --> 00:49:01,470 At the end of more than that number of years, and so. 1127 00:49:01,470 --> 00:49:05,950 We can do this with the following level definition. 1128 00:49:05,950 --> 00:49:08,320 We're going to let pairs of 0, the number of pairs at month 1129 00:49:08,320 --> 00:49:10,200 0, actually it would not be 0 it would be 1. 1130 00:49:10,200 --> 00:49:17,650 We let the number of pairs at month 1 be 1. 1131 00:49:17,650 --> 00:49:21,920 And then the number of pairs at month n is the number of 1132 00:49:21,920 --> 00:49:25,880 pairs at month n - 1 plus the number of pairs 1133 00:49:25,880 --> 00:49:27,670 at month n - 2. 1134 00:49:27,670 --> 00:49:30,910 The sum of the previous two. 1135 00:49:30,910 --> 00:49:35,350 If I write Fibonacci, you see it right there. 1136 00:49:35,350 --> 00:49:37,390 And the reason I want to show you this is to notice that the 1137 00:49:37,390 --> 00:49:39,490 recursion can be doubled. 1138 00:49:39,490 --> 00:49:43,570 So this says, given a value x, if it's either 0 or 1, either 1139 00:49:43,570 --> 00:49:45,830 of those two cases, just return 1. 1140 00:49:45,830 --> 00:49:49,260 Otherwise break this down into two versions 1141 00:49:49,260 --> 00:49:50,860 of a simpler problem. 1142 00:49:50,860 --> 00:49:54,870 Fib of x - 1 and fib of x - 2, and then take the sum of those 1143 00:49:54,870 --> 00:49:57,470 and return that as the value. 1144 00:49:57,470 --> 00:50:01,120 Notice if I'm going to have two different sub problems I 1145 00:50:01,120 --> 00:50:04,690 need to have two base cases here to catch this. 1146 00:50:04,690 --> 00:50:06,200 And if I only had one it would error out. 1147 00:50:06,200 --> 00:50:11,730 And as a consequence, I can go off and ask about rabbits. 1148 00:50:11,730 --> 00:50:13,760 Let's see. 1149 00:50:13,760 --> 00:50:18,350 At the end of 12 months, not so bad. 1150 00:50:18,350 --> 00:50:24,990 At the end of two years, we're not looking so good. 1151 00:50:24,990 --> 00:50:30,790 At the end of three years, we are now in Australia. 1152 00:50:30,790 --> 00:50:31,860 Overrun with rabbits. 1153 00:50:31,860 --> 00:50:34,460 In fact I don't think the thing ever comes back, so I'm 1154 00:50:34,460 --> 00:50:37,580 going to stop it because it really gets hung up here. 1155 00:50:37,580 --> 00:50:40,490 And I'm going to restart it. 1156 00:50:40,490 --> 00:50:42,260 What's the point of this? 1157 00:50:42,260 --> 00:50:44,600 Again, now that I can think about things recursively, I 1158 00:50:44,600 --> 00:50:47,410 can similarly break things down into simpler versions of 1159 00:50:47,410 --> 00:50:48,660 the same problem. 1160 00:50:48,660 --> 00:50:49,770 It could be one version. 1161 00:50:49,770 --> 00:50:51,090 It could be multiple versions. 1162 00:50:51,090 --> 00:50:53,810 And we're going to come back throughout the term to think 1163 00:50:53,810 --> 00:50:56,910 about how to code programs that reflect this. 1164 00:50:56,910 --> 00:50:59,090 The last point I want to make to you is, you've started 1165 00:50:59,090 --> 00:51:01,140 writing programs that you would think of as being 1166 00:51:01,140 --> 00:51:02,010 inherently iterative. 1167 00:51:02,010 --> 00:51:04,180 They're running through a loop. 1168 00:51:04,180 --> 00:51:07,290 It's a common way of thinking about problems. Some problems 1169 00:51:07,290 --> 00:51:09,410 are naturally tackled that way. 1170 00:51:09,410 --> 00:51:11,710 There are other problems that are much more naturally 1171 00:51:11,710 --> 00:51:13,900 thought of in a recursive fashion. 1172 00:51:13,900 --> 00:51:16,390 And I would suggest palindrome as a great example of that. 1173 00:51:16,390 --> 00:51:18,440 That's easy to think about recursively. 1174 00:51:18,440 --> 00:51:20,620 It's much harder to think about iteratively. 1175 00:51:20,620 --> 00:51:22,940 And you want to get into the habit of deciding which is the 1176 00:51:22,940 --> 00:51:24,890 right one for you to use. 1177 00:51:24,890 --> 00:51:27,070 And with that, we'll see you next time.