1 00:00:00,040 --> 00:00:02,460 The following content is provided under a Creative 2 00:00:02,460 --> 00:00:03,870 Commons license. 3 00:00:03,870 --> 00:00:06,910 Your support will help MIT OpenCourseWare continue to 4 00:00:06,910 --> 00:00:10,560 offer high quality educational resources for free. 5 00:00:10,560 --> 00:00:13,460 To make a donation or view additional materials from 6 00:00:13,460 --> 00:00:19,290 hundreds of MIT courses, visit MIT OpenCourseWare at 7 00:00:19,290 --> 00:00:20,540 ocw.mit.edu. 8 00:00:23,850 --> 00:00:25,660 PROFESSOR: Good morning, everybody. 9 00:00:25,660 --> 00:00:27,910 Let's go back to where we were. 10 00:00:27,910 --> 00:00:32,619 We were talking about abstract data types and the notion of 11 00:00:32,619 --> 00:00:33,955 object oriented programming. 12 00:00:37,710 --> 00:00:42,640 And in particular, the role of classes in all of that. 13 00:00:42,640 --> 00:00:45,940 A lot of people think this notion of object oriented 14 00:00:45,940 --> 00:00:48,030 programming is a new notion. 15 00:00:48,030 --> 00:00:49,440 In fact, it's not. 16 00:00:49,440 --> 00:00:52,320 It's been around for probably at least 35 17 00:00:52,320 --> 00:00:55,470 years, maybe even longer. 18 00:00:55,470 --> 00:00:59,230 But it's only been widely practiced for maybe 15 years. 19 00:00:59,230 --> 00:01:02,270 Even that to most of you will seem like a long time. 20 00:01:04,800 --> 00:01:08,250 It started in the mid 1970s when people began to write 21 00:01:08,250 --> 00:01:11,290 articles explaining this advantage of the approach to 22 00:01:11,290 --> 00:01:12,680 programming. 23 00:01:12,680 --> 00:01:17,000 And at about the same time, the language Smalltalk was 24 00:01:17,000 --> 00:01:22,710 developed at Xerox Park and CLU developed at MIT. 25 00:01:22,710 --> 00:01:25,320 And they were the first languages that, in an elegant 26 00:01:25,320 --> 00:01:29,020 way, provided linguistic support for this style of 27 00:01:29,020 --> 00:01:30,630 programming. 28 00:01:30,630 --> 00:01:34,090 But it didn't really take off in the public until the 29 00:01:34,090 --> 00:01:37,160 introduction of Java, considerably later. 30 00:01:37,160 --> 00:01:40,870 And Java was the first popular language to support object 31 00:01:40,870 --> 00:01:42,630 oriented programming. 32 00:01:42,630 --> 00:01:46,840 After that there was C++, which supports it in not a 33 00:01:46,840 --> 00:01:49,190 very elegant but a usable way. 34 00:01:49,190 --> 00:01:52,940 And today probably Python is the fastest growing language 35 00:01:52,940 --> 00:01:55,570 supporting object oriented programming. 36 00:01:55,570 --> 00:01:57,250 It's used widely, and that's one of the 37 00:01:57,250 --> 00:01:58,920 reasons we teach it here. 38 00:02:01,640 --> 00:02:06,950 As I said, at the bottom of it all, the most fundamental 39 00:02:06,950 --> 00:02:09,289 notion is that of an abstract data type. 40 00:02:13,920 --> 00:02:17,160 And the idea is that we can extend our programming 41 00:02:17,160 --> 00:02:20,440 language by adding user defined types. 42 00:02:20,440 --> 00:02:24,150 And we'll shortly see why that's such a useful thing. 43 00:02:24,150 --> 00:02:27,970 And that these types can be used just as easily as any of 44 00:02:27,970 --> 00:02:30,500 the built in types. 45 00:02:30,500 --> 00:02:34,490 Why do we call them abstract data types rather than just 46 00:02:34,490 --> 00:02:35,740 data types? 47 00:02:38,190 --> 00:02:42,250 We do that because we are essentially going to define 48 00:02:42,250 --> 00:02:43,850 for each type an interface. 49 00:02:49,660 --> 00:02:58,940 And essentially, what the interface does is it explains 50 00:02:58,940 --> 00:03:04,860 what the methods do. 51 00:03:04,860 --> 00:03:07,990 What do I mean by what they do? 52 00:03:07,990 --> 00:03:15,970 What they do at the level of the user, not how they do it. 53 00:03:22,290 --> 00:03:25,480 That, of course, is the way the built in types work. 54 00:03:25,480 --> 00:03:30,020 It wasn't until Tuesday that you understood how Python made 55 00:03:30,020 --> 00:03:32,530 dicts do what they do. 56 00:03:32,530 --> 00:03:36,170 Before then, I just explained, that you could put in a key 57 00:03:36,170 --> 00:03:39,340 and a value, and you could look it up and do an 58 00:03:39,340 --> 00:03:41,070 associative retrieval. 59 00:03:41,070 --> 00:03:45,660 It was maybe not magic, but it was wonderful that you could 60 00:03:45,660 --> 00:03:49,450 do this and not have to bother your heads with how it was 61 00:03:49,450 --> 00:03:51,360 made to work. 62 00:03:51,360 --> 00:03:54,480 And that was because we provided, or the designers of 63 00:03:54,480 --> 00:03:59,510 Python provided, an interface that lets you use it. 64 00:03:59,510 --> 00:04:03,700 We'll do the same thing with the abstract data types. 65 00:04:03,700 --> 00:04:09,180 The key idea here is one we've talked about before and that's 66 00:04:09,180 --> 00:04:10,430 a specification. 67 00:04:13,680 --> 00:04:18,720 It is the specification of a type, or of a function, or of 68 00:04:18,720 --> 00:04:23,780 a method, that tells us what that thing does. 69 00:04:23,780 --> 00:04:27,760 And we'll now until the end of the term try and maintain a 70 00:04:27,760 --> 00:04:31,430 very clear distinction between specifications and 71 00:04:31,430 --> 00:04:32,680 implementations. 72 00:04:38,530 --> 00:04:42,000 Let's look at an example. 73 00:04:42,000 --> 00:04:45,210 So the example should be familiar to you. 74 00:04:45,210 --> 00:04:48,410 You will remember that on Tuesday at the start of the 75 00:04:48,410 --> 00:04:53,410 lecture, we looked at how we could use hashing to implement 76 00:04:53,410 --> 00:04:55,410 a set of integers. 77 00:04:55,410 --> 00:04:58,770 And I explained to you that I wasn't very happy with the 78 00:04:58,770 --> 00:05:00,820 implementation because of the way it 79 00:05:00,820 --> 00:05:03,840 used this global variable. 80 00:05:03,840 --> 00:05:08,450 Now we're going to see a much more elegant approach. 81 00:05:08,450 --> 00:05:13,710 So I'm going to define a new abstract type called intSet. 82 00:05:13,710 --> 00:05:19,070 I do that by writing the word, class, followed by 83 00:05:19,070 --> 00:05:21,130 the name of the class. 84 00:05:21,130 --> 00:05:27,010 And then there's this funny thing saying that it is a 85 00:05:27,010 --> 00:05:30,140 subclass of objects. 86 00:05:30,140 --> 00:05:31,420 Ignore that for now. 87 00:05:31,420 --> 00:05:34,150 And I'm going to come back to it later. 88 00:05:34,150 --> 00:05:37,480 But fundamentally what it's saying is that every instance 89 00:05:37,480 --> 00:05:40,560 of intSet is an object. 90 00:05:40,560 --> 00:05:45,080 That's not very interesting because everything in Python 91 00:05:45,080 --> 00:05:46,230 is an object. 92 00:05:46,230 --> 00:05:49,160 So from an information theoretic point of view, 93 00:05:49,160 --> 00:05:51,600 there's no information here. 94 00:05:51,600 --> 00:05:54,700 Later we'll see that we can use this mechanism in a more 95 00:05:54,700 --> 00:05:55,950 interesting way. 96 00:05:58,810 --> 00:06:02,160 Now let's look at the methods. 97 00:06:02,160 --> 00:06:06,450 So first I tell you a comment, it's a set of integers. 98 00:06:06,450 --> 00:06:09,350 Then I've got this funny method called underbar 99 00:06:09,350 --> 00:06:12,690 underbar init. 100 00:06:12,690 --> 00:06:15,950 Whenever you see something with an underbar underbar in 101 00:06:15,950 --> 00:06:21,180 its name, it has a special status in Python that lets us 102 00:06:21,180 --> 00:06:23,595 do elegant things with the syntax. 103 00:06:26,960 --> 00:06:32,820 What will happen every time I create a new object of type 104 00:06:32,820 --> 00:06:41,135 intSet, the underbar underbar init method, or function, of 105 00:06:41,135 --> 00:06:44,330 the class will be executed on that object. 106 00:06:49,280 --> 00:06:57,810 What it will do, in this case, is introduce two attributes of 107 00:06:57,810 --> 00:07:00,090 the object. 108 00:07:00,090 --> 00:07:05,380 The attributes are numBuckets which is now replacing the 109 00:07:05,380 --> 00:07:07,440 global variable we looked at last time. 110 00:07:07,440 --> 00:07:11,170 And I've arbitrarily chosen 47. 111 00:07:11,170 --> 00:07:12,420 And Vals. 112 00:07:14,720 --> 00:07:20,780 This will be the hash table itself containing the values. 113 00:07:20,780 --> 00:07:26,500 And then, exactly as we did on Tuesday, I'm going to 114 00:07:26,500 --> 00:07:32,880 initialize the values so that each element of this list is 115 00:07:32,880 --> 00:07:34,400 now an empty list. 116 00:07:39,710 --> 00:07:42,890 Now what's going on with this funny notion of self. 117 00:07:42,890 --> 00:07:44,430 Let's look at an example here. 118 00:07:48,520 --> 00:07:53,840 I'm going to say s equals intSet open close. 119 00:07:58,840 --> 00:08:03,160 This will create a new intSet object, execute the underbar 120 00:08:03,160 --> 00:08:04,820 underbar init. 121 00:08:04,820 --> 00:08:08,835 So if, for example, I print self.numBuckets-- 122 00:08:13,580 --> 00:08:18,470 whoops, can't do that because self is not defined in this 123 00:08:18,470 --> 00:08:19,900 environment. 124 00:08:19,900 --> 00:08:23,830 Self was a local variable to underbar underbar init. 125 00:08:23,830 --> 00:08:26,140 In fact, the formal parameter. 126 00:08:26,140 --> 00:08:34,035 But I can write s.numBuckets, and I'll see it's 47. 127 00:08:44,110 --> 00:08:51,470 NumBuckets and Val are now attributes of s. 128 00:08:54,140 --> 00:08:58,340 Attributes of the instance s of the class intSet. 129 00:09:07,550 --> 00:09:08,800 And I [[UNINTELLIGIBLE] 130 00:09:12,860 --> 00:09:14,260 what we would expect. 131 00:09:14,260 --> 00:09:15,790 Yes? 132 00:09:15,790 --> 00:09:21,776 AUDIENCE: You didn't put any object in between the 133 00:09:21,776 --> 00:09:22,730 parentheses. 134 00:09:22,730 --> 00:09:23,530 PROFESSOR: Yes. 135 00:09:23,530 --> 00:09:25,050 So that-- 136 00:09:25,050 --> 00:09:29,660 the question is well, it looks like underbar underbar intSet 137 00:09:29,660 --> 00:09:33,820 or underbar underbar init has a formal parameter. 138 00:09:33,820 --> 00:09:34,660 And I've given it no 139 00:09:34,660 --> 00:09:36,220 corresponding actual parameter. 140 00:09:36,220 --> 00:09:37,055 AUDIENCE: [INAUDIBLE] 141 00:09:37,055 --> 00:09:38,020 PROFESSOR: Yes. 142 00:09:38,020 --> 00:09:38,860 Let me finish. 143 00:09:38,860 --> 00:09:40,840 So that's what it looks like. 144 00:09:40,840 --> 00:09:46,670 And that's the magic of this syntax. 145 00:09:46,670 --> 00:09:53,290 It automatically passes an implicit object, 146 00:09:53,290 --> 00:09:54,300 or it creates one. 147 00:09:54,300 --> 00:09:57,580 It's a very special role for underbar underbar init. 148 00:10:01,620 --> 00:10:05,670 Self is used to refer to the object being created. 149 00:10:09,560 --> 00:10:13,980 I'm going to come back in a minute to discuss more fully 150 00:10:13,980 --> 00:10:17,960 the concept of self and how it's used here. 151 00:10:17,960 --> 00:10:22,620 So just give me a minute to get there. 152 00:10:22,620 --> 00:10:26,860 The next thing we see is hashE. 153 00:10:26,860 --> 00:10:28,875 This is something we looked at again on Tuesday. 154 00:10:34,270 --> 00:10:38,830 It's a private function in this case that I don't intend 155 00:10:38,830 --> 00:10:41,910 to be used outside the class. 156 00:10:41,910 --> 00:10:44,570 So if we think of the specifications here, the 157 00:10:44,570 --> 00:10:50,530 interface of the class, it does not include hashE. 158 00:10:50,530 --> 00:10:52,800 That's what private means here. 159 00:10:52,800 --> 00:10:53,990 This is a convention. 160 00:10:53,990 --> 00:10:56,370 It's not enforced by the language. 161 00:10:56,370 --> 00:10:59,540 And unfortunately, as we'll see, a lot of useful things 162 00:10:59,540 --> 00:11:01,890 are not enforced by the language. 163 00:11:01,890 --> 00:11:04,960 But nevertheless, good programmers follow the 164 00:11:04,960 --> 00:11:06,460 conventions. 165 00:11:06,460 --> 00:11:10,050 And we expect you guys to do so as well because, of course, 166 00:11:10,050 --> 00:11:12,550 you're good programmers. 167 00:11:12,550 --> 00:11:14,765 So this doesn't do anything very exciting. 168 00:11:14,765 --> 00:11:18,130 It's just what we saw. 169 00:11:18,130 --> 00:11:19,650 Insert is more interesting. 170 00:11:19,650 --> 00:11:22,460 Let's look at what that does. 171 00:11:22,460 --> 00:11:28,930 It apparently takes two arguments, the formals named 172 00:11:28,930 --> 00:11:36,055 self and E and inserts E into self.vals. 173 00:11:40,340 --> 00:11:49,670 However, if we go look at the code that uses it in say 174 00:11:49,670 --> 00:11:57,120 testone what you'll note is I'm saying for i in range 40-- 175 00:11:57,120 --> 00:12:00,810 this is just like the testone we looked at Tuesday. 176 00:12:00,810 --> 00:12:04,520 I'm going to say s.insert of i. 177 00:12:04,520 --> 00:12:08,060 It looks like I'm calling insert with only one argument, 178 00:12:08,060 --> 00:12:13,920 but as we discussed last time, this s before the dot is 179 00:12:13,920 --> 00:12:19,040 actually the first argument to the method insert. 180 00:12:19,040 --> 00:12:21,220 And so it's getting two arguments really. 181 00:12:25,160 --> 00:12:31,660 And by convention, that implicit first argument is 182 00:12:31,660 --> 00:12:35,125 always called self in Python. 183 00:12:40,840 --> 00:12:42,040 It's not enforced. 184 00:12:42,040 --> 00:12:45,440 You could call it George if you preferred, or Alice, or 185 00:12:45,440 --> 00:12:48,170 whatever you like. 186 00:12:48,170 --> 00:12:51,160 But if you do, you will confuse the heck out of 187 00:12:51,160 --> 00:12:54,090 anybody who ever reads your code, including any 188 00:12:54,090 --> 00:12:56,360 TA you ask for help. 189 00:12:56,360 --> 00:12:59,810 So please do use self. 190 00:12:59,810 --> 00:13:01,900 It's just a name. 191 00:13:01,900 --> 00:13:05,630 It has nothing to do with what a philosopher, or a 192 00:13:05,630 --> 00:13:09,800 psychologist, or an ethicist might think as the concept of 193 00:13:09,800 --> 00:13:12,960 self, this wonderful elevated concept. 194 00:13:12,960 --> 00:13:13,820 It's none of those. 195 00:13:13,820 --> 00:13:15,450 It's just a name. 196 00:13:15,450 --> 00:13:17,540 But stick to using that name. 197 00:13:21,660 --> 00:13:28,580 So if we go back, I can insert a bunch of things. 198 00:13:32,040 --> 00:13:34,340 I'm going to then print s. 199 00:13:34,340 --> 00:13:35,590 That's kind of interesting. 200 00:13:39,150 --> 00:13:45,090 UnderBar underbar STR, underbar underbar is one of 201 00:13:45,090 --> 00:13:49,180 those special names as well. 202 00:13:49,180 --> 00:13:52,310 The code is pretty simple. 203 00:13:52,310 --> 00:13:54,350 All it is is returning a string 204 00:13:54,350 --> 00:13:55,820 representation of the set. 205 00:13:59,390 --> 00:14:00,880 And it could be anything you want. 206 00:14:00,880 --> 00:14:05,260 I chose sort of a conventional way of denoting sets. 207 00:14:05,260 --> 00:14:09,420 What's interesting is that it gets 208 00:14:09,420 --> 00:14:13,230 automatically called by print. 209 00:14:13,230 --> 00:14:19,110 So when I write the command, print s, in test one, the 210 00:14:19,110 --> 00:14:22,970 Python interpreter is smart enough to know oh, I better 211 00:14:22,970 --> 00:14:26,765 take s, convert it to a string, and then print it. 212 00:14:30,060 --> 00:14:32,100 How does it know to convert it to a string? 213 00:14:32,100 --> 00:14:36,850 It automatically invokes the underbar underbar STR method. 214 00:14:44,510 --> 00:14:47,560 And then the other operation is member, which again is 215 00:14:47,560 --> 00:14:49,145 exactly what we looked at before. 216 00:14:51,680 --> 00:14:58,530 But you'll notice in this code that uses intSets, I make no 217 00:14:58,530 --> 00:15:04,010 reference to the data attributes of the class 218 00:15:04,010 --> 00:15:07,540 directly, or I shouldn't. 219 00:15:07,540 --> 00:15:12,040 You'll notice that I wrote evil next to s.vals. 220 00:15:12,040 --> 00:15:15,130 Python will let me do it, but I shouldn't. 221 00:15:15,130 --> 00:15:16,590 Why shouldn't I do it? 222 00:15:19,350 --> 00:15:21,010 Why am I saying this is evil? 223 00:15:27,601 --> 00:15:34,360 Well, would you be happy if you got a message saying IDLE 224 00:15:34,360 --> 00:15:35,245 was changed. 225 00:15:35,245 --> 00:15:40,453 Please download a new version and the new version happened 226 00:15:40,453 --> 00:15:41,700 to have a different 227 00:15:41,700 --> 00:15:44,580 implementation of lists or dicts. 228 00:15:44,580 --> 00:15:49,640 And it caused all of your programs to stop working. 229 00:15:49,640 --> 00:15:51,780 You would be pretty unhappy. 230 00:15:51,780 --> 00:15:54,500 Now why won't that happen? 231 00:15:54,500 --> 00:15:59,700 Because your programs don't depend, in any way, on the way 232 00:15:59,700 --> 00:16:05,560 in which people chose to implement those built in types 233 00:16:05,560 --> 00:16:09,510 because you programmed to the specification of the types, 234 00:16:09,510 --> 00:16:10,760 not to the implementation. 235 00:16:12,900 --> 00:16:17,640 The specification of intSet did not mention Vals or 236 00:16:17,640 --> 00:16:18,890 numBuckets. 237 00:16:20,850 --> 00:16:25,500 Therefore, as the implementer of that class, I'm entitled to 238 00:16:25,500 --> 00:16:27,970 go back and change it. 239 00:16:27,970 --> 00:16:30,780 So I'm not going to use a hash table at all. 240 00:16:30,780 --> 00:16:31,900 I'm going to do something else. 241 00:16:31,900 --> 00:16:35,280 I'm going to use a red, black tree, or some other fancy 242 00:16:35,280 --> 00:16:36,880 implementation. 243 00:16:36,880 --> 00:16:38,810 I'm allowed to do that. 244 00:16:38,810 --> 00:16:43,640 And if I make that change, and Vals disappears and numBuckets 245 00:16:43,640 --> 00:16:47,960 disappears, your program should continue to work so 246 00:16:47,960 --> 00:16:51,700 long as I still meet the specification. 247 00:16:51,700 --> 00:16:55,990 The minute you go in and directly access the variables 248 00:16:55,990 --> 00:17:00,700 of the class, those attributes, you have used 249 00:17:00,700 --> 00:17:04,000 things that do not appear in this specification. 250 00:17:04,000 --> 00:17:06,270 And if I change the implementation, your program 251 00:17:06,270 --> 00:17:07,520 might break. 252 00:17:09,690 --> 00:17:11,369 So you shouldn't do that. 253 00:17:11,369 --> 00:17:13,660 Does that make sense to everybody? 254 00:17:13,660 --> 00:17:15,900 It's a very important concept. 255 00:17:15,900 --> 00:17:18,750 The concept is known as data hiding. 256 00:17:38,700 --> 00:17:44,930 It is really the most important development that 257 00:17:44,930 --> 00:17:48,200 makes abstract data types useful. 258 00:17:48,200 --> 00:17:52,960 It gives them the same status as the built in types. 259 00:17:52,960 --> 00:17:57,190 The minute you choose to ignore this, you do 260 00:17:57,190 --> 00:17:59,640 so at your own peril. 261 00:17:59,640 --> 00:18:03,880 Some programming languages, like Java, provide a mechanism 262 00:18:03,880 --> 00:18:07,250 to enforce data hiding. 263 00:18:07,250 --> 00:18:11,490 The designers of Python, for reasons I do not understand, 264 00:18:11,490 --> 00:18:13,170 chose not to. 265 00:18:13,170 --> 00:18:15,210 I think it is a flaw in the language. 266 00:18:21,260 --> 00:18:25,980 The things we're hiding are the instance variable. 267 00:18:46,190 --> 00:18:50,770 Those are the variables associated with each instance 268 00:18:50,770 --> 00:18:52,020 of the class. 269 00:19:01,320 --> 00:19:06,275 We should also hide class variables. 270 00:19:09,780 --> 00:19:13,445 We haven't seen those yet, and we'll see them later. 271 00:19:16,670 --> 00:19:22,250 The instance variables, we get a new copy of each time we 272 00:19:22,250 --> 00:19:24,400 created a new instance of the class, a new 273 00:19:24,400 --> 00:19:26,400 intSet in this case. 274 00:19:26,400 --> 00:19:29,520 The class variables are associated 275 00:19:29,520 --> 00:19:31,130 with the class itself. 276 00:19:31,130 --> 00:19:34,530 And you get only one copy of them. 277 00:19:34,530 --> 00:19:37,180 Later on, we'll see an example where class 278 00:19:37,180 --> 00:19:40,500 variables are useful. 279 00:19:40,500 --> 00:19:40,930 All right. 280 00:19:40,930 --> 00:19:43,010 So let's run this just to make sure it works. 281 00:19:50,330 --> 00:19:51,850 It does what we would expect. 282 00:19:51,850 --> 00:19:52,820 True/False. 283 00:19:52,820 --> 00:19:56,230 And then you'll see this nice string 284 00:19:56,230 --> 00:19:58,340 representation of the set. 285 00:19:58,340 --> 00:20:00,970 And then just to show you what happens when you do the evil 286 00:20:00,970 --> 00:20:04,400 thing, I printed as we did last time the actual 287 00:20:04,400 --> 00:20:07,600 list that came out. 288 00:20:13,660 --> 00:20:16,960 Let's now look at a more interesting example. 289 00:20:24,880 --> 00:20:28,770 And the idea I want to convey here is how we use classes and 290 00:20:28,770 --> 00:20:33,340 abstract data types to design programs. 291 00:20:33,340 --> 00:20:37,040 So imagine that you're writing a program to keep track of all 292 00:20:37,040 --> 00:20:41,440 the students, faculty, and maybe staff at MIT. 293 00:20:41,440 --> 00:20:44,040 It's certainly possible to write that program without 294 00:20:44,040 --> 00:20:46,080 using any classes. 295 00:20:46,080 --> 00:20:48,830 For each student, you might give them a family name, a 296 00:20:48,830 --> 00:20:53,290 given name, a home address, years, grades, et cetera. 297 00:20:53,290 --> 00:20:56,260 And you could do this with some complicated combination 298 00:20:56,260 --> 00:20:57,510 of lists and dictionaries. 299 00:20:59,930 --> 00:21:02,750 But it wouldn't be very elegant. 300 00:21:02,750 --> 00:21:06,040 So what I want to do before writing that program-- 301 00:21:06,040 --> 00:21:08,190 and I won't actually write that program. 302 00:21:08,190 --> 00:21:11,330 I'll just write some of the classes we can use-- 303 00:21:11,330 --> 00:21:13,720 I want to pull back and think about what 304 00:21:13,720 --> 00:21:17,360 abstractions would be useful. 305 00:21:17,360 --> 00:21:20,880 So this style of programming in which you organize your 306 00:21:20,880 --> 00:21:26,840 programs around abstract data types says before we write the 307 00:21:26,840 --> 00:21:32,280 code in detail, we think about these types that would make it 308 00:21:32,280 --> 00:21:34,770 easy to write the code. 309 00:21:34,770 --> 00:21:38,810 So for example, if you were a finance student, and you 310 00:21:38,810 --> 00:21:43,310 wanted to write some code dealing with markets, you 311 00:21:43,310 --> 00:21:45,530 might want to have an abstraction of a government 312 00:21:45,530 --> 00:21:48,650 bond, and another abstraction of an equity, and an 313 00:21:48,650 --> 00:21:50,960 extraction of a call option. 314 00:21:50,960 --> 00:21:52,580 Whatever you want it. 315 00:21:52,580 --> 00:21:56,060 But you'd say I want to think at that level of abstraction. 316 00:21:56,060 --> 00:21:59,840 I don't want to think about lists, and dicts, and floats. 317 00:21:59,840 --> 00:22:03,860 I just want to think about options, which have a strike 318 00:22:03,860 --> 00:22:07,830 price, a date, and things like that. 319 00:22:07,830 --> 00:22:11,900 Similarly, as I'm working on this database for MIT, I want 320 00:22:11,900 --> 00:22:17,470 to think about abstractions of students, and 321 00:22:17,470 --> 00:22:18,720 faculty, and staff. 322 00:22:22,540 --> 00:22:29,420 I'm also going to use what's called inheritance to set up a 323 00:22:29,420 --> 00:22:32,920 hierarchy of these. 324 00:22:32,920 --> 00:22:37,240 And the reason I'm going to do that is I want to be able to 325 00:22:37,240 --> 00:22:39,950 share a code. 326 00:22:39,950 --> 00:22:44,330 I know that there will be certain similarities between 327 00:22:44,330 --> 00:22:46,490 students and faculty. 328 00:22:46,490 --> 00:22:49,910 Some differences too. 329 00:22:49,910 --> 00:22:53,990 But I want to begin by saying what's not different? 330 00:22:53,990 --> 00:22:55,170 What's similar? 331 00:22:55,170 --> 00:22:56,580 What's the same? 332 00:22:56,580 --> 00:22:59,970 So that I only have to implement it once and 333 00:22:59,970 --> 00:23:03,460 get to reuse it. 334 00:23:03,460 --> 00:23:08,290 So if I pull back and say is there an abstraction that 335 00:23:08,290 --> 00:23:11,740 covers the shared attributes of students, and faculty, and 336 00:23:11,740 --> 00:23:15,890 staff, I might say it's a person. 337 00:23:15,890 --> 00:23:18,490 They're all people. 338 00:23:18,490 --> 00:23:21,970 And it's arguable whether every faculty member is a 339 00:23:21,970 --> 00:23:26,490 human being, but for now let's pretend. 340 00:23:26,490 --> 00:23:29,760 And so I'm going to start with this abstraction person. 341 00:23:32,650 --> 00:23:35,910 I'm going to import something called DateTime. 342 00:23:35,910 --> 00:23:38,360 I'll show you what we're doing when we get there. 343 00:23:38,360 --> 00:23:41,110 But it's like we've imported math before. 344 00:23:41,110 --> 00:23:46,000 This is a class somebody else wrote that deals with dates 345 00:23:46,000 --> 00:23:49,430 and time in a fairly reasonable way. 346 00:23:53,540 --> 00:23:58,610 So I'm going to import that here into person. 347 00:23:58,610 --> 00:24:01,200 Probably didn't need to import it twice. 348 00:24:01,200 --> 00:24:03,840 Maybe I'll just simplify it by getting rid of this one. 349 00:24:08,220 --> 00:24:11,450 UnderBar underbar init here will create a 350 00:24:11,450 --> 00:24:15,740 person with name 'Name'. 351 00:24:15,740 --> 00:24:23,660 And you'll notice what I'm doing here is introducing an 352 00:24:23,660 --> 00:24:25,050 extra attribute lastName -- self.lastName. 353 00:24:29,680 --> 00:24:32,790 And that's because I just want to make life easy for myself. 354 00:24:32,790 --> 00:24:35,830 I figure I'll want to find the last name frequently. 355 00:24:35,830 --> 00:24:38,940 Let's once and for all get it and put it in something. 356 00:24:41,920 --> 00:24:44,540 And I'm going to initialize birthday to none. 357 00:24:49,540 --> 00:24:56,020 The next attribute, or the next method, is get lastName. 358 00:24:56,020 --> 00:25:04,660 I have that here because I don't want users of this 359 00:25:04,660 --> 00:25:08,450 abstraction to even know that I have an attribute 360 00:25:08,450 --> 00:25:09,770 self.lastname. 361 00:25:09,770 --> 00:25:12,080 That's part of the implementation. 362 00:25:12,080 --> 00:25:15,620 And so I have this method that fetches it. 363 00:25:15,620 --> 00:25:19,490 And you'll see as you build classes that you often have 364 00:25:19,490 --> 00:25:22,140 things called get. 365 00:25:22,140 --> 00:25:25,440 And those are typically methods that return some 366 00:25:25,440 --> 00:25:27,860 information about an instance of the class. 367 00:25:31,860 --> 00:25:36,580 You'll also frequently have set methods, for example, set 368 00:25:36,580 --> 00:25:45,990 birthday that gives values to instances of the class. 369 00:25:49,280 --> 00:25:51,230 More interestingly, I have get age. 370 00:25:54,300 --> 00:25:58,370 And that's using some of the built in operations on 371 00:25:58,370 --> 00:26:00,890 DateTime conveniently. 372 00:26:00,890 --> 00:26:07,370 It allows me to subtract one date from another and get a 373 00:26:07,370 --> 00:26:08,620 number of days. 374 00:26:11,980 --> 00:26:15,390 So this will allow me to return somebody's age in days. 375 00:26:20,330 --> 00:26:23,520 Then I've got another underbar underbar method we 376 00:26:23,520 --> 00:26:24,990 haven't seen yet. 377 00:26:24,990 --> 00:26:28,210 lt stands for less than. 378 00:26:28,210 --> 00:26:31,140 Not a big surprise. 379 00:26:31,140 --> 00:26:39,240 And I'm going to use this to order names, or order people. 380 00:26:39,240 --> 00:26:42,580 Why am I using a special operator rather than just 381 00:26:42,580 --> 00:26:48,650 putting in the method L-E-S-S-T-H. A-N? 382 00:26:48,650 --> 00:26:49,900 E-N? 383 00:26:53,074 --> 00:26:57,230 I'm doing that because I want to be able to write things 384 00:26:57,230 --> 00:27:04,260 like p1 less than p2 in my code. 385 00:27:04,260 --> 00:27:09,890 And Python will take that and turn it into the underbar 386 00:27:09,890 --> 00:27:11,140 underbar LT. 387 00:27:14,750 --> 00:27:21,350 Better yet, if I have a list say of person's, I can use the 388 00:27:21,350 --> 00:27:26,330 built in sort operator on that list, and it will be smart 389 00:27:26,330 --> 00:27:29,100 enough to know when it's comparing two people to do the 390 00:27:29,100 --> 00:27:32,120 sort to use the underbar underbar LT. 391 00:27:35,760 --> 00:27:37,350 Very convenient kind of thing. 392 00:27:40,450 --> 00:27:41,800 Let's look at an example. 393 00:27:41,800 --> 00:27:43,050 Let's look at some code. 394 00:27:51,380 --> 00:27:56,485 So I'm going to set me to John Guttag, and him to Barack 395 00:27:56,485 --> 00:27:59,670 Hussein Obama, her to Madonna. 396 00:27:59,670 --> 00:28:00,920 And we'll print some things. 397 00:28:18,410 --> 00:28:20,840 So I printed him, and I printed him.getlastName. 398 00:28:26,990 --> 00:28:31,805 I can now set some birthdays. 399 00:28:43,500 --> 00:28:46,840 Let's look at this line. 400 00:28:46,840 --> 00:28:49,757 How do you feel about him.birthday equals 8/4/61? 401 00:28:59,170 --> 00:29:00,270 We'll come back to it. 402 00:29:00,270 --> 00:29:02,340 But I want you to think about it. 403 00:29:11,630 --> 00:29:15,210 And we see that Obama is-- 404 00:29:15,210 --> 00:29:17,710 well, we see their ages here. 405 00:29:17,710 --> 00:29:21,510 Actually, we see that Madonna is older. 406 00:29:21,510 --> 00:29:23,740 She looks really old when you look at that number of days, 407 00:29:23,740 --> 00:29:26,300 doesn't it. 408 00:29:26,300 --> 00:29:28,890 Maybe she is. 409 00:29:28,890 --> 00:29:30,250 Now what's going to happen here? 410 00:29:41,510 --> 00:29:42,760 I messed up. 411 00:29:46,240 --> 00:29:50,700 And I messed up because I went in and directly accessed the 412 00:29:50,700 --> 00:29:54,400 instance variable and assigned it what I thought was a 413 00:29:54,400 --> 00:29:56,190 reasonable representation of a birthdate. 414 00:29:59,130 --> 00:30:01,530 But I shouldn't have because that's not even the 415 00:30:01,530 --> 00:30:04,740 appropriate type. 416 00:30:04,740 --> 00:30:08,850 It's a string rather than something from DateTime. 417 00:30:08,850 --> 00:30:13,530 So again, we see the impact of my having done this evil thing 418 00:30:13,530 --> 00:30:20,860 of violating the abstraction boundary and stuck in there 419 00:30:20,860 --> 00:30:23,135 try to directly access an instance variable. 420 00:30:28,010 --> 00:30:29,260 We can do some comparisons. 421 00:30:37,320 --> 00:30:44,370 And what we see is that I'm not less than Madonna. 422 00:30:44,370 --> 00:30:45,620 I guess that's OK. 423 00:30:50,780 --> 00:30:52,030 You with me so far? 424 00:30:57,500 --> 00:31:07,590 I can make a list of these things and print the list. 425 00:31:15,880 --> 00:31:19,490 So it does a fairly nice job calling the underbar underbar 426 00:31:19,490 --> 00:31:22,320 STR operator. 427 00:31:22,320 --> 00:31:27,100 And you'll note I had no trouble throwing objects of 428 00:31:27,100 --> 00:31:28,580 type person into the list. 429 00:31:28,580 --> 00:31:31,210 No different than putting ints, or floats, 430 00:31:31,210 --> 00:31:32,210 or any of the built-ins. 431 00:31:32,210 --> 00:31:35,040 So it all works nicely. 432 00:31:35,040 --> 00:31:37,630 And then I can sort it and print that. 433 00:31:47,560 --> 00:31:50,700 And now the lists come out in a different order because it's 434 00:31:50,700 --> 00:31:55,790 using the underbar underbar LT operator to sort the elements. 435 00:31:55,790 --> 00:31:58,750 All of this is just by way of showing you how convenient it 436 00:31:58,750 --> 00:32:01,986 is to write code that uses a data abstraction. 437 00:32:07,690 --> 00:32:11,430 If we go back and look at the code, we'll see that once 438 00:32:11,430 --> 00:32:18,000 again person was a subclass of object. 439 00:32:18,000 --> 00:32:19,640 That's why we can do all these things we've 440 00:32:19,640 --> 00:32:21,180 been doing with it. 441 00:32:21,180 --> 00:32:23,820 But now I'm going to start using the hierarchy. 442 00:32:33,830 --> 00:32:36,940 MIT people are special. 443 00:32:36,940 --> 00:32:39,490 I hate to say that because I know we have non-MIT 444 00:32:39,490 --> 00:32:40,670 people in the room. 445 00:32:40,670 --> 00:32:43,810 But MIT people are special. 446 00:32:43,810 --> 00:32:46,290 Well here's at least one of the special 447 00:32:46,290 --> 00:32:48,490 attributes of MIT people. 448 00:32:48,490 --> 00:32:49,740 They all have an ID. 449 00:32:52,540 --> 00:32:56,020 So I'm now going to say an MIT person is a 450 00:32:56,020 --> 00:33:00,920 special subclass of person. 451 00:33:00,920 --> 00:33:05,290 So it has all of the properties of a person. 452 00:33:05,290 --> 00:33:13,010 And the way we describe that is it inherits the properties 453 00:33:13,010 --> 00:33:14,260 of the super class. 454 00:33:27,840 --> 00:33:29,090 And it adds a property. 455 00:33:32,090 --> 00:33:39,160 We can now assign an ID number. 456 00:33:39,160 --> 00:33:43,510 And now we're going to see the thing I promised to show you, 457 00:33:43,510 --> 00:33:44,785 which is a class variable. 458 00:33:48,190 --> 00:33:53,800 Next ID num is not associated with an instance of MIT 459 00:33:53,800 --> 00:33:58,830 person, but it's associated with the class itself. 460 00:33:58,830 --> 00:34:01,110 It's a class variable. 461 00:34:01,110 --> 00:34:06,215 I can do that because classes are themselves objects. 462 00:34:09,280 --> 00:34:13,070 And the advantage of this is every time I get a new 463 00:34:13,070 --> 00:34:17,010 instance of this class, I can assign a unique ID. 464 00:34:21,770 --> 00:34:25,130 Similar to the way we were using global variables earlier 465 00:34:25,130 --> 00:34:30,020 in the term, typically once we have classes, we'd stop using 466 00:34:30,020 --> 00:34:34,489 global variables because we have these class variables, 467 00:34:34,489 --> 00:34:39,320 which can serve very much the same purpose in many cases. 468 00:34:39,320 --> 00:34:44,290 And so now every time I get a new MIT person, I give them an 469 00:34:44,290 --> 00:34:48,210 ID and then increment the ID number so that the next person 470 00:34:48,210 --> 00:34:49,460 will get a different one. 471 00:34:52,040 --> 00:34:59,090 So I added a property, this ID number property, which I find 472 00:34:59,090 --> 00:35:02,140 by get ID num. 473 00:35:02,140 --> 00:35:06,405 I've also overwritten an existing property. 474 00:35:24,890 --> 00:35:29,510 You'll note that I've changed the definition of underbar 475 00:35:29,510 --> 00:35:32,480 underbar LT. 476 00:35:32,480 --> 00:35:36,820 So it's now saying we're going to compare two people not on 477 00:35:36,820 --> 00:35:39,010 the basis of their names but on the 478 00:35:39,010 --> 00:35:40,545 basis of their ID numbers. 479 00:35:46,270 --> 00:35:48,540 So let's look at some code that uses this. 480 00:36:00,980 --> 00:36:02,710 Get rid of the other code so it doesn't 481 00:36:02,710 --> 00:36:03,960 clutter up the screen. 482 00:36:33,520 --> 00:36:36,400 So we'll look at some things here. 483 00:36:36,400 --> 00:36:42,300 We'll get some MIT people called p1, p2, and p3. 484 00:36:42,300 --> 00:36:48,420 And we'll print their ID nums by calling get ID num. 485 00:36:51,200 --> 00:36:54,480 And you can see that Barbara Beaver gets 0, and the first 486 00:36:54,480 --> 00:36:58,230 Sue Wong gets 1, and the second Sue Wong has ID 2. 487 00:37:04,290 --> 00:37:07,840 I can create even a third such person. 488 00:37:07,840 --> 00:37:09,815 And now let's think about what happens here. 489 00:37:15,280 --> 00:37:23,340 I'm going to print whether or not p1 is less than p2 and 490 00:37:23,340 --> 00:37:25,400 whether or not p3 is less than p2. 491 00:37:28,680 --> 00:37:30,150 What should we get when we do this? 492 00:37:33,580 --> 00:37:34,830 Somebody? 493 00:37:37,420 --> 00:37:39,264 Pardon? 494 00:37:39,264 --> 00:37:40,870 AUDIENCE: True and false. 495 00:37:40,870 --> 00:37:44,316 PROFESSOR: I heard a true false. 496 00:37:44,316 --> 00:37:48,370 And indeed that's right because it's comparing IDs. 497 00:37:48,370 --> 00:37:50,885 Now, suppose I want to compare names. 498 00:37:53,920 --> 00:37:56,965 I could if I chose do this. 499 00:38:01,380 --> 00:38:07,250 I could call person underbar underbar LT. 500 00:38:07,250 --> 00:38:12,120 And what this says is don't use the 501 00:38:12,120 --> 00:38:15,940 less than of the subclass. 502 00:38:15,940 --> 00:38:18,380 Go up and use the super class one to do the comparison. 503 00:38:32,950 --> 00:38:34,670 So it's going up and doing that. 504 00:38:38,660 --> 00:38:41,120 I can do other things. 505 00:38:41,120 --> 00:38:42,940 I can compare things for equality. 506 00:38:45,980 --> 00:38:51,585 Let me just rip through all of these and see what we get. 507 00:38:54,720 --> 00:38:56,290 Whoops. 508 00:38:56,290 --> 00:38:58,920 Surprise! 509 00:38:58,920 --> 00:39:01,290 Well, before we get to that surprise-- 510 00:39:01,290 --> 00:39:02,930 and it's not actually a surprise. 511 00:39:02,930 --> 00:39:04,750 I shouldn't have uncommented it. 512 00:39:04,750 --> 00:39:06,000 Let's look at the other ones. 513 00:39:20,720 --> 00:39:24,710 We can say is p1 equal to p4? 514 00:39:24,710 --> 00:39:27,250 And we discover it's not. 515 00:39:27,250 --> 00:39:29,400 That's good. 516 00:39:29,400 --> 00:39:33,230 And we can say is p4 less than p3? 517 00:39:33,230 --> 00:39:34,670 That all works. 518 00:39:34,670 --> 00:39:36,300 It's not. 519 00:39:36,300 --> 00:39:40,950 But I can't say p3 less than p4. 520 00:39:44,010 --> 00:39:45,740 And why can't I do that? 521 00:39:48,730 --> 00:39:51,380 Why did I get an error message when I did that? 522 00:40:01,530 --> 00:40:02,024 Yes? 523 00:40:02,024 --> 00:40:04,494 Someone wanted to answer that? 524 00:40:04,494 --> 00:40:07,952 AUDIENCE: That's because you mix [UNINTELLIGIBLE]? 525 00:40:07,952 --> 00:40:10,916 PROFESSOR: Can you say that more loudly? 526 00:40:10,916 --> 00:40:12,398 AUDIENCE: She's a person, not an MIT person. 527 00:40:12,398 --> 00:40:14,265 So you didn't assign her an ID number. 528 00:40:14,265 --> 00:40:16,390 PROFESSOR: Exactly right. 529 00:40:16,390 --> 00:40:17,640 The answer-- 530 00:40:21,940 --> 00:40:24,820 I hit somebody right on the head. 531 00:40:24,820 --> 00:40:26,630 Now there's going to be a traumatic brain injury. 532 00:40:26,630 --> 00:40:27,590 I'm going to get sued. 533 00:40:27,590 --> 00:40:30,530 It's going to be messy. 534 00:40:30,530 --> 00:40:31,780 Time to leave the country. 535 00:40:37,450 --> 00:40:37,722 All right. 536 00:40:37,722 --> 00:40:43,500 Because it looks at p3 less than p4, looks at the first 537 00:40:43,500 --> 00:40:47,670 argument, which is p3, and says OK, what's the underbar 538 00:40:47,670 --> 00:40:51,760 underbar LT associated with p3? 539 00:40:51,760 --> 00:40:55,210 It's the one associated with an MIT person. 540 00:40:55,210 --> 00:40:57,340 Let's go execute that. 541 00:40:57,340 --> 00:41:03,310 And then it tries to retrieve the ID number of p4, which is 542 00:41:03,310 --> 00:41:07,070 not an MIT person, and it gets an error message. 543 00:41:10,820 --> 00:41:11,140 All right. 544 00:41:11,140 --> 00:41:11,690 Nothing subtle. 545 00:41:11,690 --> 00:41:14,590 It's the same kind of thing we've seen all along when we 546 00:41:14,590 --> 00:41:17,100 use type errors. 547 00:41:17,100 --> 00:41:20,610 In this case it's called an attribute error because we've 548 00:41:20,610 --> 00:41:23,630 attempted to access an attribute of an instance that 549 00:41:23,630 --> 00:41:26,045 doesn't exist. 550 00:41:26,045 --> 00:41:28,740 And so we could catch it. 551 00:41:28,740 --> 00:41:29,900 It's raised an exception. 552 00:41:29,900 --> 00:41:33,090 We could catch it as we looked at Tuesday, but we're not 553 00:41:33,090 --> 00:41:35,970 going to do that because it's really a programming bug when 554 00:41:35,970 --> 00:41:37,220 that happens. 555 00:41:39,500 --> 00:41:41,180 OK, let's continue. 556 00:41:45,330 --> 00:41:46,710 We were interested in students. 557 00:41:49,960 --> 00:41:54,040 So we're going to continue our hierarchy here. 558 00:41:54,040 --> 00:41:58,130 And now I'm going to introduce a subclass of an MIT person 559 00:41:58,130 --> 00:42:00,895 called an UG, short for undergraduate. 560 00:42:04,880 --> 00:42:09,730 Underbar underbar init is going to call MIT person 561 00:42:09,730 --> 00:42:14,790 underbar underbar init, which will give the UG an ID number 562 00:42:14,790 --> 00:42:16,090 and a name. 563 00:42:16,090 --> 00:42:19,090 And it's going to introduce yet another instance 564 00:42:19,090 --> 00:42:22,330 attribute, or field, called the year. 565 00:42:22,330 --> 00:42:26,080 And so the year, initially, is none. 566 00:42:26,080 --> 00:42:27,405 Then I can set the year. 567 00:42:30,650 --> 00:42:33,400 Though if I try and set it as something greater than 5, I'm 568 00:42:33,400 --> 00:42:38,350 going to raise an overflow error called too many. 569 00:42:38,350 --> 00:42:41,990 No undergraduate should be a year greater than 5. 570 00:42:41,990 --> 00:42:45,070 And I can get the year. 571 00:42:45,070 --> 00:42:47,095 Let's look at what happens when we do that. 572 00:42:55,540 --> 00:42:57,230 So I'll have two UG's. 573 00:42:57,230 --> 00:42:59,630 Both happen to be named Jane Doe. 574 00:42:59,630 --> 00:43:03,640 And then the same MIT person as before. 575 00:43:03,640 --> 00:43:08,100 Let's run this code and see-- well, what's going to happen? 576 00:43:08,100 --> 00:43:11,720 What's going to happen when I say print UG1? 577 00:43:11,720 --> 00:43:15,200 The first thing it's going to do is going to say is there an 578 00:43:15,200 --> 00:43:20,440 underbar underbar STR associated with UGs? 579 00:43:20,440 --> 00:43:23,600 And the answer is no. 580 00:43:23,600 --> 00:43:27,820 That's OK because I know an UG is also an MIT person. 581 00:43:27,820 --> 00:43:31,870 If I don't find it at the lowest level class, I'll 582 00:43:31,870 --> 00:43:35,860 bounce up and say all right, is there an underbar underbar 583 00:43:35,860 --> 00:43:38,975 STR associated with an MIT person? 584 00:43:42,240 --> 00:43:43,350 No. 585 00:43:43,350 --> 00:43:44,640 That's OK. 586 00:43:44,640 --> 00:43:48,670 I'll go up another level and say, well, I know an MIT 587 00:43:48,670 --> 00:43:51,630 person happens to be a person. 588 00:43:51,630 --> 00:43:54,870 And then they'll say oh, good there is an underbar underbar 589 00:43:54,870 --> 00:43:57,500 STR associated with person. 590 00:43:57,500 --> 00:44:00,070 So I'll use that one. 591 00:44:00,070 --> 00:44:02,210 So it looks at the class. 592 00:44:02,210 --> 00:44:04,640 If it doesn't find it, it goes to the super class. 593 00:44:04,640 --> 00:44:07,230 If it doesn't find it, it goes to the super class. 594 00:44:07,230 --> 00:44:10,770 And it does that all the way up until the end, where at 595 00:44:10,770 --> 00:44:13,140 worst, it will use the built-in thing for printing 596 00:44:13,140 --> 00:44:16,960 objects because remember everything is 597 00:44:16,960 --> 00:44:19,530 a subclass of objects. 598 00:44:19,530 --> 00:44:21,000 You don't want to do that. 599 00:44:21,000 --> 00:44:23,380 You want to have something more elegant than object at 600 00:44:23,380 --> 00:44:27,730 location xe345, or whatever if would have printed. 601 00:44:37,910 --> 00:44:40,530 Then we'll do some comparisons. 602 00:44:40,530 --> 00:44:43,220 It will first look for the most local and then work its 603 00:44:43,220 --> 00:44:44,470 way up as needed. 604 00:44:50,240 --> 00:44:51,490 OK? 605 00:44:54,000 --> 00:44:55,530 Let's keep going. 606 00:44:55,530 --> 00:44:58,490 We're going to introduce another kind of person called 607 00:44:58,490 --> 00:45:00,800 a graduate student. 608 00:45:00,800 --> 00:45:03,240 And I'm going to write pass. 609 00:45:03,240 --> 00:45:10,700 What that means is a G is an MIT person with no special 610 00:45:10,700 --> 00:45:16,960 properties, all the usual properties of an MIT person. 611 00:45:16,960 --> 00:45:19,360 Does not have a year because graduate students could be 612 00:45:19,360 --> 00:45:23,140 here more or less forever, which goes like 613 00:45:23,140 --> 00:45:24,390 this when I say that. 614 00:45:27,470 --> 00:45:29,630 Why did I introduce the type in the first place? 615 00:45:33,590 --> 00:45:38,110 Because it lets me do type checking. 616 00:45:38,110 --> 00:45:44,880 I can now check whether or not a person is a graduate student 617 00:45:44,880 --> 00:45:51,210 because an instance of G will have all of the properties of 618 00:45:51,210 --> 00:45:55,650 an MIT person, but it will have a different type. 619 00:45:55,650 --> 00:45:58,310 It will be type G. 620 00:45:58,310 --> 00:46:01,440 And so I can now ask the question is the type of this 621 00:46:01,440 --> 00:46:05,660 object a G. Or is it an MIT person and 622 00:46:05,660 --> 00:46:06,910 get a different answer. 623 00:46:14,480 --> 00:46:15,730 So I can do this. 624 00:46:19,600 --> 00:46:21,990 And if I go type of G1-- 625 00:46:24,890 --> 00:46:27,530 well, that's interesting. 626 00:46:27,530 --> 00:46:33,280 It says classmain.G. 627 00:46:33,280 --> 00:46:36,000 It's going to upset its class. 628 00:46:36,000 --> 00:46:39,060 And the class is defined at the outermost level, which is 629 00:46:39,060 --> 00:46:40,270 called main. 630 00:46:40,270 --> 00:46:45,630 And the classes name is G, which is what we expect. 631 00:46:50,330 --> 00:46:52,350 And so I could write something like that. 632 00:46:57,180 --> 00:47:03,630 Type of G1 equals equals G. And I get True. 633 00:47:07,000 --> 00:47:07,140 Ok. 634 00:47:07,140 --> 00:47:09,310 So it's a handy thing to be able to do. 635 00:47:12,350 --> 00:47:19,670 And in fact, I'm now going to bounce back to MIT person and 636 00:47:19,670 --> 00:47:21,390 add another method to it. 637 00:47:24,000 --> 00:47:29,540 And this happens all the time when I'm programming that I go 638 00:47:29,540 --> 00:47:33,290 define a class, think I'm done, and then some time later 639 00:47:33,290 --> 00:47:35,400 decide that it would be convenient to add something 640 00:47:35,400 --> 00:47:37,480 new, another method. 641 00:47:37,480 --> 00:47:41,370 In this case, I'm now adding the method is student, which 642 00:47:41,370 --> 00:47:45,420 returns type of self equal equal UG or type of self equal 643 00:47:45,420 --> 00:47:47,140 equals G. 644 00:47:47,140 --> 00:47:52,490 So this will let me distinguish a student from 645 00:47:52,490 --> 00:47:53,900 another kind of MIT person. 646 00:47:58,450 --> 00:48:03,150 So for example, if I want to have a course list-- 647 00:48:03,150 --> 00:48:07,770 another class, this is a subclass of object. 648 00:48:07,770 --> 00:48:11,250 You'll note I have an add student method, which takes 649 00:48:11,250 --> 00:48:14,740 self and who, maybe it should be whom. 650 00:48:14,740 --> 00:48:18,760 And it says, if not who.isstudent raise type error 651 00:48:18,760 --> 00:48:21,570 not a student. 652 00:48:21,570 --> 00:48:25,580 So I'm getting some leverage now out of this. 653 00:48:25,580 --> 00:48:28,690 Now I wouldn't need to necessarily do this. 654 00:48:28,690 --> 00:48:37,600 I could have said if not type of who equals G, or type of 655 00:48:37,600 --> 00:48:39,730 who equals UG. 656 00:48:39,730 --> 00:48:42,180 But I chose not to. 657 00:48:42,180 --> 00:48:46,980 The reason I chose not to is looking ahead, I might want to 658 00:48:46,980 --> 00:48:48,250 add some other students. 659 00:48:48,250 --> 00:48:51,950 I might want to add special student, for example. 660 00:48:51,950 --> 00:48:55,080 Or I might want to add cross registering student as 661 00:48:55,080 --> 00:48:57,930 separate types. 662 00:48:57,930 --> 00:49:03,660 Now, the nice thing is I don't have to make a lot of changes. 663 00:49:03,660 --> 00:49:07,790 I know there's exactly one place in my code that defines 664 00:49:07,790 --> 00:49:10,440 what it means to be an MIT student. 665 00:49:10,440 --> 00:49:13,010 I go back and I change that method. 666 00:49:13,010 --> 00:49:16,140 And even if I asked whether somebody's a student in a 100 667 00:49:16,140 --> 00:49:18,920 different places, I only have to make one 668 00:49:18,920 --> 00:49:21,520 change to fix my code. 669 00:49:21,520 --> 00:49:26,940 So I'm getting some modularity by associating the method with 670 00:49:26,940 --> 00:49:32,110 the class MIT person rather than every time 671 00:49:32,110 --> 00:49:33,360 I need to use it.