1 00:00:00,530 --> 00:00:02,960 The following content is provided under a Creative 2 00:00:02,960 --> 00:00:04,370 Commons license. 3 00:00:04,370 --> 00:00:07,410 Your support will help MIT OpenCourseWare continue to 4 00:00:07,410 --> 00:00:09,200 offer high quality, educational 5 00:00:09,200 --> 00:00:11,060 resources for free. 6 00:00:11,060 --> 00:00:13,960 To make a donation or view additional materials from 7 00:00:13,960 --> 00:00:19,790 hundreds of MIT courses, visit MIT OpenCourseWare at 8 00:00:19,790 --> 00:00:21,040 ocw.mit.edu. 9 00:00:23,130 --> 00:00:24,480 PROFESSOR: There's so many things that we're going to 10 00:00:24,480 --> 00:00:26,570 start with today, one, is we're going 11 00:00:26,570 --> 00:00:27,820 to review the quiz. 12 00:00:27,820 --> 00:00:29,620 And we'll be real quick on that. 13 00:00:29,620 --> 00:00:30,840 Then, we're going to talk about object oriented 14 00:00:30,840 --> 00:00:33,235 programming, which is something that you'll probably 15 00:00:33,235 --> 00:00:35,820 be more interested in for your problem set. 16 00:00:35,820 --> 00:00:42,530 So just going down problem (1): it's false, true, false, 17 00:00:42,530 --> 00:00:44,410 false, false. 18 00:00:44,410 --> 00:00:47,928 Does anyone have any questions on this? 19 00:00:47,928 --> 00:00:48,830 No. 20 00:00:48,830 --> 00:00:49,650 Everyone good with that? 21 00:00:49,650 --> 00:00:51,525 Anyone wonder why if something's true? 22 00:00:51,525 --> 00:00:53,360 Or why something's false? 23 00:00:53,360 --> 00:00:55,240 AUDIENCE: Why is the second one false? 24 00:00:55,240 --> 00:00:55,960 PROFESSOR: Why is it false? 25 00:00:55,960 --> 00:00:56,220 AUDIENCE: Why? 26 00:00:56,220 --> 00:00:57,820 PROFESSOR: It's true. 27 00:00:57,820 --> 00:01:03,040 Because, and this is an English thing, so, or language 28 00:01:03,040 --> 00:01:06,110 thing, so it can kind of trip people up. 29 00:01:06,110 --> 00:01:10,240 But it's basically saying that there are some problems that 30 00:01:10,240 --> 00:01:13,940 you need to use recursion or iteration to solve. 31 00:01:13,940 --> 00:01:15,510 AUDIENCE: Why do you always have to use [INAUDIBLE]? 32 00:01:19,650 --> 00:01:22,470 PROFESSOR: Well, if you have a large number of inputs or the 33 00:01:22,470 --> 00:01:28,690 inputs are variable, the point is that there are certain 34 00:01:28,690 --> 00:01:31,300 problems that you would need to use recursion or iteration 35 00:01:31,300 --> 00:01:33,720 to solve them. 36 00:01:33,720 --> 00:01:35,650 There are some that you don't. 37 00:01:35,650 --> 00:01:38,930 But this is just asking if there are problems that exist. 38 00:01:38,930 --> 00:01:41,140 AUDIENCE: Can you use brute force? 39 00:01:41,140 --> 00:01:42,720 PROFESSOR: Well, brute force usually involves 40 00:01:42,720 --> 00:01:44,410 some sort of iteration. 41 00:01:44,410 --> 00:01:45,890 Because you have to iterate through all 42 00:01:45,890 --> 00:01:47,275 the possible solutions. 43 00:01:50,120 --> 00:01:51,490 Any other questions? 44 00:01:51,490 --> 00:01:53,270 OK. 45 00:01:53,270 --> 00:01:57,460 So the next one, this is just an exercise in code reading. 46 00:01:57,460 --> 00:02:02,100 And we can actually just look at how it runs. 47 00:02:08,259 --> 00:02:09,750 If I run like that. 48 00:02:09,750 --> 00:02:11,850 Also, if you don't have your quiz, I have them up here, if 49 00:02:11,850 --> 00:02:14,230 you want to pick it up. 50 00:02:14,230 --> 00:02:17,260 But that's just the output of that code. 51 00:02:17,260 --> 00:02:19,320 Does anyone not see how that works? 52 00:02:19,320 --> 00:02:21,250 Or want me to step through it? 53 00:02:32,570 --> 00:02:36,565 Question (3) was the double recurring question. 54 00:02:40,740 --> 00:02:44,860 And those are the two answers we're were looking for. 55 00:02:44,860 --> 00:02:48,140 Does anyone not see how that works? 56 00:02:48,140 --> 00:02:49,390 Or want to try and walk through it? 57 00:02:53,480 --> 00:03:00,680 The way to tackle this problem is walk through in your head. 58 00:03:00,680 --> 00:03:02,800 Let's take the first set of input. 59 00:03:07,120 --> 00:03:09,930 At the top, that's your initial call. 60 00:03:09,930 --> 00:03:17,880 Now, the string, s, here, is not less than 1, right. 61 00:03:17,880 --> 00:03:20,820 You're going to go to this double recursive call here. 62 00:03:20,820 --> 00:03:33,960 So that means you're going to get as you return. 63 00:03:33,960 --> 00:03:37,190 And the way I got this at is, I'm just taking s 64 00:03:37,190 --> 00:03:38,440 from one to the end. 65 00:03:41,860 --> 00:03:44,230 What this means is that this part is 66 00:03:44,230 --> 00:03:45,760 going to execute first. 67 00:03:45,760 --> 00:03:47,340 And it's the same thing. 68 00:03:47,340 --> 00:03:48,820 Go into the function. 69 00:03:48,820 --> 00:03:50,090 This is now s. 70 00:03:50,090 --> 00:03:52,770 This is obviously not only one character long. 71 00:03:52,770 --> 00:03:57,040 So we're going to have, again, another double recursive call. 72 00:03:57,040 --> 00:03:58,323 And it's going to look like this. 73 00:04:08,070 --> 00:04:10,680 Now, I've got this call to contend with. 74 00:04:10,680 --> 00:04:12,590 This string is one character long. 75 00:04:12,590 --> 00:04:14,800 So what does it do? 76 00:04:14,800 --> 00:04:17,700 It just returns the input. 77 00:04:17,700 --> 00:04:22,560 So, this function call is just going to return t. 78 00:04:22,560 --> 00:04:24,180 And, then, this function is going to get 79 00:04:24,180 --> 00:04:26,190 called with t, again. 80 00:04:26,190 --> 00:04:28,730 And we already know what happens when you can pass a t. 81 00:04:28,730 --> 00:04:35,230 That means that this whole function here, results in t. 82 00:04:35,230 --> 00:04:37,560 Then, we tack on the a. 83 00:04:37,560 --> 00:04:43,870 That means this function call, 'at', returns 'ta'. 84 00:04:43,870 --> 00:04:47,700 And then we pass it into this outer function here. 85 00:04:47,700 --> 00:04:50,480 And we can already guess what this is going to return 86 00:04:50,480 --> 00:04:53,680 because for this input it just reversed the characters. 87 00:04:53,680 --> 00:04:54,920 It just flipped them. 88 00:04:54,920 --> 00:04:57,690 For 'ta', it's going to flip them again. 89 00:04:57,690 --> 00:05:02,220 The entire function call here, results in 'at'. 90 00:05:05,060 --> 00:05:07,100 And then we just append 'm' to it. 91 00:05:07,100 --> 00:05:10,015 The entire return for this one is 'atm'. 92 00:05:16,820 --> 00:05:20,630 It's tricky, but you've just got to step through the code 93 00:05:20,630 --> 00:05:23,960 and step through the functions and look at each step, what 94 00:05:23,960 --> 00:05:26,360 the function is getting as input. 95 00:05:26,360 --> 00:05:27,710 This was the coding question. 96 00:05:27,710 --> 00:05:30,110 Most of the questions up until now has been, can you read 97 00:05:30,110 --> 00:05:31,630 code and understand what it's doing. 98 00:05:31,630 --> 00:05:33,395 This one asked you to actually implement a function. 99 00:05:36,080 --> 00:05:38,280 When you start with these questions you should always 100 00:05:38,280 --> 00:05:39,530 start from the specification. 101 00:05:42,230 --> 00:05:44,490 So, this function is assuming that we have a list of words 102 00:05:44,490 --> 00:05:46,140 in lowercase. 103 00:05:46,140 --> 00:05:49,205 lStr is a string of lowercase letters. 104 00:05:51,780 --> 00:05:55,960 All the letters in lStr are unique. 105 00:05:55,960 --> 00:05:58,380 And that the return of the function are going to be all 106 00:05:58,380 --> 00:06:04,610 the words in word list that have a one to one mapping 107 00:06:04,610 --> 00:06:06,760 between the letters in the word and lStr. 108 00:06:10,510 --> 00:06:15,175 In English, let's say that my lStr is raft. 109 00:06:20,030 --> 00:06:20,165 Ok. 110 00:06:20,165 --> 00:06:24,116 Assuming that I have a fairly complete word list, I'm going 111 00:06:24,116 --> 00:06:31,170 to have two words that are going to meet that criteria. 112 00:06:31,170 --> 00:06:35,490 I can say there's an r, a, f, t. 113 00:06:35,490 --> 00:06:37,680 That's pretty obvious. 114 00:06:37,680 --> 00:06:42,020 And then we have a t, f, a, r. 115 00:06:42,020 --> 00:06:45,310 That's what we're looking at. 116 00:06:45,310 --> 00:06:49,660 A lot of you did something where you iterated through all 117 00:06:49,660 --> 00:06:55,110 the words and then you had another loop inside that tried 118 00:06:55,110 --> 00:06:57,740 to find this correspondence. 119 00:06:57,740 --> 00:07:01,450 The way that we solved it-- and there are multiple 120 00:07:01,450 --> 00:07:02,180 solutions to this. 121 00:07:02,180 --> 00:07:05,200 So if your solution worked, you got full credit. 122 00:07:05,200 --> 00:07:08,550 But the solution that we came up with is first, we're going 123 00:07:08,550 --> 00:07:12,100 to take the letters in lStr and we're going to sort them. 124 00:07:12,100 --> 00:07:16,720 So we're going to have a, f, r, t. 125 00:07:16,720 --> 00:07:17,830 Alphabetically. 126 00:07:17,830 --> 00:07:22,520 And then for each word in word list, we're going to do the 127 00:07:22,520 --> 00:07:23,770 same thing. 128 00:07:25,670 --> 00:07:27,530 Raft becomes a, f, r, t. 129 00:07:27,530 --> 00:07:30,500 Fart becomes a, f, r, t, as well. 130 00:07:30,500 --> 00:07:32,530 Then it becomes just a simple string comparison. 131 00:07:37,900 --> 00:07:39,815 And all you have to do is iterate through the word list. 132 00:07:43,050 --> 00:07:44,300 Does that make sense to everyone? 133 00:07:47,880 --> 00:07:49,380 Our solution has a trick. 134 00:07:49,380 --> 00:07:50,480 You don't need to use this trick. 135 00:07:50,480 --> 00:07:52,510 A lot of people didn't and they got full credit. 136 00:07:52,510 --> 00:07:53,810 But this is one way of doing it. 137 00:07:59,790 --> 00:08:01,430 Question (5). 138 00:08:01,430 --> 00:08:06,070 This was the one where we asked you to find the problem 139 00:08:06,070 --> 00:08:07,700 with this code. 140 00:08:07,700 --> 00:08:10,710 Or, rather we asked does this code meet the specification. 141 00:08:13,740 --> 00:08:16,110 When you get a question like that, first thing you should 142 00:08:16,110 --> 00:08:19,480 do is actually look at the specification. 143 00:08:19,480 --> 00:08:23,180 Then, you should look for what this code needs to do. 144 00:08:23,180 --> 00:08:26,230 Because the specification is going to tell you what the 145 00:08:26,230 --> 00:08:27,240 function needs to do. 146 00:08:27,240 --> 00:08:29,390 If it doesn't say you need to do something then, that means 147 00:08:29,390 --> 00:08:30,640 it's undefined. 148 00:08:33,429 --> 00:08:33,449 Right? 149 00:08:33,449 --> 00:08:37,990 So In those cases, you can do whatever, as long as you meet 150 00:08:37,990 --> 00:08:40,530 the specification. 151 00:08:40,530 --> 00:08:43,480 The first requirement is it returns a list of the 152 00:08:43,480 --> 00:08:45,570 pointwise sum of the elements. 153 00:08:45,570 --> 00:08:49,120 That's the first requirement of the specification. 154 00:08:49,120 --> 00:08:52,740 And then it gives you 2 implicit requirements. 155 00:08:52,740 --> 00:08:58,070 One is this example, where it says if I'm given two vectors, 156 00:08:58,070 --> 00:09:00,350 this is what I expect the return to be. 157 00:09:00,350 --> 00:09:03,860 In this case, the vectors are two different lengths. 158 00:09:03,860 --> 00:09:06,800 It's also saying that your vectors are not always going 159 00:09:06,800 --> 00:09:08,940 to be the same length. 160 00:09:08,940 --> 00:09:13,770 In that case, you take the pointwise sum up to the 161 00:09:13,770 --> 00:09:18,880 shorter of the two lists and just tack on the remainder 162 00:09:18,880 --> 00:09:22,350 from a longer list. 163 00:09:22,350 --> 00:09:23,580 So that's the second requirement. 164 00:09:23,580 --> 00:09:25,710 The third requirement is, if you have two empty lists 165 00:09:25,710 --> 00:09:28,570 you're going to return an empty list. 166 00:09:28,570 --> 00:09:31,660 And, finally, your fourth requirement is, does not 167 00:09:31,660 --> 00:09:33,260 modify input. 168 00:09:33,260 --> 00:09:34,710 Now, you know the four requirements from the 169 00:09:34,710 --> 00:09:35,960 specification. 170 00:09:37,770 --> 00:09:40,920 And. now, you need to look in the code and see if this code 171 00:09:40,920 --> 00:09:43,700 matches all those requirements. 172 00:09:43,700 --> 00:09:44,710 The first one. 173 00:09:44,710 --> 00:09:46,750 Does it return a list containing the pointwise some 174 00:09:46,750 --> 00:09:47,780 of the elements. 175 00:09:47,780 --> 00:09:51,220 Well, this is the portion of the code that does that. 176 00:09:55,830 --> 00:09:57,280 It looks like it meets that specification. 177 00:10:01,290 --> 00:10:06,860 Result is going to be the longer of the two vectors. 178 00:10:06,860 --> 00:10:09,290 In this case if v1 longer than v2. 179 00:10:09,290 --> 00:10:11,390 We set result to v1 and other to v2. 180 00:10:11,390 --> 00:10:13,500 That's the shorter. 181 00:10:13,500 --> 00:10:17,450 Then, if we choose the longer, we set result to v2. 182 00:10:17,450 --> 00:10:21,320 And other to the shorter of the two vectors. 183 00:10:21,320 --> 00:10:22,570 Does everyone see that? 184 00:10:24,920 --> 00:10:27,320 We iterate through and we get the pointwise sum. 185 00:10:27,320 --> 00:10:30,430 We meet the first requirement. 186 00:10:30,430 --> 00:10:34,760 The second requirement is that if we're given two vectors 187 00:10:34,760 --> 00:10:38,710 that are different lengths then, we're going to sum up 188 00:10:38,710 --> 00:10:41,150 the furthest that we can, up to the length of the shortest 189 00:10:41,150 --> 00:10:43,570 one an tack on the remainder. 190 00:10:43,570 --> 00:10:47,570 Well, again, this for loop here, that does a pointwise 191 00:10:47,570 --> 00:10:50,485 sum, it only goes up to the length of the shorter list. 192 00:10:53,180 --> 00:10:55,610 Second requirement met. 193 00:10:55,610 --> 00:10:57,010 Third requirement. 194 00:10:57,010 --> 00:10:58,600 Two empty vectors returns an empty vector. 195 00:11:01,310 --> 00:11:03,130 Well, if I have an empty vector here, this 196 00:11:03,130 --> 00:11:03,980 is going to be 0. 197 00:11:03,980 --> 00:11:06,190 This FOR loop is never going to execute. 198 00:11:06,190 --> 00:11:08,570 And my result is going to be empty. 199 00:11:11,870 --> 00:11:14,420 And, then, finally that leaves a fourth requirement, does not 200 00:11:14,420 --> 00:11:15,670 modify the input. 201 00:11:18,680 --> 00:11:20,580 What's result? 202 00:11:20,580 --> 00:11:22,700 Result is what we're ultimately returning. 203 00:11:22,700 --> 00:11:24,510 And that's the only thing that we really 204 00:11:24,510 --> 00:11:27,100 modify in this function. 205 00:11:30,070 --> 00:11:34,640 Result in this case, is v1 or v2. 206 00:11:34,640 --> 00:11:35,810 But they're aliased. 207 00:11:35,810 --> 00:11:38,570 So it's modifying the inputs and that's a violation. 208 00:11:38,570 --> 00:11:42,415 So the answer to this problem is a total of six characters. 209 00:11:46,840 --> 00:11:51,220 Some of you wrote entire redefinitions of the function 210 00:11:51,220 --> 00:11:54,590 or, copied Ryan's code from the reviews. 211 00:11:54,590 --> 00:11:58,300 Perfectly acceptable, but way too much work. 212 00:11:58,300 --> 00:12:02,140 Remember, programmers are lazy. 213 00:12:02,140 --> 00:12:03,390 That's all we were looking for. 214 00:12:06,060 --> 00:12:09,070 If you used the code from Ryan or, you had a different 215 00:12:09,070 --> 00:12:11,540 implementation that met the specifications, but was 216 00:12:11,540 --> 00:12:15,060 completely different you got full credit. 217 00:12:15,060 --> 00:12:15,927 You have a question? 218 00:12:15,927 --> 00:12:17,177 AUDIENCE: [INAUDIBLE] 219 00:12:24,376 --> 00:12:24,873 . 220 00:12:24,873 --> 00:12:27,358 I'm just trying to figure out what the distinction is 221 00:12:27,358 --> 00:12:28,849 [INAUDIBLE] 222 00:12:28,849 --> 00:12:29,029 do a dot copy. 223 00:12:29,029 --> 00:12:31,831 Why one is better than the other. 224 00:12:31,831 --> 00:12:34,753 PROFESSOR: Dot copy applies only to dictionaries. 225 00:12:34,753 --> 00:12:35,520 AUDIENCE: Oh. 226 00:12:35,520 --> 00:12:47,908 PROFESSOR: So if we try and do a dot copy on a list. 227 00:12:47,908 --> 00:12:48,894 AUDIENCE: Oh, OK. 228 00:12:48,894 --> 00:12:49,830 PROFESSOR: Got it. 229 00:12:49,830 --> 00:12:52,600 I think we took one point for that or something. 230 00:12:52,600 --> 00:12:58,440 We knew what your intent was but you didn't have your IDE 231 00:12:58,440 --> 00:12:59,690 there with you. 232 00:13:04,200 --> 00:13:06,605 Question (6) was another exercise in code reading. 233 00:13:09,110 --> 00:13:13,530 The way that I would attack this one is to figure out what 234 00:13:13,530 --> 00:13:16,890 the two functions do first. 235 00:13:16,890 --> 00:13:20,330 Let's take the easier of the two, addUp. 236 00:13:20,330 --> 00:13:24,735 Takes a dictionaries input and it has a variable result that 237 00:13:24,735 --> 00:13:26,610 it initially sets to 0. 238 00:13:26,610 --> 00:13:31,010 And then it iterates through all the keys in the dictionary 239 00:13:31,010 --> 00:13:32,310 and adds them to result. 240 00:13:32,310 --> 00:13:36,060 Basically, its assuming that the values in the dictionary 241 00:13:36,060 --> 00:13:39,660 are some sort of number, and it's summing them up, and 242 00:13:39,660 --> 00:13:41,080 returning the total. 243 00:13:45,150 --> 00:13:50,580 And, then, this f function here -- 244 00:13:50,580 --> 00:13:54,870 takes the dictionary it zeroes out any of the 245 00:13:54,870 --> 00:13:56,620 keys it might have. 246 00:13:56,620 --> 00:14:00,770 And then it iterates through all the characters in s. 247 00:14:00,770 --> 00:14:03,320 If the character is already in the dictionary then, it's 248 00:14:03,320 --> 00:14:04,370 going to add 1 to it. 249 00:14:04,370 --> 00:14:06,330 So it's going to increment it. 250 00:14:06,330 --> 00:14:08,570 And if the character isn't in the dictionary, then, it's 251 00:14:08,570 --> 00:14:10,750 going to set up to 0. 252 00:14:10,750 --> 00:14:15,320 Then, it's going to return the result in dictionary. 253 00:14:15,320 --> 00:14:19,540 Knowing that, the function becomes pretty easy. 254 00:14:19,540 --> 00:14:24,910 f of abbc for d1, which is an empty dictionary. 255 00:14:24,910 --> 00:14:31,690 Just walking through it, starting from this point, if 256 00:14:31,690 --> 00:14:37,320 we iterate a, it's not going to be in the dictionary. 257 00:14:37,320 --> 00:14:40,440 So we're going to set d of a to 0. 258 00:14:40,440 --> 00:14:44,150 Then, we move on to the next character, b. 259 00:14:44,150 --> 00:14:45,250 b is not in the dictionary. 260 00:14:45,250 --> 00:14:48,060 So d of b becomes 0. 261 00:14:48,060 --> 00:14:50,152 Now, we get one of the second b. 262 00:14:50,152 --> 00:14:52,380 b Is now in the dictionary. 263 00:14:52,380 --> 00:14:54,720 So we increment b. 264 00:14:54,720 --> 00:14:58,020 Now, d of b is 1. 265 00:14:58,020 --> 00:15:01,370 Then, we move on to the final character, c, again not the 266 00:15:01,370 --> 00:15:01,860 dictionary. 267 00:15:01,860 --> 00:15:03,790 So we set d of c to 0. 268 00:15:03,790 --> 00:15:05,040 Then, we return the dictionary. 269 00:15:07,970 --> 00:15:11,390 That means that in my dictionary, I have three keys 270 00:15:11,390 --> 00:15:12,900 a, b, and c. 271 00:15:12,900 --> 00:15:16,135 And they have values 0, 1, and 0 Respectively. 272 00:15:18,840 --> 00:15:24,130 So add up is going to return 1. 273 00:15:24,130 --> 00:15:27,040 And same process for all of these. 274 00:15:27,040 --> 00:15:29,200 Question I have here is what happens when Python 275 00:15:29,200 --> 00:15:30,450 gets to that line? 276 00:15:32,670 --> 00:15:33,920 Anyone. 277 00:15:36,160 --> 00:15:37,120 It's going to be an error. 278 00:15:37,120 --> 00:15:38,370 Why? 279 00:15:39,918 --> 00:15:41,350 AUDIENCE: Result is a local variable. 280 00:15:41,350 --> 00:15:41,940 PROFESSOR: Right. 281 00:15:41,940 --> 00:15:44,050 Result is a local variable to addUP. 282 00:15:49,780 --> 00:15:51,030 There you go. 283 00:16:15,080 --> 00:16:18,210 So, again, the approach to this problem is to figure out 284 00:16:18,210 --> 00:16:22,290 which each of the functions do, and then right walk 285 00:16:22,290 --> 00:16:24,830 through the code. 286 00:16:24,830 --> 00:16:26,970 Did anyone have trouble with this or want me to actually 287 00:16:26,970 --> 00:16:28,220 step through it? 288 00:16:34,820 --> 00:16:39,780 First, when f gets an integer, it just prints out 289 00:16:39,780 --> 00:16:41,460 the integer in binary. 290 00:16:44,350 --> 00:16:49,900 And then, this loop here, prints out the binary 291 00:16:49,900 --> 00:16:52,120 representations from 0, 1, 2. 292 00:16:57,760 --> 00:17:00,305 Why is the first output none in this case? 293 00:17:07,190 --> 00:17:14,200 Because in that first iteration i is 0. 294 00:17:14,200 --> 00:17:16,800 When f is called, n, is going to be 0. 295 00:17:16,800 --> 00:17:18,560 It's just going to return nothing. 296 00:17:18,560 --> 00:17:19,810 So it gives you nothing. 297 00:17:22,349 --> 00:17:35,940 Now, the next question was under the assumption that the 298 00:17:35,940 --> 00:17:40,670 log base 2 is o of n, what is the order of the function, f? 299 00:17:43,180 --> 00:17:49,710 And to figure this out, you know that this function here 300 00:17:49,710 --> 00:17:51,440 is o of n, because we told you. 301 00:17:53,940 --> 00:17:55,590 We know that that's one of the first things 302 00:17:55,590 --> 00:17:56,780 that's called in f. 303 00:17:56,780 --> 00:18:00,350 So automatically, a run time is o of n. 304 00:18:04,300 --> 00:18:12,340 Now, this loop here, iterates how many times? 305 00:18:12,340 --> 00:18:13,590 Log n. 306 00:18:17,510 --> 00:18:22,190 Well, log base 2n, to be explicit. 307 00:18:22,190 --> 00:18:25,250 For this function, which is the dominating term here? 308 00:18:29,100 --> 00:18:32,365 When we want to see o of n, it's just going to be that. 309 00:18:35,680 --> 00:18:42,670 If you had o of n plus log n, I think we took a point. 310 00:18:42,670 --> 00:18:45,830 Just because when we talk about worst case scenario, 311 00:18:45,830 --> 00:18:49,140 we're looking for what the dominating portion of this 312 00:18:49,140 --> 00:18:50,390 function is. 313 00:18:55,780 --> 00:18:58,490 How does it do it? 314 00:18:58,490 --> 00:19:02,060 You want to walk through the code now? 315 00:19:02,060 --> 00:19:04,050 Alright. 316 00:19:04,050 --> 00:19:07,250 First thing it does, is it gets something it's calling 317 00:19:07,250 --> 00:19:08,490 curve digit. 318 00:19:08,490 --> 00:19:11,800 All that is, is you take the log base 2 of a number you're 319 00:19:11,800 --> 00:19:15,190 going to get the number of binary digits in it. 320 00:19:15,190 --> 00:19:19,660 Think of it as like if I have three which binary is 1, 1. 321 00:19:23,060 --> 00:19:26,440 If I take log base2 of this, then my curve digit 322 00:19:26,440 --> 00:19:28,320 is going to be 1. 323 00:19:41,900 --> 00:19:43,480 I'm not sure, Python's been around too long. 324 00:19:54,160 --> 00:19:56,950 Well, 1.5 but if we truncate it to an int 325 00:19:56,950 --> 00:19:58,200 it's going to be 1. 326 00:20:00,150 --> 00:20:02,590 That's kind of like our position marker 327 00:20:02,590 --> 00:20:04,680 in the binary number. 328 00:20:04,680 --> 00:20:06,710 Now, we're going to iterate while the current digit is 329 00:20:06,710 --> 00:20:10,370 greater than or equal to 0. 330 00:20:10,370 --> 00:20:14,270 We're basically going to start here and move down the line in 331 00:20:14,270 --> 00:20:15,520 this direction. 332 00:20:19,170 --> 00:20:24,930 All it does is says if my n mod 2 -- so I'm checking to 333 00:20:24,930 --> 00:20:26,520 see if it's odd or even -- 334 00:20:26,520 --> 00:20:28,240 if it's going to be 1 or 0. 335 00:20:28,240 --> 00:20:30,790 In this case, it's going to be 1 to the power of the current 336 00:20:30,790 --> 00:20:34,364 digit, which in this case is 1. 337 00:20:34,364 --> 00:20:35,930 I'm sorry, misspoke. 338 00:20:35,930 --> 00:20:40,170 n is 3, The remainder is going to be 1. 339 00:20:40,170 --> 00:20:46,750 In this case 1 to the power of 1 is going to be 1. 340 00:20:46,750 --> 00:20:48,620 That's less than n, which it is. 341 00:20:48,620 --> 00:20:52,680 Then, my ans is going to be ans plus 1. 342 00:20:52,680 --> 00:20:56,860 I'm going to add 1 to the string and construct it. 343 00:20:56,860 --> 00:21:02,550 Then, I'm going to subtract whatever this part is. 344 00:21:02,550 --> 00:21:09,910 So 2 to the current digit, in this case to the 1. 345 00:21:09,910 --> 00:21:13,700 It's just going to subtract this off. 346 00:21:13,700 --> 00:21:16,720 Then, curve digit is going to be decremented and moved here. 347 00:21:19,600 --> 00:21:25,650 Then, in this iteration, curve digit is going to be 0 and n 348 00:21:25,650 --> 00:21:26,830 is going to be 1. 349 00:21:26,830 --> 00:21:28,960 So 1 mod 2 is going to be 1. 350 00:21:32,500 --> 00:21:33,370 Curve digit is 0. 351 00:21:33,370 --> 00:21:36,835 So that's going to be 1 less than 1. 352 00:21:40,190 --> 00:21:43,170 It should print it out. 353 00:21:43,170 --> 00:21:45,055 I was not prepared for that. 354 00:21:51,210 --> 00:21:51,254 All right. 355 00:21:51,254 --> 00:21:53,310 So. the final question -- 356 00:21:53,310 --> 00:21:54,560 number (8). 357 00:21:59,560 --> 00:22:03,590 Big O notation, if we match it up, does anyone 358 00:22:03,590 --> 00:22:04,340 know what it is? 359 00:22:04,340 --> 00:22:05,550 AUDIENCE: Upper bound. 360 00:22:05,550 --> 00:22:07,140 PROFESSOR: Yeah. 361 00:22:07,140 --> 00:22:11,660 A lot of you put the expected running time. 362 00:22:11,660 --> 00:22:14,130 And the letters are messed up on this but-- 363 00:22:14,130 --> 00:22:16,530 a lot of you put the expected running time, but when we are 364 00:22:16,530 --> 00:22:18,500 talking about Big O, we're talking 365 00:22:18,500 --> 00:22:20,720 about worst case scenario. 366 00:22:20,720 --> 00:22:22,530 So, that's the upper bound. 367 00:22:22,530 --> 00:22:25,130 There is an expected bound. 368 00:22:25,130 --> 00:22:29,930 If you decide to do any more algorithm analysis, you have 369 00:22:29,930 --> 00:22:33,013 Big O, expected, and little o. 370 00:22:35,550 --> 00:22:39,860 If I plot the run time of a given function, my 371 00:22:39,860 --> 00:22:41,680 Big O might be this. 372 00:22:41,680 --> 00:22:44,800 The worst time, my expected, might be like that. 373 00:22:44,800 --> 00:22:49,370 And my absolute best case might be like that. 374 00:22:49,370 --> 00:22:51,640 When we say they go that's what we're looking for. 375 00:22:54,830 --> 00:22:57,350 Alright Newton's method. 376 00:22:57,350 --> 00:22:59,170 What is that an example of? 377 00:22:59,170 --> 00:23:01,470 AUDIENCE: [INAUDIBLE] 378 00:23:01,470 --> 00:23:03,980 AUDIENCE: Yeah. 379 00:23:03,980 --> 00:23:05,230 These don't look right. 380 00:23:08,020 --> 00:23:10,600 You know what, I'm sorry. 381 00:23:10,600 --> 00:23:12,055 This is a different version of the quiz. 382 00:23:15,040 --> 00:23:17,750 Newton's method, that's an approximation. 383 00:23:17,750 --> 00:23:21,170 Then the last one was recursion on your test. 384 00:23:21,170 --> 00:23:22,640 The answer we were looking for was induction. 385 00:23:27,610 --> 00:23:28,860 That's that. 386 00:23:31,440 --> 00:23:32,690 Anyone have any actual questions. 387 00:23:35,480 --> 00:23:37,980 AUDIENCE: Go back to number (4). 388 00:23:37,980 --> 00:23:38,640 PROFESSOR: Number (4). 389 00:23:38,640 --> 00:23:39,129 AUDIENCE: Yeah. 390 00:23:39,129 --> 00:23:40,379 [INAUDIBLE] 391 00:23:52,820 --> 00:23:54,650 PROFESSOR: What was the part that you did not understand 392 00:23:54,650 --> 00:23:57,178 with number (4)? 393 00:23:57,178 --> 00:24:01,146 AUDIENCE: I thought it was confusing how to join the 394 00:24:01,146 --> 00:24:07,346 [INAUDIBLE] together or how to go through them to see if you 395 00:24:07,346 --> 00:24:08,596 know exactly [INAUDIBLE]. 396 00:24:10,590 --> 00:24:15,880 PROFESSOR: Well, that's kind of the trick we have here. 397 00:24:15,880 --> 00:24:18,110 We know we have a list of words so to iterate through 398 00:24:18,110 --> 00:24:20,660 the words is just a FOR loop. 399 00:24:20,660 --> 00:24:24,720 So that's what that for word in wordList does. 400 00:24:24,720 --> 00:24:29,980 To do the thing where you match the letters one to one, 401 00:24:29,980 --> 00:24:34,960 what we implemented here is, we first take lStr and we sort 402 00:24:34,960 --> 00:24:38,310 it, sort the characters in lStr. 403 00:24:38,310 --> 00:24:46,210 Then, what we do for wordList is for each word, we sort the 404 00:24:46,210 --> 00:24:48,170 characters in that word. 405 00:24:48,170 --> 00:24:50,820 And what that does is, it allows us to just directly 406 00:24:50,820 --> 00:24:52,700 compare the two strings. 407 00:24:52,700 --> 00:24:55,360 And if they're equal, then we've met the criteria for 408 00:24:55,360 --> 00:24:59,015 adding it into the wordList, Or the return wordList. 409 00:25:05,700 --> 00:25:07,150 That's the quiz. 410 00:25:07,150 --> 00:25:09,952 If you don't have it, you can come pick it up. 411 00:25:09,952 --> 00:25:13,389 AUDIENCE: Sorry, I was just going to ask really quick. 412 00:25:13,389 --> 00:25:17,317 If you're getting a [INAUDIBLE] string, you're 413 00:25:17,317 --> 00:25:21,326 concatenating [INAUDIBLE] strings, the empty string, why 414 00:25:21,326 --> 00:25:23,209 can't you just set it equal to the [INAUDIBLE] string? 415 00:25:23,209 --> 00:25:25,664 Is there something about the way that operates that you 416 00:25:25,664 --> 00:25:26,660 couldn't do it? 417 00:25:26,660 --> 00:25:31,650 PROFESSOR: Yeah, so if I say my string is 'abcdef,' and I 418 00:25:31,650 --> 00:25:37,420 just say sorted(s), this returns a list. 419 00:25:37,420 --> 00:25:45,440 What I'm doing with join is I'm just converting 420 00:25:45,440 --> 00:25:47,400 it back to a string. 421 00:25:47,400 --> 00:25:48,650 Got it? 422 00:25:54,830 --> 00:26:00,120 OK, so on to object oriented programming. 423 00:26:00,120 --> 00:26:05,755 So what can someone tell me about classes? 424 00:26:08,960 --> 00:26:10,210 What do they allow you to do? 425 00:26:13,341 --> 00:26:15,233 AUDIENCE: Allow you to define a custom type. 426 00:26:15,233 --> 00:26:16,450 PROFESSOR: Yes. 427 00:26:16,450 --> 00:26:19,380 So one thing they allow you to do is to define a custom type. 428 00:26:33,000 --> 00:26:43,110 Now, when you define a class, you can group your methods and 429 00:26:43,110 --> 00:26:47,070 data together with something called encapsulation. 430 00:26:47,070 --> 00:26:54,200 So first stuff, we've actually already been using classes. 431 00:26:54,200 --> 00:26:55,910 We just didn't tell you, right? 432 00:26:55,910 --> 00:27:03,440 So ints, floats, dicts, et cetera, these are 433 00:27:03,440 --> 00:27:04,766 all types of classes. 434 00:27:08,110 --> 00:27:12,810 And each of these, we've already seen them, have 435 00:27:12,810 --> 00:27:17,230 something called methods associated with them, right? 436 00:27:17,230 --> 00:27:20,220 Methods are basically functions that are associated 437 00:27:20,220 --> 00:27:22,210 with a given class. 438 00:27:22,210 --> 00:27:27,840 So for example, if I have the str class, which everyone's 439 00:27:27,840 --> 00:27:33,590 seen, then it has, say, a method, dot lower. 440 00:27:33,590 --> 00:27:35,820 So if I have s equal-- 441 00:27:35,820 --> 00:27:39,890 well, let me write it up here on the code. 442 00:27:39,890 --> 00:27:46,160 If I say something like s equal 'abcdef,' I can call the 443 00:27:46,160 --> 00:27:48,010 method, lower. 444 00:27:48,010 --> 00:27:49,880 So we've actually already been doing object oriented 445 00:27:49,880 --> 00:27:50,260 programming. 446 00:27:50,260 --> 00:27:51,510 You just didn't know it. 447 00:27:54,190 --> 00:27:57,660 Along with that, classes have methods. 448 00:27:57,660 --> 00:27:58,910 And they also have something else. 449 00:28:02,150 --> 00:28:04,660 Someone help me? 450 00:28:04,660 --> 00:28:05,110 What? 451 00:28:05,110 --> 00:28:06,024 AUDIENCE: Parameters? 452 00:28:06,024 --> 00:28:06,952 Variables? 453 00:28:06,952 --> 00:28:10,550 PROFESSOR: I'm looking for something-- 454 00:28:10,550 --> 00:28:12,510 terminology-wise, attributes. 455 00:28:12,510 --> 00:28:15,873 So they're a way of grouping methods and attributes. 456 00:28:19,930 --> 00:28:24,250 So when we talk about attributes, we're talking 457 00:28:24,250 --> 00:28:29,030 about things that pertain to a specific instance of a class. 458 00:28:29,030 --> 00:28:37,100 So let's say that I have a real world example. 459 00:28:37,100 --> 00:28:39,500 I have a person class. 460 00:28:39,500 --> 00:28:41,110 We've already kind of seen this guy. 461 00:28:44,810 --> 00:28:48,740 A person has multiple instances. 462 00:28:48,740 --> 00:28:52,390 So there's an instance of Mitch. 463 00:28:52,390 --> 00:28:53,820 There's an instance of Garthi. 464 00:28:59,130 --> 00:29:04,260 There's an instance of Phillipe. 465 00:29:04,260 --> 00:29:08,630 We're all people, mostly human. 466 00:29:08,630 --> 00:29:10,390 And we all have attributes. 467 00:29:10,390 --> 00:29:15,780 So we all have an age, when we were born. 468 00:29:15,780 --> 00:29:17,140 We all have a name. 469 00:29:17,140 --> 00:29:22,570 Some of us have hair and other attributes, right? 470 00:29:25,100 --> 00:29:27,460 We also have actions that we can take. 471 00:29:27,460 --> 00:29:28,830 So I can talk. 472 00:29:28,830 --> 00:29:30,130 And I could walk. 473 00:29:30,130 --> 00:29:34,340 I can talk to you, you, you, you, you, and you. 474 00:29:34,340 --> 00:29:37,810 So a method that I could define for a person might be 475 00:29:37,810 --> 00:29:40,350 talk to someone. 476 00:29:40,350 --> 00:29:45,280 So that's one way of thinking about objects. 477 00:29:45,280 --> 00:29:50,260 So object-oriented programming also gives us something called 478 00:29:50,260 --> 00:29:52,170 inheritance, right? 479 00:29:52,170 --> 00:29:54,050 So I could think of-- 480 00:29:54,050 --> 00:29:56,900 if I'm going along with my person analogy-- 481 00:29:56,900 --> 00:30:07,200 I could think of sub-classing person if I'm willing to draw 482 00:30:07,200 --> 00:30:08,450 hard binary on the genders. 483 00:30:11,020 --> 00:30:15,270 You have males and you have females, right? 484 00:30:15,270 --> 00:30:17,690 And in this column, I might have Tracy. 485 00:30:20,220 --> 00:30:22,190 I'm just picking on people who come to office hours. 486 00:30:26,520 --> 00:30:31,000 And then, Garthi, et cetera. 487 00:30:31,000 --> 00:30:37,080 Now, the inheritance portion of it is important because 488 00:30:37,080 --> 00:30:40,110 I've already said that one of my methods on a person is I 489 00:30:40,110 --> 00:30:41,260 can talk to people. 490 00:30:41,260 --> 00:30:43,040 I can talk to other people. 491 00:30:43,040 --> 00:30:46,010 It shouldn't matter if I'm talking to Garthi, as a male, 492 00:30:46,010 --> 00:30:47,760 versus Tracy, as a female. 493 00:30:47,760 --> 00:30:50,000 I talk to people basically the same. 494 00:30:50,000 --> 00:30:54,650 So that gets into something called polymorphism, which is 495 00:30:54,650 --> 00:31:01,150 we treat objects with a common super class the same as their 496 00:31:01,150 --> 00:31:02,870 sub-classes. 497 00:31:02,870 --> 00:31:14,260 So as another example, let's say that I have dogs and-- 498 00:31:14,260 --> 00:31:18,140 what's another canine, foxes? 499 00:31:18,140 --> 00:31:20,440 I'm not going to necessarily talk to canines the way that I 500 00:31:20,440 --> 00:31:22,100 talk to a person. 501 00:31:22,100 --> 00:31:25,370 So they would exist with a different super-class. 502 00:31:25,370 --> 00:31:26,790 And then, we could all be animals. 503 00:31:29,540 --> 00:31:33,130 So really, what object-oriented programming 504 00:31:33,130 --> 00:31:35,150 gives you is a different way of thinking about how you're 505 00:31:35,150 --> 00:31:38,400 modeling your world. 506 00:31:38,400 --> 00:31:42,790 And what I want to do is now, instead of just talking about 507 00:31:42,790 --> 00:31:45,530 these abstract things, walk through 508 00:31:45,530 --> 00:31:46,780 some concrete examples. 509 00:31:49,070 --> 00:31:52,030 So the first thing that I want to illustrate is let's say 510 00:31:52,030 --> 00:31:53,700 that we want to create a person. 511 00:31:53,700 --> 00:31:55,990 But we don't want to use object oriented programming. 512 00:31:55,990 --> 00:31:59,080 Or, we don't want to use classes. 513 00:31:59,080 --> 00:32:01,830 Professor Guttag will get angry at me if I say we're not 514 00:32:01,830 --> 00:32:03,950 using object oriented programming. 515 00:32:03,950 --> 00:32:08,480 So let's say I have a function, makePerson. 516 00:32:08,480 --> 00:32:12,820 And I'm going to represent a person as a dictionary that 517 00:32:12,820 --> 00:32:17,590 has name, age, height, weight as keys. 518 00:32:20,440 --> 00:32:23,780 All makePerson does is it takes these things as 519 00:32:23,780 --> 00:32:27,370 parameters, makes a dictionary with them as values, and then 520 00:32:27,370 --> 00:32:29,800 returns a dictionary. 521 00:32:29,800 --> 00:32:31,290 Then, I have a bunch of helper functions, 522 00:32:31,290 --> 00:32:34,150 like get_name of person. 523 00:32:34,150 --> 00:32:35,820 All that does is it just returns 524 00:32:35,820 --> 00:32:38,520 whatever's in the name key. 525 00:32:38,520 --> 00:32:42,130 I can also set the name in case a person decides they 526 00:32:42,130 --> 00:32:45,090 don't want to be known as Mitch. 527 00:32:45,090 --> 00:32:46,310 They want to be known as Mitchell or 528 00:32:46,310 --> 00:32:47,560 something like that. 529 00:32:49,740 --> 00:32:51,750 So I have a bunch of these getter and setter function. 530 00:32:51,750 --> 00:32:56,600 These are called accessor and mutator functions, whatever 531 00:32:56,600 --> 00:32:57,850 terminology you want to use. 532 00:33:00,370 --> 00:33:04,130 I can also define another function that will do 533 00:33:04,130 --> 00:33:06,650 something like print out the person. 534 00:33:06,650 --> 00:33:10,450 So in this case, I'm just going to print out name, age, 535 00:33:10,450 --> 00:33:12,040 height, and weight. 536 00:33:12,040 --> 00:33:16,860 And to see this in action, I'm going to make a person, Mitch, 537 00:33:16,860 --> 00:33:18,960 32 70, 200. 538 00:33:18,960 --> 00:33:21,140 And then, Serena, 25, 65, 130. 539 00:33:21,140 --> 00:33:24,060 I don't know if these are actually correct. 540 00:33:24,060 --> 00:33:25,880 So don't quote me on it. 541 00:33:28,480 --> 00:33:29,730 I have a syntax error. 542 00:33:34,920 --> 00:33:39,440 So if I run this, then all it's going to do is just print 543 00:33:39,440 --> 00:33:40,870 out what I'd expect it to print out. 544 00:33:45,700 --> 00:33:47,370 I can also set my age. 545 00:33:47,370 --> 00:33:53,860 So I can go back in time to 25, which is a great age. 546 00:33:53,860 --> 00:33:55,110 And now, I'm 25. 547 00:33:58,520 --> 00:34:03,250 Now, this is fine if you just want to do simple things. 548 00:34:03,250 --> 00:34:06,940 But the reason why we kind of like object oriented 549 00:34:06,940 --> 00:34:12,670 programming is because we run into difficulties. 550 00:34:12,670 --> 00:34:17,500 So let's say that I print out the type of Mitch. 551 00:34:17,500 --> 00:34:18,750 It says I'm a dict. 552 00:34:23,300 --> 00:34:25,900 But it doesn't give me any more information. 553 00:34:25,900 --> 00:34:30,750 So that means that I could define any random old dict and 554 00:34:30,750 --> 00:34:33,130 pass it to some of my functions that I've defined to 555 00:34:33,130 --> 00:34:35,540 work on people. 556 00:34:35,540 --> 00:34:36,920 And it will probably give me an error. 557 00:34:40,230 --> 00:34:46,080 It also makes other operations kind of non-intuitive. 558 00:34:46,080 --> 00:34:50,190 So let's say that I want to figure out if 559 00:34:50,190 --> 00:34:51,409 two people are equal. 560 00:34:51,409 --> 00:34:55,630 Well, I could do that by defining a function, 561 00:34:55,630 --> 00:34:59,990 people_equal, or equal_people, and passing in it a person1 562 00:34:59,990 --> 00:35:02,920 and person2. 563 00:35:02,920 --> 00:35:06,500 And for our intents and purposes, it's just going to 564 00:35:06,500 --> 00:35:10,520 be if they have the same name, they're the same person. 565 00:35:10,520 --> 00:35:12,922 So this is going to, of course, do what we expect it 566 00:35:12,922 --> 00:35:15,050 to do and return false, right? 567 00:35:15,050 --> 00:35:16,795 Because Serena and Mitch aren't the same person. 568 00:35:19,500 --> 00:35:21,460 But it's kind of awkward. 569 00:35:21,460 --> 00:35:28,310 And if we do things using classes, it becomes a little 570 00:35:28,310 --> 00:35:29,940 bit more elegant. 571 00:35:29,940 --> 00:35:33,710 And you get a lot more power. 572 00:35:33,710 --> 00:35:37,530 So let's say I do the exact same thing with a class. 573 00:35:41,010 --> 00:35:42,940 So I have the class keyword. 574 00:35:42,940 --> 00:35:47,460 I have the name of my object, or my class, my new type. 575 00:35:47,460 --> 00:35:49,910 And then, I have this thing called init. 576 00:35:49,910 --> 00:35:57,600 All init does is it says, when I get a new person object, 577 00:35:57,600 --> 00:36:01,790 Python automatically calls init with whatever parameters 578 00:36:01,790 --> 00:36:07,580 are specified and tells the object to make attributes or 579 00:36:07,580 --> 00:36:09,170 to set itself up. 580 00:36:09,170 --> 00:36:11,405 So in this case-- 581 00:36:18,000 --> 00:36:20,980 need a bigger screen-- 582 00:36:20,980 --> 00:36:24,130 I'm making a Mitch person, all right? 583 00:36:24,130 --> 00:36:27,160 And the way that you make a new object, or an instance of 584 00:36:27,160 --> 00:36:29,790 person, is you have the class name. 585 00:36:29,790 --> 00:36:32,330 And then, you pass it whatever parameters are 586 00:36:32,330 --> 00:36:33,892 specified in init. 587 00:36:36,490 --> 00:36:43,280 Now, behind the scenes, Python will create a chunk of memory. 588 00:36:43,280 --> 00:36:47,180 And then, it'll call this init function. 589 00:36:47,180 --> 00:36:51,220 And it'll pass a reference to that chunk of memory. 590 00:36:51,220 --> 00:37:23,960 So visually, let's say this is your magical memory. 591 00:37:23,960 --> 00:37:26,850 Python sees us call person, goes in, 592 00:37:26,850 --> 00:37:29,180 grabs a chunk of memory-- 593 00:37:29,180 --> 00:37:30,430 this marker sucks-- 594 00:37:33,590 --> 00:37:37,190 grabs a chunk of memory and says, this chunk of memory is 595 00:37:37,190 --> 00:37:39,240 of type person. 596 00:37:42,700 --> 00:37:45,940 Then, it calls init. 597 00:37:45,940 --> 00:38:00,950 init says, basically, Mitch is a reference to 598 00:38:00,950 --> 00:38:02,900 this chunk of memory. 599 00:38:02,900 --> 00:38:05,040 This is a self parameter. 600 00:38:05,040 --> 00:38:06,290 And then, it has the other parameters. 601 00:38:17,350 --> 00:38:21,920 And then, in the init method, all we're doing is we're 602 00:38:21,920 --> 00:38:26,670 creating new attributes on this chunk of memory. 603 00:38:26,670 --> 00:38:29,600 So we're going to have an attribute name. 604 00:38:29,600 --> 00:38:34,560 We're going to have an attribute age, height, weight. 605 00:38:45,350 --> 00:38:50,100 And then, we have a bunch of accessors or getters, mutators 606 00:38:50,100 --> 00:38:51,370 or setters. 607 00:38:51,370 --> 00:38:54,390 Same exact thing as the functions that I showed, that 608 00:38:54,390 --> 00:38:56,350 we had when we were trying to do this without classes. 609 00:38:59,850 --> 00:39:01,480 The difference is that these are 610 00:39:01,480 --> 00:39:04,370 lexically scoped to person. 611 00:39:04,370 --> 00:39:10,730 They are methods for an instance of type person. 612 00:39:10,730 --> 00:39:14,600 Whereas before, they were just functions that worked on 613 00:39:14,600 --> 00:39:16,640 something we called a person. 614 00:39:16,640 --> 00:39:18,150 But a person was actually a dict. 615 00:39:23,080 --> 00:39:29,070 So let me just run this. 616 00:39:29,070 --> 00:39:32,865 So if I run this, I'm just going to create a person, a 617 00:39:32,865 --> 00:39:35,245 Mitch person and a Sarina person. 618 00:39:35,245 --> 00:39:37,626 I'm going to print out Mitch. 619 00:39:37,626 --> 00:39:41,280 It's the same thing that I had before, right? 620 00:39:41,280 --> 00:39:42,530 Except I'm using a class. 621 00:39:47,090 --> 00:39:50,320 Now, if I want to use one of the accessors, so I want to 622 00:39:50,320 --> 00:39:57,750 get younger again, I can just take my object, Mitch, and I 623 00:39:57,750 --> 00:40:01,140 can call the set_age method and pass it in my new age. 624 00:40:05,280 --> 00:40:06,530 And I've lost seven years. 625 00:40:10,120 --> 00:40:16,370 All right, now so far, this is just a different way of doing 626 00:40:16,370 --> 00:40:19,190 the same thing, right? 627 00:40:19,190 --> 00:40:23,250 But if we look at the type of Mitch, I'm a person. 628 00:40:25,870 --> 00:40:31,500 So there's now some extra information that we didn't 629 00:40:31,500 --> 00:40:36,430 have before when we were using a dict to represent a person. 630 00:40:36,430 --> 00:40:38,260 Before, it could've been any dict. 631 00:40:38,260 --> 00:40:40,300 We didn't know that it represented a person. 632 00:40:40,300 --> 00:40:43,530 The only reason that it represented a person before we 633 00:40:43,530 --> 00:40:49,850 used a class was because we had set certain keys to 634 00:40:49,850 --> 00:40:51,050 certain values. 635 00:40:51,050 --> 00:40:52,980 But other than that, it was just a dict. 636 00:40:52,980 --> 00:40:58,770 Here, this is marked as being a person. 637 00:40:58,770 --> 00:41:02,500 And that also gives us some additional kind of power, 638 00:41:02,500 --> 00:41:05,430 which we'll see in a little bit. 639 00:41:05,430 --> 00:41:10,670 So now, I've done something sneaky. 640 00:41:10,670 --> 00:41:16,780 And I've created a way of comparing Mitch and Sarina. 641 00:41:16,780 --> 00:41:19,390 Before I had that function, people_equal. 642 00:41:19,390 --> 00:41:22,730 Now, I can use the double equal operator, which is 643 00:41:22,730 --> 00:41:23,680 something that we're used to. 644 00:41:23,680 --> 00:41:26,180 We use it with all the other types. 645 00:41:26,180 --> 00:41:27,430 Why don't we use it with people? 646 00:41:30,110 --> 00:41:36,880 The way that we define that is that on this person class, I 647 00:41:36,880 --> 00:41:41,190 have to find this function underbar, underbar, EQ, 648 00:41:41,190 --> 00:41:45,090 underbar, underbar, right? 649 00:41:45,090 --> 00:41:46,600 The underbar methods-- 650 00:41:46,600 --> 00:41:49,950 and underbar, underbar, init is one of them-- 651 00:41:49,950 --> 00:41:53,630 have a special significance in Python. 652 00:41:53,630 --> 00:41:57,690 So in this case, the underbar, underbar, EQ, underbar, 653 00:41:57,690 --> 00:42:06,600 underbar says that if I have an object niche, and I have a 654 00:42:06,600 --> 00:42:10,790 double equal, and I have another object, Serena, it's 655 00:42:10,790 --> 00:42:12,840 going to look in the Mitch object. 656 00:42:12,840 --> 00:42:18,310 And it's going to say, does it have an EQ method? 657 00:42:18,310 --> 00:42:20,960 Does it have this method name? 658 00:42:20,960 --> 00:42:22,540 In this case, it does. 659 00:42:22,540 --> 00:42:27,490 So it says, OK, this object is capable of comparing itself to 660 00:42:27,490 --> 00:42:29,840 another object for equality. 661 00:42:29,840 --> 00:42:32,430 And so it calls this method. 662 00:42:32,430 --> 00:42:37,780 And self, in this case, is the Mitch object, is this guy. 663 00:42:37,780 --> 00:42:40,080 And the other is the Serena object. 664 00:42:40,080 --> 00:42:41,570 Sorry? 665 00:42:41,570 --> 00:42:46,726 AUDIENCE: So when it looks for the EQ, does it look for EQ, 666 00:42:46,726 --> 00:42:49,400 or does it look for something that has a double equal sign, 667 00:42:49,400 --> 00:42:52,630 and then go off from there? 668 00:42:52,630 --> 00:42:56,810 Is the underbar, underbar, EQ, underbar, underbar -- 669 00:42:56,810 --> 00:42:58,800 is it defined for all? 670 00:42:58,800 --> 00:42:59,935 PROFESSOR: It's defined for all persons. 671 00:42:59,935 --> 00:43:00,760 AUDIENCE: All persons. 672 00:43:00,760 --> 00:43:02,010 PROFESSOR: Yeah. 673 00:43:04,350 --> 00:43:05,260 OK, I see what you're saying. 674 00:43:05,260 --> 00:43:06,950 Is it defined for objects other than 675 00:43:06,950 --> 00:43:07,980 persons, like all objects? 676 00:43:07,980 --> 00:43:08,400 AUDIENCE: Yeah. 677 00:43:08,400 --> 00:43:11,025 PROFESSOR: Well, we can check that out. 678 00:43:13,840 --> 00:43:18,230 You notice that person inherits from object. 679 00:43:18,230 --> 00:43:21,110 This is where all classes that you define 680 00:43:21,110 --> 00:43:22,480 should inherit from. 681 00:43:22,480 --> 00:43:25,950 And so object, like any other type-- remember I showed the 682 00:43:25,950 --> 00:43:27,210 dir command before? 683 00:43:27,210 --> 00:43:31,060 If you do this, you can see everything that's 684 00:43:31,060 --> 00:43:32,400 inherent to an object. 685 00:43:32,400 --> 00:43:36,100 So in this case, it doesn't have the 686 00:43:36,100 --> 00:43:37,980 underbar, underbar, EQ. 687 00:43:37,980 --> 00:43:45,640 So it might be something special that Python does. 688 00:43:45,640 --> 00:43:49,090 So this is where I'd actually have to look it up to answer 689 00:43:49,090 --> 00:43:50,330 your question. 690 00:43:50,330 --> 00:43:53,580 So I'm going to punt on that. 691 00:43:53,580 --> 00:43:56,534 AUDIENCE: So it knows somehow to look for EQ specifically? 692 00:43:56,534 --> 00:43:58,370 PROFESSOR: Yeah. 693 00:43:58,370 --> 00:44:03,280 When it sees the double equals sign, it knows to look for EQ. 694 00:44:03,280 --> 00:44:05,620 The double underbars signify a magical 695 00:44:05,620 --> 00:44:09,862 operator or magical method. 696 00:44:09,862 --> 00:44:13,925 AUDIENCE: So when you're calling EQ, you're not 697 00:44:13,925 --> 00:44:18,010 formally giving it two formal parameters in the parentheses. 698 00:44:18,010 --> 00:44:19,810 So it's presumably taking the first name before the equals 699 00:44:19,810 --> 00:44:21,010 and the second name before the equals-- 700 00:44:21,010 --> 00:44:22,260 PROFESSOR: We'll get into that. 701 00:44:25,160 --> 00:44:29,370 So the question is, are we actually explicitly passing 702 00:44:29,370 --> 00:44:31,300 two formal parameters to it? 703 00:44:31,300 --> 00:44:35,790 And the answer is yes and no. 704 00:44:35,790 --> 00:44:40,620 This is a bit of syntactic sugar for Python, which means 705 00:44:40,620 --> 00:44:44,010 that it's a nicer way of writing things. 706 00:44:44,010 --> 00:44:45,660 But we could do something like this. 707 00:44:57,960 --> 00:45:02,540 Which is totally awkward, but in actuality, this is what 708 00:45:02,540 --> 00:45:04,800 Python does in the background. 709 00:45:04,800 --> 00:45:08,230 It does this sort of mangling. 710 00:45:08,230 --> 00:45:10,400 And I was actually going to show that with something a 711 00:45:10,400 --> 00:45:13,280 little bit easier to comprehend. 712 00:45:13,280 --> 00:45:17,430 So I have a method called get_age, an accessor, right? 713 00:45:17,430 --> 00:45:22,070 And usually, you call a method by having a reference to the 714 00:45:22,070 --> 00:45:26,400 object, dot, and then whatever method name-- 715 00:45:26,400 --> 00:45:28,670 in this case, get_age. 716 00:45:28,670 --> 00:45:32,040 You can also write it like this, which is, if you think 717 00:45:32,040 --> 00:45:34,070 about it, exactly what happened with the double equal 718 00:45:34,070 --> 00:45:36,160 operator, right? 719 00:45:36,160 --> 00:45:39,200 Python took your nice, intuitive syntax-- 720 00:45:39,200 --> 00:45:42,260 Mitch double equal Sarina-- 721 00:45:42,260 --> 00:45:45,380 and totally mangled it and made it something that was 722 00:45:45,380 --> 00:45:47,100 completely ugly. 723 00:45:47,100 --> 00:45:50,400 And this is how Python would actually see it. 724 00:45:50,400 --> 00:45:54,270 So that's why, when you write these methods, 725 00:45:54,270 --> 00:45:55,600 you have a self parameter. 726 00:45:55,600 --> 00:46:00,610 This self parameter is like this guy. 727 00:46:00,610 --> 00:46:02,940 Python says, ooh, I have an object reference. 728 00:46:02,940 --> 00:46:05,160 And they're calling a method, get_age? 729 00:46:05,160 --> 00:46:06,910 Do I have a get_age method? 730 00:46:06,910 --> 00:46:07,700 Yes, I do. 731 00:46:07,700 --> 00:46:08,870 Here it is. 732 00:46:08,870 --> 00:46:12,650 OK, now I'm going to take this and make it look ugly. 733 00:46:12,650 --> 00:46:14,250 It's a person object. 734 00:46:14,250 --> 00:46:16,960 So I'm going to call person.get_age, and I'm going 735 00:46:16,960 --> 00:46:19,860 to pass it Mitch, the reference to the object. 736 00:46:19,860 --> 00:46:21,610 And that becomes a self parameter. 737 00:46:21,610 --> 00:46:23,470 So that's where the self parameter comes from. 738 00:46:26,110 --> 00:46:28,810 There's a little bit of mangling that goes on. 739 00:46:28,810 --> 00:46:30,920 And it's partially hidden from you. 740 00:46:30,920 --> 00:46:32,770 In other languages, it's completely hidden from you. 741 00:46:32,770 --> 00:46:37,286 But in Python, you see some of the ugliness. 742 00:46:37,286 --> 00:46:39,689 AUDIENCE: So in this case, how did it know I was talking 743 00:46:39,689 --> 00:46:44,696 about Mitch self and not-- 744 00:46:44,696 --> 00:46:45,460 PROFESSOR: Serena? 745 00:46:45,460 --> 00:46:46,010 AUDIENCE: Yeah. 746 00:46:46,010 --> 00:46:49,590 PROFESSOR: So the question was how did Python know that the 747 00:46:49,590 --> 00:46:51,970 parameter was Mitch. 748 00:46:51,970 --> 00:46:54,200 Because-- 749 00:46:54,200 --> 00:46:56,670 let me comment this out so we explicitly 750 00:46:56,670 --> 00:46:57,900 what I'm talking about. 751 00:46:57,900 --> 00:47:05,680 So Mitch is a reference to a person that represents me on a 752 00:47:05,680 --> 00:47:07,840 computer, right? 753 00:47:07,840 --> 00:47:12,690 Python knows that this object is of type person because it 754 00:47:12,690 --> 00:47:15,810 chunked that memory and made it of type person. 755 00:47:15,810 --> 00:47:18,350 So when it sees this reference and it knows it's of type 756 00:47:18,350 --> 00:47:22,780 person and it sees this dot and get_age, what that 757 00:47:22,780 --> 00:47:28,200 automatically tells Python is, hey, this instance of person 758 00:47:28,200 --> 00:47:30,520 is trying to call a method. 759 00:47:30,520 --> 00:47:33,420 Does this class have a method, get_age? 760 00:47:33,420 --> 00:47:36,120 In this case, it does. 761 00:47:36,120 --> 00:47:38,080 So python says, oh, it does. 762 00:47:38,080 --> 00:47:44,690 So I'm going to call this method, person.get_age, and 763 00:47:44,690 --> 00:47:46,602 pass it Mitch as a self parameter. 764 00:47:54,420 --> 00:47:57,245 Does it make sense in some way? 765 00:47:57,245 --> 00:48:02,490 AUDIENCE: So it basically allows you to put in the name 766 00:48:02,490 --> 00:48:03,640 of the person instead of the attribute, instead 767 00:48:03,640 --> 00:48:05,448 of using the type? 768 00:48:05,448 --> 00:48:09,165 PROFESSOR: Yeah, so you could do this. 769 00:48:13,500 --> 00:48:15,300 I don't recommend that you do this. 770 00:48:15,300 --> 00:48:17,170 I'm trying to illustrate where the self 771 00:48:17,170 --> 00:48:18,420 parameter is coming from. 772 00:48:22,140 --> 00:48:23,925 It's much cleaner to write-- 773 00:48:29,490 --> 00:48:32,222 than it is to write this. 774 00:48:32,222 --> 00:48:34,100 Fewer keystrokes, too. 775 00:48:34,100 --> 00:48:35,350 Remember, programmers are lazy. 776 00:48:38,130 --> 00:48:39,450 But it'll do the same exact thing. 777 00:48:43,360 --> 00:48:45,610 So can I move on? 778 00:48:48,390 --> 00:48:50,760 Wow, we've only got three minutes left. 779 00:48:53,350 --> 00:48:56,300 I don't think I'm going to be able to get through this. 780 00:48:56,300 --> 00:49:00,560 So my intent with this code was to show inheritance with 781 00:49:00,560 --> 00:49:04,380 shapes, because that's the classic. 782 00:49:04,380 --> 00:49:07,310 I'm going to define a base class called shape. 783 00:49:07,310 --> 00:49:11,630 And I'm going to give it some methods, area, perimeter, EQ, 784 00:49:11,630 --> 00:49:12,730 and less than. 785 00:49:12,730 --> 00:49:15,830 For my purposes, shapes are equal if they have the same 786 00:49:15,830 --> 00:49:21,250 area, and they're less than if the area's less than. 787 00:49:21,250 --> 00:49:23,820 So when we're doing logical comparisons, 788 00:49:23,820 --> 00:49:26,530 we're comparing areas. 789 00:49:26,530 --> 00:49:28,840 So now, I'm going to define a class, rectangle. 790 00:49:28,840 --> 00:49:32,210 It inherits from shape. 791 00:49:32,210 --> 00:49:36,690 It's got two sides, or the lengths of two sides. 792 00:49:36,690 --> 00:49:40,440 So the area's pretty easy, just a multiplication. 793 00:49:40,440 --> 00:49:42,985 And the parameter is just the sum of the four sides. 794 00:49:45,650 --> 00:49:48,355 And then, I'm going to define another shape, circle. 795 00:49:50,870 --> 00:49:52,880 It's got a radius. 796 00:49:52,880 --> 00:49:55,810 And it does the area and the perimeter in the way that you 797 00:49:55,810 --> 00:49:57,520 expect a circle to do the area and the perimeter. 798 00:50:00,070 --> 00:50:03,160 And then, I've got square, which is a sub-class of 799 00:50:03,160 --> 00:50:09,210 rectangle, because a square is just a special case, right? 800 00:50:09,210 --> 00:50:14,080 And all I'm going to do is when I initialize my square, 801 00:50:14,080 --> 00:50:19,310 I'm just going to call the rectangle's init method, and 802 00:50:19,310 --> 00:50:20,785 give it the same size twice. 803 00:50:25,540 --> 00:50:31,480 So what this gives us is some inheritance, some nice 804 00:50:31,480 --> 00:50:32,120 properties. 805 00:50:32,120 --> 00:50:35,480 So first off, when Python gets to this line, 806 00:50:35,480 --> 00:50:36,730 what's going to happen? 807 00:50:40,350 --> 00:50:42,300 s is of type shape, right? 808 00:50:42,300 --> 00:50:45,905 So what is the method for shape? 809 00:50:49,246 --> 00:50:50,680 AUDIENCE: [INAUDIBLE]. 810 00:50:50,680 --> 00:50:51,010 PROFESSOR: What's that? 811 00:50:51,010 --> 00:50:55,320 AUDIENCE: What is the method for shape? 812 00:50:55,320 --> 00:50:58,180 PROFESSOR: What does the area method for shape do? 813 00:50:58,180 --> 00:50:59,550 Because that's what I'm calling here. 814 00:50:59,550 --> 00:51:01,526 AUDIENCE: It's going to throw an error. 815 00:51:01,526 --> 00:51:04,460 PROFESSOR: So yeah, voila. 816 00:51:04,460 --> 00:51:07,780 And the reason is that we haven't implemented it here. 817 00:51:07,780 --> 00:51:10,100 This method is a placeholder. 818 00:51:10,100 --> 00:51:12,450 It's saying that if I have a shape, it should 819 00:51:12,450 --> 00:51:15,320 have an area method. 820 00:51:15,320 --> 00:51:18,950 And this is something that you should see on your problem set 821 00:51:18,950 --> 00:51:23,110 when you're doing PS5 with trigger. 822 00:51:23,110 --> 00:51:26,540 AUDIENCE: So it doesn't do anything on its own. 823 00:51:26,540 --> 00:51:29,970 You can ignore it and just put [INAUDIBLE] 824 00:51:29,970 --> 00:51:31,930 for a circle. 825 00:51:31,930 --> 00:51:32,740 PROFESSOR: Yeah. 826 00:51:32,740 --> 00:51:34,240 AUDIENCE: It just reminds you? 827 00:51:34,240 --> 00:51:35,910 PROFESSOR: It reminds you, yeah. 828 00:51:35,910 --> 00:51:36,750 AUDIENCE: It's like commenting. 829 00:51:36,750 --> 00:51:37,600 PROFESSOR: What's that? 830 00:51:37,600 --> 00:51:38,890 AUDIENCE: So it's kind of like commenting? 831 00:51:38,890 --> 00:51:41,120 PROFESSOR: It's like commenting, except that you 832 00:51:41,120 --> 00:51:43,420 get a little bit nicer error checking. 833 00:51:43,420 --> 00:51:50,200 So it is a way of explicitly saying that if I have 834 00:51:50,200 --> 00:51:53,270 something that is sub-classed from shape, then I can be 835 00:51:53,270 --> 00:51:54,950 guaranteed that there is an area method. 836 00:51:59,160 --> 00:52:00,740 But if I sub-class off it-- 837 00:52:00,740 --> 00:52:03,450 so rectangle, square, and circle-- they all have 838 00:52:03,450 --> 00:52:05,880 concrete implementation for areas. 839 00:52:05,880 --> 00:52:10,320 So this is all going to run fine. 840 00:52:10,320 --> 00:52:12,690 And then, I have my equality operator and 841 00:52:12,690 --> 00:52:13,810 my less than operator. 842 00:52:13,810 --> 00:52:15,060 Those will run fine. 843 00:52:17,390 --> 00:52:20,665 So let me-- 844 00:52:28,910 --> 00:52:30,870 all right. 845 00:52:30,870 --> 00:52:36,880 The reason why this is useful, and the big idea, is if I have 846 00:52:36,880 --> 00:52:39,990 a list of shapes-- 847 00:52:39,990 --> 00:52:41,645 circle, square, and a rectangle-- 848 00:52:44,820 --> 00:52:47,620 then I can treat them all exactly the same because they 849 00:52:47,620 --> 00:52:50,640 all have an area method, which is defined on a shape. 850 00:52:50,640 --> 00:52:53,380 They all sub-class from shape. 851 00:52:53,380 --> 00:52:59,960 So it'll print all those areas. 852 00:52:59,960 --> 00:53:04,330 And then, if I wanted to, I could even-- 853 00:53:04,330 --> 00:53:07,335 because I have a list, I can call the sort method. 854 00:53:07,335 --> 00:53:11,980 And because I've defined the less than operator, it'll sort 855 00:53:11,980 --> 00:53:14,820 the shapes in descending order by area. 856 00:53:14,820 --> 00:53:23,750 And that's what this last bit of code does unless I comment 857 00:53:23,750 --> 00:53:26,110 out my assignment. 858 00:53:26,110 --> 00:53:27,840 There we go. 859 00:53:27,840 --> 00:53:30,660 So I know I rushed through the shape 860 00:53:30,660 --> 00:53:32,540 implementation, and I'm sorry. 861 00:53:32,540 --> 00:53:33,790 But I'm actually out of time.