1 00:00:00 --> 00:00:00 2 00:00:00 --> 00:00:01 The following content is provided under a 3 00:00:01 --> 00:00:03 Creative Commons license. 4 00:00:03 --> 00:00:06 Your support will help MIT OpenCourseWare continue to 5 00:00:06 --> 00:00:10 offer high quality educational resources for free, To make a 6 00:00:10 --> 00:00:13 donation or view additional materials from hundreds of 7 00:00:13 --> 00:00:19 MIT courses, visit MIT OpenCourseWare at ocw.mit.edu. 8 00:00:19 --> 00:00:25 PROFESSOR: Last time, Professor Guttag introduced the idea of 9 00:00:25 --> 00:00:29 objects and classes and this wonderful phrase called 10 00:00:29 --> 00:00:31 object-oriented programming. 11 00:00:31 --> 00:00:33 And it's a topic I want to pick up on today, we're going to do 12 00:00:33 --> 00:00:36 for the next few lectures, and it's a topic I want to spend 13 00:00:36 --> 00:00:43 some time on because this idea of capturing data and methods, 14 00:00:43 --> 00:00:45 the term we're going to use for it, but data and functions that 15 00:00:45 --> 00:00:48 belong to that data, things that can be used to manipulate 16 00:00:48 --> 00:00:50 them, is a really powerful one. 17 00:00:50 --> 00:00:53 What we're really getting at is the idea of saying I want to 18 00:00:53 --> 00:00:57 have a way of grouping together information into units 19 00:00:57 --> 00:00:58 that make sense. 20 00:00:58 --> 00:01:00 So I can go back to one of those topics we had at the 21 00:01:00 --> 00:01:03 beginning, which is the idea of abstraction, that I can create 22 00:01:03 --> 00:01:07 one of those units as a simple entity, bury away the details 23 00:01:07 --> 00:01:09 and write really modular code. 24 00:01:09 --> 00:01:11 And so we're going to talk about that a 25 00:01:11 --> 00:01:13 lot as we go along. 26 00:01:13 --> 00:01:16 What we're really doing, or I shouldn't say what we're really 27 00:01:16 --> 00:01:18 doing, a basic piece of what we're doing, when we talk about 28 00:01:18 --> 00:01:22 classes or objects, is we're doing something that Professor 29 00:01:22 --> 00:01:26 Guttag mentioned, we're defining an abstract data type. 30 00:01:26 --> 00:01:28 Now what in the world does that mean? 31 00:01:28 --> 00:01:30 Well basically what we're doing is we're giving ourselves the 32 00:01:30 --> 00:01:33 ability to create data types the same way that we have some 33 00:01:33 --> 00:01:37 built-ins, so we have things like int, float, string, these 34 00:01:37 --> 00:01:39 are built-in data types. 35 00:01:39 --> 00:01:41 And if you think about it, associated with each one of 36 00:01:41 --> 00:01:44 those data types is a set of functions it's 37 00:01:44 --> 00:01:46 intended to apply to. 38 00:01:46 --> 00:01:49 Sometimes the functions -- sometimes a function can be 39 00:01:49 --> 00:01:53 used on multiple data types, plus, for example, we saw could 40 00:01:53 --> 00:01:56 add strings, or could add ints, but each one of those data 41 00:01:56 --> 00:01:58 types has associated with it a set of functions that are 42 00:01:58 --> 00:02:00 geared to handling them. 43 00:02:00 --> 00:02:03 We want to do the same thing, but with our data types. 44 00:02:03 --> 00:02:06 We want to create data types and functions, or we're going 45 00:02:06 --> 00:02:09 to call them methods, that are specifically aimed at 46 00:02:09 --> 00:02:11 manipulating those kinds of objects. 47 00:02:11 --> 00:02:14 And our goal is then to basically see how we can build 48 00:02:14 --> 00:02:18 systems that take advantage of that modularity. 49 00:02:18 --> 00:02:20 Right, so the fundamental idea then, is, I want to glue 50 00:02:20 --> 00:02:23 together information, I want to take pieces of data that 51 00:02:23 --> 00:02:25 naturally belong together, glue them together, and attach 52 00:02:25 --> 00:02:27 some methods to it. 53 00:02:27 --> 00:02:30 And that's, you know, saying a lot of words, let's do an 54 00:02:30 --> 00:02:32 example because it's probably easiest to see this by looking 55 00:02:32 --> 00:02:34 at a specific example. 56 00:02:34 --> 00:02:38 So here's the example I'm going to start with. 57 00:02:38 --> 00:02:44 Suppose I want to do little piece of code that's going 58 00:02:44 --> 00:02:48 to do planar geometry, points in the plane. 59 00:02:48 --> 00:02:50 All right, so I want to have some way of gluing 60 00:02:50 --> 00:02:51 those things together. 61 00:02:51 --> 00:02:53 Well you know what a point is, it's got an x- and a y- 62 00:02:53 --> 00:02:56 coordinate, it's natural to think about those two things as 63 00:02:56 --> 00:02:58 belonging as a single entity. 64 00:02:58 --> 00:03:00 So an easy way to do this would be to say, let's just 65 00:03:00 --> 00:03:06 represent them as a list. 66 00:03:06 --> 00:03:08 Just as a 2-list, or a list of 2 elements. 67 00:03:08 --> 00:03:10 It's easy to think of a point as just a list of an x- 68 00:03:10 --> 00:03:12 and a y- coordinate. 69 00:03:12 --> 00:03:23 OK, for example, I might say point p1 is that list, x is 1, 70 00:03:23 --> 00:03:33 y is 2. in fact, if I draw a little simple -- it's basically 71 00:03:33 --> 00:03:37 pointing to that point in the plane, right, x is 1, y is 2. 72 00:03:37 --> 00:03:41 OK, fine, there's another way to represent points on the 73 00:03:41 --> 00:03:45 plane now, and that's in polar form, so this, if you 74 00:03:45 --> 00:03:48 like, is Cartesian. 75 00:03:48 --> 00:03:50 Another way to represent a point in a plane is I've got a 76 00:03:50 --> 00:03:53 radius and I've got an angle from the x-axis, right, 77 00:03:53 --> 00:03:55 and that's a standard thing you might do. 78 00:03:55 --> 00:04:00 So I might define, for example, in polar form p 2, and let me 79 00:04:00 --> 00:04:08 see, which example did I do here, we'll make this the point 80 00:04:08 --> 00:04:11 of radius 2 and at angle pi by 2, I'm going to make it easy 81 00:04:11 --> 00:04:14 because pi by 2 is up along this axis, and that's 82 00:04:14 --> 00:04:17 basically that point. 83 00:04:17 --> 00:04:22 Ok, just fine, it's no big deal. 84 00:04:22 --> 00:04:23 But here now becomes the problem. 85 00:04:23 --> 00:04:26 I've glued things together but just using a list. 86 00:04:26 --> 00:04:30 Suppose I hand you one of these lists. 87 00:04:30 --> 00:04:32 How do you know which kind it is? 88 00:04:32 --> 00:04:34 How do you know whether it's in Cartesian form 89 00:04:34 --> 00:04:36 or in polar form? 90 00:04:36 --> 00:04:38 You have nothing that identifies that there, you have 91 00:04:38 --> 00:04:41 no way of saying what this grouping actually means. 92 00:04:41 --> 00:04:44 Right, and just to get a sense of this, let's look at a simple 93 00:04:44 --> 00:04:48 little example, so on your hand-out, you'll see I've got a 94 00:04:48 --> 00:04:50 little piece of code that says assuming I've got one of these 95 00:04:50 --> 00:04:52 points, I want to do things with it, for example I might 96 00:04:52 --> 00:04:53 want to add them together. 97 00:04:53 --> 00:04:57 So this first little piece of code right here says, ok you 98 00:04:57 --> 00:05:01 give me 2 points, I'll create another 1 of these lists and 99 00:05:01 --> 00:05:04 I'll simply take the x, sorry I shouldn't say x, I'm going to 100 00:05:04 --> 00:05:06 assume it's the x, the x-values are the two points, add them 101 00:05:06 --> 00:05:09 together, just right there, the y-values, add them together 102 00:05:09 --> 00:05:11 and return that list. 103 00:05:11 --> 00:05:17 And if I actually run this, which I'm going to do -- excuse 104 00:05:17 --> 00:05:21 me, do it again -- OK, you can see that I've added together 105 00:05:21 --> 00:05:23 and I've printed out the value of r, and I'll just show you 106 00:05:23 --> 00:05:24 that in fact that's what I've got. 107 00:05:24 --> 00:05:29 This looks fine, right, I'm doing the right thing. 108 00:05:29 --> 00:05:32 Another way of saying it is, I've actually said, what did I 109 00:05:32 --> 00:05:41 use there, (1,2) and (3,1), It's basically saying there is 110 00:05:41 --> 00:05:43 the first point, there's the second point, add them together 111 00:05:43 --> 00:05:45 and I get that point. 112 00:05:45 --> 00:05:49 OK, that sounds fine. 113 00:05:49 --> 00:05:53 Now, suppose in fact these weren't x and y glued together, 114 00:05:53 --> 00:05:55 these were radius and angle glued together. 115 00:05:55 --> 00:06:02 In that case point p 1 doesn't correspond to this point, it 116 00:06:02 --> 00:06:05 actually corresponds to the point of radius 2 and angle 117 00:06:05 --> 00:06:07 1, which is about here. 118 00:06:07 --> 00:06:11 I think I wrote this down carefully so I would make 119 00:06:11 --> 00:06:13 sure I did it right. 120 00:06:13 --> 00:06:17 Sorry, said that wrong, radius 1 and angle 2, 2 radians is a 121 00:06:17 --> 00:06:19 little bit more than pi half. 122 00:06:19 --> 00:06:23 And the second point is of radius 3 and angle 1, 123 00:06:23 --> 00:06:30 which is up about there. 124 00:06:30 --> 00:06:32 So what point, sorry, bad pun, what point am I 125 00:06:32 --> 00:06:34 trying to make here? 126 00:06:34 --> 00:06:38 Different understandings of what that piece means gives 127 00:06:38 --> 00:06:42 you different values, and that's a bit of a problem. 128 00:06:42 --> 00:06:45 The second problem is, suppose actually I had p 1 and p 2 129 00:06:45 --> 00:06:49 were in polar form, and I ran add points on them. 130 00:06:49 --> 00:06:52 This little piece of code here that I did. 131 00:06:52 --> 00:06:55 Does that even make any sense? 132 00:06:55 --> 00:06:55 Course not, right? 133 00:06:55 --> 00:06:58 You know when you add 2 polar forms, you add the radii 134 00:06:58 --> 00:07:00 together, you don't add the angles together, you need to 135 00:07:00 --> 00:07:02 do it in Cartesian form. 136 00:07:02 --> 00:07:06 So what I'm leading up to here is that we've got a problem. 137 00:07:06 --> 00:07:10 And the problem is, that we want to build this abstract 138 00:07:10 --> 00:07:12 data type, but we'd like to basically know what kind of 139 00:07:12 --> 00:07:16 object is it, and what functions actually belong to 140 00:07:16 --> 00:07:17 it, how do we use them? 141 00:07:17 --> 00:07:20 And so I'm going to go back to this idea of a class, and let's 142 00:07:20 --> 00:07:23 build the first of these, and that is shown right here on 143 00:07:23 --> 00:07:25 this piece of your handout. 144 00:07:25 --> 00:07:29 I'm going to define a class, and in particular, what 145 00:07:29 --> 00:07:33 I'm going to do, is walk through what that says. 146 00:07:33 --> 00:07:36 So I'm going to now build an object, it's going 147 00:07:36 --> 00:07:43 to represent a point. 148 00:07:43 --> 00:07:44 So what does that thing say up there? 149 00:07:44 --> 00:07:47 It's got this funky looking form, right, it says, I've got 150 00:07:47 --> 00:07:52 something that I'm going to call a class, got that key 151 00:07:52 --> 00:07:56 word class right here. 152 00:07:56 --> 00:07:58 And I'm going to give it a name, and right now I'm just 153 00:07:58 --> 00:08:00 building a simple piece of it -- but first of all, 154 00:08:00 --> 00:08:01 what does a class do? 155 00:08:01 --> 00:08:11 Think of this as, this is a template for creating 156 00:08:11 --> 00:08:19 instances of an object. 157 00:08:19 --> 00:08:22 At the moment, it's a really dumb template. 158 00:08:22 --> 00:08:23 I'm going to add to it in a second, but I want 159 00:08:23 --> 00:08:24 to build up to this. 160 00:08:24 --> 00:08:27 Right now it's got that second key word there called pass, 161 00:08:27 --> 00:08:29 which is just Python's way of saying there's an 162 00:08:29 --> 00:08:31 empty body in here. 163 00:08:31 --> 00:08:33 Right,, we're going to add to it in a second, but the idea is 164 00:08:33 --> 00:08:37 class is going to be a template for creating instances. 165 00:08:37 --> 00:08:39 How do I use it? 166 00:08:39 --> 00:08:41 Well, I call class just like a function, and 167 00:08:41 --> 00:08:42 you can see that below. 168 00:08:42 --> 00:08:45 Having created this thing called Cartesian point, I'm 169 00:08:45 --> 00:08:49 going to create two instances of it. c p 1 and c p 2. 170 00:08:49 --> 00:08:51 Notice the form of it, it's just the name of the class 171 00:08:51 --> 00:08:54 followed by open paren, close paren, treating 172 00:08:54 --> 00:08:56 it like a function. 173 00:08:56 --> 00:09:03 What that does, is that it creates, c p 1 and c p 2 are 174 00:09:03 --> 00:09:15 both instances of this type, specific versions of this type. 175 00:09:15 --> 00:09:18 For now the way to think about this is, when I call that class 176 00:09:18 --> 00:09:22 definition, it goes off and allocates a specific spot in 177 00:09:22 --> 00:09:25 memory that corresponds to that instance. 178 00:09:25 --> 00:09:26 Right now it's empty, actually it's not quite empty, it has 179 00:09:26 --> 00:09:28 a pointer back to the class. 180 00:09:28 --> 00:09:32 And I can give a name to that, so c p 1 and c p 2 are both 181 00:09:32 --> 00:09:34 going to point to that. 182 00:09:34 --> 00:09:37 Once I've got that, I can now start giving some variable 183 00:09:37 --> 00:09:39 names, sorry not, rephrase that, I can give some 184 00:09:39 --> 00:09:42 attributes, I can give some characteristics to 185 00:09:42 --> 00:09:43 these classes. 186 00:09:43 --> 00:09:49 So each instance has some internal, or will have 187 00:09:49 --> 00:09:58 some internal attributes. 188 00:09:58 --> 00:10:00 Notice how I did that up there. 189 00:10:00 --> 00:10:05 Having created c p 1 and c p 2, I had this weird 190 00:10:05 --> 00:10:06 looking form here. 191 00:10:06 --> 00:10:08 Not so weird, you've actually seen it before. 192 00:10:08 --> 00:10:15 In which I said c p 1 dot x equals 1.0. 193 00:10:15 --> 00:10:20 What's this doing? c p 1 points to an instance, it points to a 194 00:10:20 --> 00:10:23 particular version of this class. 195 00:10:23 --> 00:10:27 And I have now given an internal variable name x and a 196 00:10:27 --> 00:10:29 value associated with that. 197 00:10:29 --> 00:10:31 So I've just given it an x variable. 198 00:10:31 --> 00:10:34 All right, c p 1 dot y, I've said assign that 199 00:10:34 --> 00:10:37 to the value 2, 2,0. 200 00:10:37 --> 00:10:42 So now c p 1 has inside of it an x and y value. 201 00:10:42 --> 00:10:44 Did the same thing with c p 2, give it a different 202 00:10:44 --> 00:10:46 x and y value. 203 00:10:46 --> 00:10:49 Again, remind you, c p 2 is a different instance 204 00:10:49 --> 00:10:51 of this data type. 205 00:10:51 --> 00:10:53 All right, when I call the class definition it goes off 206 00:10:53 --> 00:10:56 and finds another spot in memory, says that the spot I'm 207 00:10:56 --> 00:10:58 going to give you a pointer back to that, give it the name 208 00:10:58 --> 00:11:02 c p 2, and then by running these 2 little assignments 209 00:11:02 --> 00:11:08 statements here, I've given it an x and a y value for c p 2. 210 00:11:08 --> 00:11:10 So you see why I say it's a template, right? 211 00:11:10 --> 00:11:12 Right now it's a simple template, but it's a template 212 00:11:12 --> 00:11:15 for creating what a class looks like, and I now have an x- and 213 00:11:15 --> 00:11:18 y- value associated with each instance of this. 214 00:11:18 --> 00:11:23 OK, and if I wanted to look at it, we can come back over here, 215 00:11:23 --> 00:11:28 and we can see what does c p 1 look like, interesting. 216 00:11:28 --> 00:11:31 It says some funky stuff, and says it's a kind 217 00:11:31 --> 00:11:33 of Cartesian point. 218 00:11:33 --> 00:11:35 And that's going to be valuable to me when I want to get back 219 00:11:35 --> 00:11:36 to using these things, right? 220 00:11:36 --> 00:11:39 You see that little thing says dot Cartesian point in there. 221 00:11:39 --> 00:11:42 If I want to get out right now the versions of these things, I 222 00:11:42 --> 00:11:46 can ask what's the value of c p 1 x, and it returns 223 00:11:46 --> 00:11:48 it back out. 224 00:11:48 --> 00:11:52 I could say c p 2 dot x, that was a bad one to use because 225 00:11:52 --> 00:11:54 they use the same valuable in both places, didn't I? 226 00:11:54 --> 00:12:01 So let's do c p 1 dot y, c p 2 dot y. 227 00:12:01 --> 00:12:04 OK, so I've just created local versions of variables with 228 00:12:04 --> 00:12:05 each one of these objects. 229 00:12:05 --> 00:12:08 I can get at them just like I would before, I can assign them 230 00:12:08 --> 00:12:12 in as I might have done before. 231 00:12:12 --> 00:12:16 OK, now that I've got that, we could think about what would I 232 00:12:16 --> 00:12:18 want to do with these points? 233 00:12:18 --> 00:12:20 Well one thing I might want to do is say, is this 234 00:12:20 --> 00:12:22 the same point or not? 235 00:12:22 --> 00:12:25 So the next little piece of code I've written here, just 236 00:12:25 --> 00:12:30 move down to it slightly. 237 00:12:30 --> 00:12:33 I've got a little piece of code called same point. 238 00:12:33 --> 00:12:35 And you can look at it. 239 00:12:35 --> 00:12:36 What does it say to do? 240 00:12:36 --> 00:12:39 It says, if you give me two of these data objects, I'm going 241 00:12:39 --> 00:12:42 to call them p 1 and p 2. 242 00:12:42 --> 00:12:46 I'm going to say, gee, is the x value the same in both of them, 243 00:12:46 --> 00:12:50 and if it is, and the y value's the same, then this is the same 244 00:12:50 --> 00:12:53 point, I'm going to return true. 245 00:12:53 --> 00:12:54 Notice the form. 246 00:12:54 --> 00:12:58 This is saying, that's a class, or sorry, an instance of a 247 00:12:58 --> 00:13:02 class, and I'm going to get the x value associated with it. 248 00:13:02 --> 00:13:04 I going to come back in a second to how it actually does 249 00:13:04 --> 00:13:07 that, but it basically says, get me x value for p 1, get me 250 00:13:07 --> 00:13:08 the x value for p 2, compare them, just as you 251 00:13:08 --> 00:13:10 would normally. 252 00:13:10 --> 00:13:12 I've got another little thing here that I'm going to use a 253 00:13:12 --> 00:13:16 little later on that just prints out values of things. 254 00:13:16 --> 00:13:21 OK, let's see what happens if I do this. 255 00:13:21 --> 00:13:22 Let me show you simple little example. 256 00:13:22 --> 00:13:29 I'm going to go over here, and let me define a 257 00:13:29 --> 00:13:30 couple of these things. 258 00:13:30 --> 00:13:42 I'm going to say p 1, try it again, p 1 is a Cartesian, it 259 00:13:42 --> 00:13:49 would help if I could type, Cartesian point, and I'm going 260 00:13:49 --> 00:13:56 to say p 1 of x is 3, p 1 of y is 4, and I'm going to make p 261 00:13:56 --> 00:14:03 2 another Cartesian point. 262 00:14:03 --> 00:14:12 And I'll give it an x value of 3 and a y value of 4. 263 00:14:12 --> 00:14:15 OK, now I want to say, are these the same? 264 00:14:15 --> 00:14:18 Thing I've got a little procedure that could do that, 265 00:14:18 --> 00:14:20 but you know the simplest thing I could do is to say well, gee, 266 00:14:20 --> 00:14:22 wait a minute, why don't I just check to see if these 267 00:14:22 --> 00:14:23 are the same thing? 268 00:14:23 --> 00:14:29 So I can say is p 1 the same as p 2, using Scheme's 269 00:14:29 --> 00:14:30 built-in is comparator. 270 00:14:30 --> 00:14:32 Say -- sorry? 271 00:14:32 --> 00:14:33 PROFESSOR 2: Part of Python? 272 00:14:33 --> 00:14:35 PROFESSOR: Part of Scheme, whoa, there's a Freudian 273 00:14:35 --> 00:14:36 slip, thank you, John. 274 00:14:36 --> 00:14:39 I'm showing my age, and my history here, is p 1 275 00:14:39 --> 00:14:41 and p 2 the same thing? 276 00:14:41 --> 00:14:42 Hey, there's a bad English sentence even worse, now 277 00:14:42 --> 00:14:43 I'm really thrown off. 278 00:14:43 --> 00:14:45 I'm using Python's is comparator to say is 279 00:14:45 --> 00:14:46 it the same thing? 280 00:14:46 --> 00:14:50 It says no. 281 00:14:50 --> 00:15:00 But if I say, are p 1 and p 2 the same point, it says yes. 282 00:15:00 --> 00:15:02 And this is a point I want to stress here. 283 00:15:02 --> 00:15:04 So what's going on in this case is, I want to distinguish 284 00:15:04 --> 00:15:18 between shallow equality and deep equality. 285 00:15:18 --> 00:15:23 The first thing is testing shallow equality. 286 00:15:23 --> 00:15:26 What it is doing, that's another bad English sentence, 287 00:15:26 --> 00:15:27 but what it is doing? 288 00:15:27 --> 00:15:32 Is is essentially saying, given 2 things, do they point to 289 00:15:32 --> 00:15:34 exactly the same referent? 290 00:15:34 --> 00:15:37 Or another way of thinking about it, is remember I said 291 00:15:37 --> 00:15:39 when I call that class definition it creates an 292 00:15:39 --> 00:15:41 instance, that's a pointer to some spot in memory that's got 293 00:15:41 --> 00:15:43 some local information around it. 294 00:15:43 --> 00:15:46 Is is saying, do these things point to exactly the same spot 295 00:15:46 --> 00:15:49 in memory, the same instance. 296 00:15:49 --> 00:15:56 Deep equality, we get to define, that's what I did 297 00:15:56 --> 00:15:57 by writing same point. 298 00:15:57 --> 00:16:00 OK, as I said, I want equality in the case of points to 299 00:16:00 --> 00:16:02 be, are the x- and y- coordinates the same? 300 00:16:02 --> 00:16:05 And I'm actually going to change it. just to 301 00:16:05 --> 00:16:06 show you this point. 302 00:16:06 --> 00:16:12 If I do the following, and I say, I'm going to 303 00:16:12 --> 00:16:14 assign p 1 to be p 2. 304 00:16:14 --> 00:16:15 What's that doing? 305 00:16:15 --> 00:16:18 It's taking the name p 1 and it's changing its value 306 00:16:18 --> 00:16:21 to point to exactly what p 2 points to. 307 00:16:21 --> 00:16:25 And then I say, are they the same thing? 308 00:16:25 --> 00:16:28 Answer's yes, because now they are pointing to exactly 309 00:16:28 --> 00:16:30 the same spot in memory. 310 00:16:30 --> 00:16:32 The same instance. 311 00:16:32 --> 00:16:34 OK, the reason I'm saying this is, we have one class 312 00:16:34 --> 00:16:36 definition, is a cookie cutter, it's a template that's going to 313 00:16:36 --> 00:16:38 let us build versions of these things. 314 00:16:38 --> 00:16:40 Every time I use it, I'm creating a new instance, 315 00:16:40 --> 00:16:43 that's a different thing inside of memory. 316 00:16:43 --> 00:16:45 And I want to have that because I want to have lots of 317 00:16:45 --> 00:16:47 versions of points. 318 00:16:47 --> 00:16:54 OK, now, let's go back to where I was. 319 00:16:54 --> 00:16:56 I said one of the things I want to do is, I want to have 320 00:16:56 --> 00:16:57 different versions of points. 321 00:16:57 --> 00:17:00 So I've got now things that are Cartesian points. 322 00:17:00 --> 00:17:03 I could do the same thing, I could build polar point. 323 00:17:03 --> 00:17:04 I wanted to show it to you here. 324 00:17:04 --> 00:17:07 I've got a class called polar point, which is right there, 325 00:17:07 --> 00:17:10 and same kind of thing, I can create instances of it, and 326 00:17:10 --> 00:17:13 then assign to them things like a radius and an angle, 327 00:17:13 --> 00:17:15 make instances of those. 328 00:17:15 --> 00:17:18 OK, John? 329 00:17:18 --> 00:17:21 PROFESSOR 2: I just want to maybe mention that in some of 330 00:17:21 --> 00:17:21 the reading, you'll see terms like object equality and value 331 00:17:21 --> 00:17:26 equality, instead of shallow equality and deep equality. 332 00:17:26 --> 00:17:33 PROFESSOR: Right, so, this object, this is, 333 00:17:33 --> 00:17:35 right, value quality. 334 00:17:35 --> 00:17:36 Right. 335 00:17:36 --> 00:17:37 And you will see both terms used. 336 00:17:37 --> 00:17:40 Some people like to use shallow and deep, object and value, but 337 00:17:40 --> 00:17:42 they're talking about the same thing, which is it the same 338 00:17:42 --> 00:17:45 object or is it the same, in this case, set of values, 339 00:17:45 --> 00:17:49 depending on what you want to define as you use it. 340 00:17:49 --> 00:17:57 OK, so as I said, now I can go off and I could create 341 00:17:57 --> 00:17:57 a different class. 342 00:17:57 --> 00:18:00 I've got Cartesian points, I could create a polar points. 343 00:18:00 --> 00:18:01 And I'm going to run it in a sec, but you can see, 344 00:18:01 --> 00:18:02 the same kind of idea. 345 00:18:02 --> 00:18:05 I define a class call polar point, I create a couple of 346 00:18:05 --> 00:18:07 them, and I give them a radius and an angle. 347 00:18:07 --> 00:18:10 And then I could do things like again, say, okay having done, 348 00:18:10 --> 00:18:18 that let me just run it here, run that, so I've now got polar 349 00:18:18 --> 00:18:19 point 1, and polar point 2. 350 00:18:19 --> 00:18:23 I can say is polar point 1 the same as polar point 2, and 351 00:18:23 --> 00:18:25 the answer should be no. 352 00:18:25 --> 00:18:30 And then I could say well, gee, are they the same point? 353 00:18:30 --> 00:18:38 Oops. 354 00:18:38 --> 00:18:40 What happened? 355 00:18:40 --> 00:18:41 Well it bombed out. 356 00:18:41 --> 00:18:43 Because, what was I expecting to do? 357 00:18:43 --> 00:18:46 I was expecting to compare x- and y- values, not 358 00:18:46 --> 00:18:47 radius and angle. 359 00:18:47 --> 00:18:50 And so this doesn't know how to do it, it doesn't have a method 360 00:18:50 --> 00:18:52 to deal with it, so it complains. 361 00:18:52 --> 00:18:54 So what's my problem here, and this is what I want 362 00:18:54 --> 00:18:55 to now lead up to. 363 00:18:55 --> 00:18:59 I could imagine writing another function for same point, and I 364 00:18:59 --> 00:19:01 have to give it a name like same point polar, and 365 00:19:01 --> 00:19:03 same point Cartesian. 366 00:19:03 --> 00:19:07 A different function to compare polar versions of these points. 367 00:19:07 --> 00:19:09 But that's starting to get to be a nuisance. 368 00:19:09 --> 00:19:13 What I'd really like to do is to have 1 representation for a 369 00:19:13 --> 00:19:17 point that supports different ways of getting information 370 00:19:17 --> 00:19:20 out, but has gathered within it, a method or a function for 371 00:19:20 --> 00:19:22 dealing with things like how do I know if it's the 372 00:19:22 --> 00:19:23 same point or not. 373 00:19:23 --> 00:19:26 So I want to take this idea classes now, and I 374 00:19:26 --> 00:19:28 want to generalize it. 375 00:19:28 --> 00:19:32 Right, and that is going to lead us then to this 376 00:19:32 --> 00:19:34 funky looking thing. 377 00:19:34 --> 00:19:36 Right there, and I'd like you to look at that 378 00:19:36 --> 00:19:38 in your handout. 379 00:19:38 --> 00:19:44 OK, I'm going to go back and rebuild the class. 380 00:19:44 --> 00:19:45 Ok, and again, I'm going to remind you, the 381 00:19:45 --> 00:19:50 class is this template. 382 00:19:50 --> 00:19:52 But now I'm going to change it, so what is that new 383 00:19:52 --> 00:19:54 version of class say. 384 00:19:54 --> 00:19:55 I'm going to call it c point just to make 385 00:19:55 --> 00:19:56 it a little shorter. 386 00:19:56 --> 00:19:59 You can see inside of it, it's got a set of definitions 387 00:19:59 --> 00:20:01 for things like functions. 388 00:20:01 --> 00:20:04 And that first one is this kind of interesting thing, it's 389 00:20:04 --> 00:20:09 two underbars, init, and two underbars. 390 00:20:09 --> 00:20:11 Underscores, I guess is the right way to say 391 00:20:11 --> 00:20:13 it, not underbars. 392 00:20:13 --> 00:20:17 Right that's a specific name, and what it basically says is, 393 00:20:17 --> 00:20:20 when I call the class instance. 394 00:20:20 --> 00:20:22 That's a bad mistake. 395 00:20:22 --> 00:20:24 When I call the class definition, that is I call 396 00:20:24 --> 00:20:30 c point, I'm going to call it with a specific 397 00:20:30 --> 00:20:31 set of arguments. 398 00:20:31 --> 00:20:34 And what is it going to happen is that init is 399 00:20:34 --> 00:20:36 going to then apply. 400 00:20:36 --> 00:20:38 It's going to apply to those arguments. 401 00:20:38 --> 00:20:40 So let me in fact show you an example. 402 00:20:40 --> 00:20:43 I've got a definition of Cartesian point, I've got a 403 00:20:43 --> 00:20:46 definition of polar point. 404 00:20:46 --> 00:20:51 Let me just run these to get them in there. 405 00:20:51 --> 00:20:52 Now let's do the following. 406 00:20:52 --> 00:20:57 Let's let p be Cartesian point, and we'll give 407 00:20:57 --> 00:21:03 it a couple of values. 408 00:21:03 --> 00:21:06 OK? 409 00:21:06 --> 00:21:06 So what happened? 410 00:21:06 --> 00:21:11 Notice in the class definition here, is there, this is the 411 00:21:11 --> 00:21:12 first thing that's got called, and I just called with the 412 00:21:12 --> 00:21:16 value for x and the value for y, and it went off and 413 00:21:16 --> 00:21:18 did something for me. 414 00:21:18 --> 00:21:25 Does that look right? 415 00:21:25 --> 00:21:28 This is where you all hate it, I get no eye contact anywhere. 416 00:21:28 --> 00:21:30 Anything look odd about that? 417 00:21:30 --> 00:21:31 I said. 418 00:21:31 --> 00:21:33 When I call this class definition, it calls init, and 419 00:21:33 --> 00:21:38 I give it an x and a y value. 420 00:21:38 --> 00:21:40 How many arguments does init take? 421 00:21:40 --> 00:21:41 Three. 422 00:21:41 --> 00:21:43 How many arguments did I give it? 423 00:21:43 --> 00:21:44 Two. 424 00:21:44 --> 00:21:47 What in the world's going on? 425 00:21:47 --> 00:21:49 Well, this is a piece of object-oriented coding that we 426 00:21:49 --> 00:21:50 get to talk about a little bit. 427 00:21:50 --> 00:21:53 There's this weird extra variable in there called self. 428 00:21:53 --> 00:21:57 So what is self? 429 00:21:57 --> 00:21:59 And I have to admit, I did the standard thing you do every 430 00:21:59 --> 00:22:02 time you run across something you don't know about, 431 00:22:02 --> 00:22:04 you go to Wikipedia. 432 00:22:04 --> 00:22:06 So I went and looked up self in Wikipedia, and 433 00:22:06 --> 00:22:08 I have to read it out. 434 00:22:08 --> 00:22:12 Wikipedia informs us that the self is the idea of a unified 435 00:22:12 --> 00:22:15 being, which is the source of an idiosyncratic consciousness. 436 00:22:15 --> 00:22:18 Moreover, this self is the agent responsible for the 437 00:22:18 --> 00:22:20 thoughts and actions of an individual to which 438 00:22:20 --> 00:22:21 they are ascribed. 439 00:22:21 --> 00:22:24 It is a substance which therefore endures through time, 440 00:22:24 --> 00:22:26 thus thoughts and actions at different moments of time may 441 00:22:26 --> 00:22:29 pertain to the same self. 442 00:22:29 --> 00:22:31 OK, how do we code that up? 443 00:22:31 --> 00:22:33 Sounds like an AI problem, I guess right? 444 00:22:33 --> 00:22:38 But there's actually hidden in there an important element, and 445 00:22:38 --> 00:22:42 that is, when I create an instance, I have to be able to 446 00:22:42 --> 00:22:45 get access to the things that characterize that instance. 447 00:22:45 --> 00:22:47 I won't say that they're thoughts and emotions or 448 00:22:47 --> 00:22:50 things, but what characterizes an instance here, it's the 449 00:22:50 --> 00:22:54 internal parameters that specify what is going on. 450 00:22:54 --> 00:22:57 So in fact what happens inside of an object-oriented system, 451 00:22:57 --> 00:23:00 and particularly in Python's object-oriented system, 452 00:23:00 --> 00:23:02 is the following. 453 00:23:02 --> 00:23:14 When we call init, it's going to create the instance, all 454 00:23:14 --> 00:23:16 right, just as we said before. 455 00:23:16 --> 00:23:29 But in particular, it's going to use self to 456 00:23:29 --> 00:23:32 refer to that instance. 457 00:23:32 --> 00:23:36 Right, so let me say this a little differently. 458 00:23:36 --> 00:23:38 I have a class definition. 459 00:23:38 --> 00:23:39 It's actually an object somewhere. 460 00:23:39 --> 00:23:42 It has inside of it all those internal definitions. 461 00:23:42 --> 00:23:45 When I call that class definition, it calls init. 462 00:23:45 --> 00:23:48 Init creates a pointer to the instance. 463 00:23:48 --> 00:23:51 And then it needs to have access to that, so it calls 464 00:23:51 --> 00:23:56 it, passing in self as the pointer to the instance. 465 00:23:56 --> 00:23:59 That is, it says it has access to that piece in memory, and 466 00:23:59 --> 00:24:02 now inside of that piece of memory, I can do things like, 467 00:24:02 --> 00:24:07 as you see here, define self dot x to be the value 468 00:24:07 --> 00:24:09 passed in for x. 469 00:24:09 --> 00:24:09 What's that doing? 470 00:24:09 --> 00:24:11 It's saying where's self pointing to? 471 00:24:11 --> 00:24:15 Inside of that structure, create a variable name x, and 472 00:24:15 --> 00:24:16 a value associated with it. 473 00:24:16 --> 00:24:19 Notice what I also do here, I create self dot y, give it a 474 00:24:19 --> 00:24:23 value, and then, oh cool, I can also set up what's the radius 475 00:24:23 --> 00:24:27 and angle for this point, by just doing a little 476 00:24:27 --> 00:24:29 bit of work. 477 00:24:29 --> 00:24:32 OK, in fact if you look at what it does there, just put the 478 00:24:32 --> 00:24:36 pointer over here, it says, get the value of x that I just 479 00:24:36 --> 00:24:40 stored away, square it, add it to the value of y squared that 480 00:24:40 --> 00:24:42 I just stored away, and then take square root, 481 00:24:42 --> 00:24:43 pass it back out. 482 00:24:43 --> 00:24:45 So I just computed the radius of that particular thing. 483 00:24:45 --> 00:24:46 Right? 484 00:24:46 --> 00:24:47 Compute the angle the same way, just using 485 00:24:47 --> 00:24:49 the appropriate things. 486 00:24:49 --> 00:24:54 So the idea is that self will always point to the 487 00:24:54 --> 00:24:56 particular instance. 488 00:24:56 --> 00:24:58 Now you might say, why? 489 00:24:58 --> 00:25:00 Why do it this way? 490 00:25:00 --> 00:25:03 Well, basically because it was a design choice when the 491 00:25:03 --> 00:25:05 creators of Python decided to create the language, they 492 00:25:05 --> 00:25:07 basically said, we're always going to have an explicit 493 00:25:07 --> 00:25:09 pointer to the instance. 494 00:25:09 --> 00:25:11 Some other object-oriented programming languages do 495 00:25:11 --> 00:25:13 not provide that pointer. 496 00:25:13 --> 00:25:15 This is kind of nice in my view, I don't know 497 00:25:15 --> 00:25:17 if John, you'd agree, but this is explicit. 498 00:25:17 --> 00:25:19 It actually lets you see how to get access to that pointer so 499 00:25:19 --> 00:25:21 you know what you're referring to. 500 00:25:21 --> 00:25:23 But it's simply design choice. 501 00:25:23 --> 00:25:26 So another way saying it again is, when I call the class 502 00:25:26 --> 00:25:28 definition, by default I'm going to look to see is there 503 00:25:28 --> 00:25:31 an init method there, and if there is, I'm going to use it. 504 00:25:31 --> 00:25:35 First argument by convention is always self, because it has to 505 00:25:35 --> 00:25:37 point to the instance, and then I pass, in this case, another 506 00:25:37 --> 00:25:39 couple of arguments in. 507 00:25:39 --> 00:25:43 OK, now, if I actually do this, and I'm going to show you the 508 00:25:43 --> 00:25:45 example, I just, what did I type over there, I 509 00:25:45 --> 00:25:48 got p was a c point. 510 00:25:48 --> 00:25:52 If I want to get values back out, I could in fact simply 511 00:25:52 --> 00:25:55 send to that instance a message, in this case 512 00:25:55 --> 00:25:58 I could say p dot x. 513 00:25:58 --> 00:26:00 In fact let's do it. 514 00:26:00 --> 00:26:08 If I do that over here -- aha -- it gets me back the value. 515 00:26:08 --> 00:26:10 Now let me spend just a second to say, what was this actually 516 00:26:10 --> 00:26:13 doing? p is an instance. 517 00:26:13 --> 00:26:16 It knows, or has stored away, and in fact let's look at it, 518 00:26:16 --> 00:26:22 if we look at what p does, p says -- it says reading through 519 00:26:22 --> 00:26:26 a little bit of this stuff here, it says -- it's a kind of 520 00:26:26 --> 00:26:29 Cartesian point, it's an instance, there's actually the 521 00:26:29 --> 00:26:31 memory location that it's at, that's why I say this idea of 522 00:26:31 --> 00:26:34 it's an instant at a specific spot. 523 00:26:34 --> 00:26:38 It knows that it came from this class, c point. 524 00:26:38 --> 00:26:41 So when I type, I'm sorry, I shouldn't say type, when I 525 00:26:41 --> 00:26:44 write, although I would have typed it, p dot x, here's what 526 00:26:44 --> 00:26:48 basically happens. p is an instance, it's being sent a 527 00:26:48 --> 00:26:50 message, in this case the message x, it says I want the 528 00:26:50 --> 00:26:55 x-value back out. p knows that it is a kind of Cartesian 529 00:26:55 --> 00:26:59 point, it actually goes and gets, if you like, the 530 00:26:59 --> 00:27:04 class definition up here. 531 00:27:04 --> 00:27:06 And is able to then say, inside of that class definition, 532 00:27:06 --> 00:27:09 find the value of x. 533 00:27:09 --> 00:27:13 All right, now, that's one of the ways we could get things 534 00:27:13 --> 00:27:15 out, but in fact it's really not a good way. 535 00:27:15 --> 00:27:20 A better way to do this would be the following. 536 00:27:20 --> 00:27:27 If I could type. 537 00:27:27 --> 00:27:29 What did I just do there? 538 00:27:29 --> 00:27:31 One of the things that I defined inside my class 539 00:27:31 --> 00:27:36 definition here was an internal method. 540 00:27:36 --> 00:27:39 That method has a name, obviously, and what does it do? 541 00:27:39 --> 00:27:42 It's going to go off and get the values of x and 542 00:27:42 --> 00:27:45 y attached to this thing and return them to me. 543 00:27:45 --> 00:27:46 And that's one of the things I want. 544 00:27:46 --> 00:27:57 I would like my classes to have methods. 545 00:27:57 --> 00:28:09 So you can access the values of the specific instance. 546 00:28:09 --> 00:28:11 Now, this is still a nuance, why would I like to do this? 547 00:28:11 --> 00:28:13 Well this is leading up to why I want to gather 548 00:28:13 --> 00:28:16 things together in classes to start with. 549 00:28:16 --> 00:28:19 It's perfectly legal in Python to type that in and get 550 00:28:19 --> 00:28:21 the value back out. 551 00:28:21 --> 00:28:23 As I said, I would prefer to do something that uses an 552 00:28:23 --> 00:28:28 accessor that I just wrote. 553 00:28:28 --> 00:28:35 So p dot Cartesian is a kind of accessor, it's getting 554 00:28:35 --> 00:28:39 access to the data. 555 00:28:39 --> 00:28:42 And here's why I'd like to have it. 556 00:28:42 --> 00:28:45 Right now, I still have the problem that those classes, 557 00:28:45 --> 00:28:47 those instances of classes, are exposed. 558 00:28:47 --> 00:28:48 What do I mean by that? 559 00:28:48 --> 00:28:57 Here's something I could do. 560 00:28:57 --> 00:29:07 Let's do it in fact. 561 00:29:07 --> 00:29:09 OK. 562 00:29:09 --> 00:29:13 What point in the plane does p now point to? 563 00:29:13 --> 00:29:16 X-axis is foobar y-axis ought to be foobass 564 00:29:16 --> 00:29:18 something else, right? 565 00:29:18 --> 00:29:21 I know it looks like a simple and silly little example, but 566 00:29:21 --> 00:29:25 at the moment, I still have the ability to go in and change the 567 00:29:25 --> 00:29:28 values of the parameters by that little definition. 568 00:29:28 --> 00:29:29 And this makes no sense. 569 00:29:29 --> 00:29:32 And this is because I don't have something I would 570 00:29:32 --> 00:29:40 really like to have, which is data hiding. 571 00:29:40 --> 00:29:42 So you'll see lots of definitions of this. 572 00:29:42 --> 00:29:49 I think of data hiding as basically saying, one can only 573 00:29:49 --> 00:29:54 access instance values, or, we'll call them that, instance 574 00:29:54 --> 00:30:06 values through defined methods. 575 00:30:06 --> 00:30:09 And that's a wonderful thing to have because it gives you that 576 00:30:09 --> 00:30:11 modularity, that encapsulation that basically says, when I 577 00:30:11 --> 00:30:15 create a point, the only way I can get at the values, is by 578 00:30:15 --> 00:30:17 using one of the defined methods, in this case it 579 00:30:17 --> 00:30:20 could be Cartesian, and get all the pieces of that. 580 00:30:20 --> 00:30:28 Unfortunately, Python doesn't do this. 581 00:30:28 --> 00:30:30 Which is really a shame. 582 00:30:30 --> 00:30:34 Or another way of saying it is, please don't do that. 583 00:30:34 --> 00:30:36 Don't go in and change the values of things by 584 00:30:36 --> 00:30:38 using the direct access. 585 00:30:38 --> 00:30:42 Have the computational hygiene, if you like, to only go through 586 00:30:42 --> 00:30:44 accessors, only go through methods that are actually 587 00:30:44 --> 00:30:46 provided to you as you do this. 588 00:30:46 --> 00:30:51 I actually don't remember, John, C++ does have data 589 00:30:51 --> 00:30:52 hiding, I think, right? 590 00:30:52 --> 00:30:57 PROFESSOR 2: And not only shouldn't you change it, you 591 00:30:57 --> 00:30:58 shouldn't even read it. 592 00:30:58 --> 00:30:58 PROFESSOR: Exactly. 593 00:30:58 --> 00:31:00 What you're going to see in a second I violated in some of my 594 00:31:00 --> 00:31:03 code, which Professor Guttag is going to yell at me shortly 595 00:31:03 --> 00:31:05 because I should have done it through accessors, but, 596 00:31:05 --> 00:31:06 he's exactly right. 597 00:31:06 --> 00:31:09 A good, hygienic way of doing this is, not only do I not go 598 00:31:09 --> 00:31:11 in and change things except through a pre-defined method, I 599 00:31:11 --> 00:31:13 shouldn't read it other than through a pre-defined method. 600 00:31:13 --> 00:31:23 I should use Cartesian or polar to pull out those pieces of it. 601 00:31:23 --> 00:31:26 Once I've got that, you notice I can now define 602 00:31:26 --> 00:31:30 a polar point, same way. 603 00:31:30 --> 00:31:33 Notice I've now solved one of my problems, which is, in each 604 00:31:33 --> 00:31:38 one of these cases here, I'm creating both x y and radius 605 00:31:38 --> 00:31:40 angle values inside of there. 606 00:31:40 --> 00:31:43 If it's in polar form I passed in a radius and angle and I'll 607 00:31:43 --> 00:31:46 compute what the x- and y- value is. 608 00:31:46 --> 00:31:48 If its in Cartesian form I'll pass in an x and y and compute 609 00:31:48 --> 00:31:50 what a radius and angle is. 610 00:31:50 --> 00:31:53 But it now says that in any, in no matter what kind of form I 611 00:31:53 --> 00:31:56 made it from, I can get out that kind of information. 612 00:31:56 --> 00:32:00 So for example I defined p, remember back over here, as a 613 00:32:00 --> 00:32:05 Cartesian point, but I can actually ask for 614 00:32:05 --> 00:32:07 its polar form. 615 00:32:07 --> 00:32:09 It's there accessible to me. 616 00:32:09 --> 00:32:11 OK, this is great. 617 00:32:11 --> 00:32:14 Just to drive home one more reason why I don't want to 618 00:32:14 --> 00:32:16 have changes to the values other than through 619 00:32:16 --> 00:32:18 pre-defined things. 620 00:32:18 --> 00:32:23 Notice what happens if I do the following. 621 00:32:23 --> 00:32:26 I could say I want to change the radius of 622 00:32:26 --> 00:32:28 this particular thing. 623 00:32:28 --> 00:32:32 OK, perfectly reasonable thing to do. 624 00:32:32 --> 00:32:38 And if I go look at the polar form of this, OK, good, 625 00:32:38 --> 00:32:40 looks right, right? 626 00:32:40 --> 00:32:42 It's now got a different radius, same angle, so I just 627 00:32:42 --> 00:32:44 changed the radius of it. 628 00:32:44 --> 00:32:46 Oh, but what happened to the Cartesian form. 629 00:32:46 --> 00:32:48 I should have done this earlier by typing the Cartesian form 630 00:32:48 --> 00:32:51 earlier, so let me go back to where I was, sorry for that, 631 00:32:51 --> 00:32:58 let me go make this a 1 again. 632 00:32:58 --> 00:33:01 If I look at the Cartesian, oh, I did have the Cartesian form, 633 00:33:01 --> 00:33:05 don't mind me while I mutter to myself here quietly. 634 00:33:05 --> 00:33:07 Yeah, that's right, I did screw that up badly. 635 00:33:07 --> 00:33:10 All right, we try one more time, here we go, let's 636 00:33:10 --> 00:33:12 try one more time. 637 00:33:12 --> 00:33:23 We'll make p a new point, ok? 638 00:33:23 --> 00:33:24 There's the Cartesian representation of it, 639 00:33:24 --> 00:33:26 which is right, (1,2). 640 00:33:26 --> 00:33:31 Here's the polar representation of it, some random set of 641 00:33:31 --> 00:33:33 numbers which makes sense. 642 00:33:33 --> 00:33:37 If I now say, I'm going to go ahead and change the radius of 643 00:33:37 --> 00:33:48 this, something, my polar form did it right, but what happened 644 00:33:48 --> 00:33:53 to the Cartesian form? 645 00:33:53 --> 00:33:56 Ah yes, didn't change. 646 00:33:56 --> 00:33:58 Which makes sense if you think of my code. 647 00:33:58 --> 00:34:00 I didn't have anything in there that says, if you change one of 648 00:34:00 --> 00:34:03 these values, other values depend on it, and I want to 649 00:34:03 --> 00:34:05 make that change to it. 650 00:34:05 --> 00:34:08 So this is one more example of stressing why I only want to 651 00:34:08 --> 00:34:12 come access to the instances through defined methods. 652 00:34:12 --> 00:34:14 Because I could've built that in, it says if you change the 653 00:34:14 --> 00:34:16 value of this thing, by the way you need to change recompute 654 00:34:16 --> 00:34:19 those other values in order to make this hold up. 655 00:34:19 --> 00:34:23 OK, so what else do I have then in my little class 656 00:34:23 --> 00:34:25 definitions here? 657 00:34:25 --> 00:34:28 So, I've got an init in both cases. 658 00:34:28 --> 00:34:31 I don't have to put an init in, but it's again, usually a good 659 00:34:31 --> 00:34:33 idea to put that in originally. 660 00:34:33 --> 00:34:34 I've got and init that says, when you create an instance, 661 00:34:34 --> 00:34:36 here's what you do. 662 00:34:36 --> 00:34:39 Notice that that typically also defines for me what the 663 00:34:39 --> 00:34:42 internal variables are, what the internal characteristics 664 00:34:42 --> 00:34:44 of the class are going to be. 665 00:34:44 --> 00:34:46 Again, I could have some other functions to compute things, 666 00:34:46 --> 00:34:48 but this is typically the place where I'm going to put them in. 667 00:34:48 --> 00:34:51 So this is giving me now that template, better way of saying 668 00:34:51 --> 00:34:53 it, all right, a template now, for a point is x, 669 00:34:53 --> 00:34:55 y, radius, angle. 670 00:34:55 --> 00:34:57 And I can see that in those pieces there. 671 00:34:57 --> 00:35:00 And then I've got some things that get me back out 672 00:35:00 --> 00:35:02 information about them. 673 00:35:02 --> 00:35:04 But I got a couple of other of these strange looking things in 674 00:35:04 --> 00:35:05 there with underbars to them. 675 00:35:05 --> 00:35:09 So let's look at what some of the traditional methods 676 00:35:09 --> 00:35:11 for classes are in Python. 677 00:35:11 --> 00:35:15 I have init. 678 00:35:15 --> 00:35:22 This is what's actually going to create the instance, 679 00:35:22 --> 00:35:24 instantiate it, create what the set of variable 680 00:35:24 --> 00:35:26 values are for it. 681 00:35:26 --> 00:35:32 OK, I have another one in there, underbar, underbar, str. 682 00:35:32 --> 00:35:38 Anybody have a sense of what that's doing? 683 00:35:38 --> 00:35:41 What's s -- sorry, I heard something, sorry go ahead. 684 00:35:41 --> 00:35:44 STUDENT: Display what I have. 685 00:35:44 --> 00:35:44 PROFESSOR: Displaying what I have. 686 00:35:44 --> 00:35:44 Thank you. 687 00:35:44 --> 00:35:46 Yeah, I was going to say, think about what does 688 00:35:46 --> 00:35:48 str do, in general? 689 00:35:48 --> 00:35:50 It converts things into a string type. 690 00:35:50 --> 00:35:52 How do we typically print things, we convert 691 00:35:52 --> 00:35:53 them to strings. 692 00:35:53 --> 00:35:56 So str is basically telling us how we want 693 00:35:56 --> 00:36:08 to have it printed out. 694 00:36:08 --> 00:36:15 OK, in fact if we look at this, if I say, print of p, it 695 00:36:15 --> 00:36:16 prints it out in that form. 696 00:36:16 --> 00:36:18 Now this is actually a poor way to do it, because you might 697 00:36:18 --> 00:36:19 say, well, it's just the list. 698 00:36:19 --> 00:36:20 But remember, it wasn't a list. 699 00:36:20 --> 00:36:21 What does it do? 700 00:36:21 --> 00:36:24 It says, if I want to print out something I built in Cartesian 701 00:36:24 --> 00:36:28 form up here, says, again, I'm going to pass it in a pointer 702 00:36:28 --> 00:36:31 to the instance, that self thing, and then I'm going to 703 00:36:31 --> 00:36:35 return a string that I combine together with an open and close 704 00:36:35 --> 00:36:39 paren, a comma in the middle, and getting the x-value and the 705 00:36:39 --> 00:36:41 y-value and converting them into strings before I put 706 00:36:41 --> 00:36:43 the whole thing together. 707 00:36:43 --> 00:36:46 So it gives me basically my printed representation. 708 00:36:46 --> 00:36:47 OK. 709 00:36:47 --> 00:36:49 What else do I have in here? 710 00:36:49 --> 00:36:54 Well, I have cmp. 711 00:36:54 --> 00:36:57 My handout's wrong, which I discovered this morning after 712 00:36:57 --> 00:36:58 I printed them all out. 713 00:36:58 --> 00:37:07 So the version I'd like you to have uses, that, greater than 714 00:37:07 --> 00:37:11 rather than equals that I had in my handout. 715 00:37:11 --> 00:37:14 What's cmp doing as a method? 716 00:37:14 --> 00:37:14 Yeah? 717 00:37:14 --> 00:37:16 STUDENT: Comparing values? 718 00:37:16 --> 00:37:17 PROFESSOR: Yeah, comparing values, right? 719 00:37:17 --> 00:37:20 And again, it's similar to what cmp would do 720 00:37:20 --> 00:37:22 generically in Python. 721 00:37:22 --> 00:37:23 It's a way of doing comparisons. 722 00:37:23 --> 00:37:29 So this is doing comparisons. 723 00:37:29 --> 00:37:31 Now, I put a version up there, I have no idea if this is 724 00:37:31 --> 00:37:33 the right way to do comparisons or not. 725 00:37:33 --> 00:37:35 I said both the x- and y- coordinates are bigger, 726 00:37:35 --> 00:37:36 then I'm going to return something to it. 727 00:37:36 --> 00:37:40 And I think in the polar one I said, if, what did I do there, 728 00:37:40 --> 00:37:42 I said, yeah, again if the x and y are greater than 729 00:37:42 --> 00:37:45 the other one, I'm going to return them to it. 730 00:37:45 --> 00:37:50 The version in the handout, what was that actually doing? 731 00:37:50 --> 00:37:56 You could look at the handout. 732 00:37:56 --> 00:38:00 Well I think it was comparing, are they the same? 733 00:38:00 --> 00:38:08 So that would actually be another method I could put in. 734 00:38:08 --> 00:38:11 Underbar underbar eq, underbar underbar. 735 00:38:11 --> 00:38:14 Would be a default or generic way of doing, are 736 00:38:14 --> 00:38:16 these things the same? 737 00:38:16 --> 00:38:23 OK, in each case, what these things are doing, is they're 738 00:38:23 --> 00:38:31 doing, what sometimes gets referred to as 739 00:38:31 --> 00:38:33 operator overloading. 740 00:38:33 --> 00:38:35 I know you don't remember that far back, but in about the 741 00:38:35 --> 00:38:38 second lecture I made a joke of Professor Guttag which, you 742 00:38:38 --> 00:38:40 know, you didn't laugh at, he didn't laugh at, that's okay. 743 00:38:40 --> 00:38:43 In which I said, you know, I didn't like the fact that 744 00:38:43 --> 00:38:45 things like plus are overloaded, because you can use 745 00:38:45 --> 00:38:48 plus to add strings, you can use plus to add numbers, you 746 00:38:48 --> 00:38:50 can use plus to add floats. 747 00:38:50 --> 00:38:53 And he quite correctly, because he's more senior than I am, 748 00:38:53 --> 00:38:54 more experienced than I am, said it's actually 749 00:38:54 --> 00:38:55 a good thing. 750 00:38:55 --> 00:38:57 And he's right. 751 00:38:57 --> 00:38:59 Most of the time. 752 00:38:59 --> 00:39:02 The reason I say that is, by having operator overloading I 753 00:39:02 --> 00:39:06 can use 1 generic interface to all of the objects 754 00:39:06 --> 00:39:07 that I want to use. 755 00:39:07 --> 00:39:10 So it makes sense to be able to say, look for many methods I do 756 00:39:10 --> 00:39:13 want to have a way of doing comparison, and I don't have to 757 00:39:13 --> 00:39:16 remember, at top level, what the name of the 758 00:39:16 --> 00:39:17 comparison method was. 759 00:39:17 --> 00:39:20 I can simply use the built-in Sc -- about to say Scheme 760 00:39:20 --> 00:39:23 again -- the built-in Python comparison operation. 761 00:39:23 --> 00:39:25 Say, are these 2 things the same? 762 00:39:25 --> 00:39:27 Same thing with cmp, that's just saying greater than, and 763 00:39:27 --> 00:39:30 greater than now can apply to strings, it can apply to 764 00:39:30 --> 00:39:32 floats, it could apply to points, it could add 765 00:39:32 --> 00:39:34 other pieces into it. 766 00:39:34 --> 00:39:36 So there are some downsides, in my view, to doing operator 767 00:39:36 --> 00:39:38 overloading, but there's some real pluses. 768 00:39:38 --> 00:39:41 And the main one is, I get to just decide, how do I want 769 00:39:41 --> 00:39:42 to use this, and call it. 770 00:39:42 --> 00:39:43 Yes, ma'am? 771 00:39:43 --> 00:39:47 STUDENT: [INAUDIBLE] 772 00:39:47 --> 00:39:52 PROFESSOR: Right, cmp other, so how would I call this? 773 00:39:52 --> 00:39:52 A good question. 774 00:39:52 --> 00:39:54 Here's the way I would call it. 775 00:39:54 --> 00:39:59 Let me give you, I'm going to create, a polar point, I'm 776 00:39:59 --> 00:40:02 going to call it q, and we'll give it some random values. 777 00:40:02 --> 00:40:09 OK, and now I want to know, is p greater than q? 778 00:40:09 --> 00:40:11 Now happens to return true here, but the question is, 779 00:40:11 --> 00:40:13 where's the other come from? 780 00:40:13 --> 00:40:16 P is a particular object type. 781 00:40:16 --> 00:40:19 When I try and evaluate that expression of greater than, is 782 00:40:19 --> 00:40:23 going to go into the class to say greater than 783 00:40:23 --> 00:40:25 is a comp method. 784 00:40:25 --> 00:40:27 So let me say it very carefully here. 785 00:40:27 --> 00:40:33 When I evaluate, yeah, when I evaluate this, p is an instance 786 00:40:33 --> 00:40:37 of a point, in this case it was actually a Cartesian point, it 787 00:40:37 --> 00:40:41 sends a message to the instance, which sends a message 788 00:40:41 --> 00:40:46 to the class, to get the cmp method from the class. 789 00:40:46 --> 00:40:51 And that then gets applied to itself, just p, and one other 790 00:40:51 --> 00:40:55 argument, which is the second piece there, so other points 791 00:40:55 --> 00:40:57 to the second argument that was present. 792 00:40:57 --> 00:40:59 OK. 793 00:40:59 --> 00:40:59 John? 794 00:40:59 --> 00:41:03 PROFESSOR 2: -- other, it could have said who or zort or -- 795 00:41:03 --> 00:41:05 PROFESSOR: Yeah, sorry, that was part of the question, I 796 00:41:05 --> 00:41:07 could have a picked foobar could put anything in here. 797 00:41:07 --> 00:41:11 It's simply, notice the form of it here is, it's going to take 798 00:41:11 --> 00:41:13 two arguments, and you're right, self is the 799 00:41:13 --> 00:41:14 original instance. 800 00:41:14 --> 00:41:16 This says, I need a second argument to it, and that second 801 00:41:16 --> 00:41:19 argument better be a point so I can do the comparison. 802 00:41:19 --> 00:41:20 Yes ma'am? 803 00:41:20 --> 00:41:23 STUDENT: [INAUDIBLE] 804 00:41:23 --> 00:41:28 PROFESSOR: What do you think happens? 805 00:41:28 --> 00:41:29 Sorry, the question was, what happens if I said 806 00:41:29 --> 00:41:31 p is less than q? 807 00:41:31 --> 00:41:34 Got it, yes? 808 00:41:34 --> 00:41:40 Seems pretty obvious, right? 809 00:41:40 --> 00:41:48 Next time I bring the right glasses. 810 00:41:48 --> 00:41:51 It's still calling cmp, but it's knowing that cmp 811 00:41:51 --> 00:41:53 is just reversing the order of the arguments. 812 00:41:53 --> 00:41:54 Ok, which makes sense. 813 00:41:54 --> 00:41:58 If greater than takes, expects, arguments in order x y, less 814 00:41:58 --> 00:42:01 than simply takes greater than, but with the 815 00:42:01 --> 00:42:02 arguments reversed. 816 00:42:02 --> 00:42:04 OK, so I don't have to, it's a great question, I don't have to 817 00:42:04 --> 00:42:06 create a second one for cmp. 818 00:42:06 --> 00:42:08 Cmp is just saying, is this bigger than, and if I 819 00:42:08 --> 00:42:10 want to reverse it, it goes the other way. 820 00:42:10 --> 00:42:10 Question? 821 00:42:10 --> 00:42:13 STUDENT: [INAUDIBLE] 822 00:42:13 --> 00:42:17 PROFESSOR: Or equal equal? 823 00:42:17 --> 00:42:25 Let's try equal equal because I didn't define it here. 824 00:42:25 --> 00:42:28 It says they're not the same, and boy, I need help on this 825 00:42:28 --> 00:42:32 one, John, it's not, there's no pre-defined eq in there. 826 00:42:32 --> 00:42:37 PROFESSOR 2: So, what cmp does, and maybe this isn't exactly 827 00:42:37 --> 00:42:40 the right way to write is, is cmp actually returns 828 00:42:40 --> 00:42:42 1 of 3 values. 829 00:42:42 --> 00:42:48 A 0, minus a positive value, zero or a negative value, 830 00:42:48 --> 00:42:51 depending upon whether it's less than, equal, 831 00:42:51 --> 00:42:52 or greater than. 832 00:42:52 --> 00:42:52 PROFESSOR: Right. 833 00:42:52 --> 00:42:56 PROFESSOR2: So it's not really a Boolean-valued function. 834 00:42:56 --> 00:42:59 It has 3 possible values it could return. 835 00:42:59 --> 00:43:02 PROFESSOR: And so in this case, it's using the same piece, but 836 00:43:02 --> 00:43:04 it's returning that middle value that says they're 837 00:43:04 --> 00:43:07 actually the same. 838 00:43:07 --> 00:43:09 Right, one the things you can see now is, we start building 839 00:43:09 --> 00:43:10 up classes, we get these methods. 840 00:43:10 --> 00:43:13 So you can actually say, how do I know which methods are 841 00:43:13 --> 00:43:14 associated with the class? 842 00:43:14 --> 00:43:20 For that, we can call dir. 843 00:43:20 --> 00:43:25 And what it does, is it gives me back a listing of all the 844 00:43:25 --> 00:43:27 things, all the methods, that are associated with it. 845 00:43:27 --> 00:43:32 Some of which I built: cmp, init, str. 846 00:43:32 --> 00:43:35 And there, notice, are the internal definitions and there 847 00:43:35 --> 00:43:37 are the internal variables. 848 00:43:37 --> 00:43:38 And in fact I should've said, we often call 849 00:43:38 --> 00:43:40 those things fields. 850 00:43:40 --> 00:43:46 So inside of an instance, associated with an instance, we 851 00:43:46 --> 00:43:51 have both methods and fields. 852 00:43:51 --> 00:43:54 These are both altogether called attributes 853 00:43:54 --> 00:43:56 of the instance. 854 00:43:56 --> 00:43:58 And then there were a couple of other ones in there that I 855 00:43:58 --> 00:44:00 hadn't actually dealt with. 856 00:44:00 --> 00:44:03 The reason I want to point this out to you is, if we go back up 857 00:44:03 --> 00:44:06 to the kinds of data objects we started with, floats, ints, 858 00:44:06 --> 00:44:09 strings, they actually behave the same way. 859 00:44:09 --> 00:44:13 They are instances of a class, and associated with that 860 00:44:13 --> 00:44:14 class is a set of methods. 861 00:44:14 --> 00:44:19 So for example, I can say, what are all the methods 862 00:44:19 --> 00:44:24 associated with the number, or the integer 1? 863 00:44:24 --> 00:44:26 And you probably recognize some of them in there, right, 864 00:44:26 --> 00:44:30 absolute value, add, comp, cors, well we didn't do cors, 865 00:44:30 --> 00:44:32 we did a bunch of other things. 866 00:44:32 --> 00:44:37 It could also say, what are the methods associated 867 00:44:37 --> 00:44:42 with the string, 1. 868 00:44:42 --> 00:44:44 I'm sure you can quickly graph it, but notice 869 00:44:44 --> 00:44:46 they aren't the same. 870 00:44:46 --> 00:44:47 That makes sense. 871 00:44:47 --> 00:44:50 We have some set of things we want to do with strings, and 872 00:44:50 --> 00:44:52 different set of things we want to do with numbers. 873 00:44:52 --> 00:44:54 But underlying Python is the same idea. 874 00:44:54 --> 00:44:58 These are instances of a class, and associated with that class 875 00:44:58 --> 00:45:01 are a set of methods, things that I can deal with. 876 00:45:01 --> 00:45:03 So this is a handy way of being able to see, what are in fact 877 00:45:03 --> 00:45:06 the methods that are available if I don't happen to remember 878 00:45:06 --> 00:45:08 them, and want to go back to them. 879 00:45:08 --> 00:45:12 OK, I want to spend the last few minutes just showing you 880 00:45:12 --> 00:45:15 a couple of other things that we can do in here. 881 00:45:15 --> 00:45:17 Let me see where I want to go with this. 882 00:45:17 --> 00:45:23 So let's add one more piece to this. 883 00:45:23 --> 00:45:26 OK, now that I've got points, I might want to 884 00:45:26 --> 00:45:27 do something with points. 885 00:45:27 --> 00:45:29 So an easy thing to do in planar geometry is I want 886 00:45:29 --> 00:45:30 to make a line segment. 887 00:45:30 --> 00:45:32 It's got a start point, it's got an end point. 888 00:45:32 --> 00:45:40 Right, if you want to think of it back over here. 889 00:45:40 --> 00:45:41 There's a line segment, it's got a starting 890 00:45:41 --> 00:45:44 point and ending point. 891 00:45:44 --> 00:45:45 Well, I can do the same thing. 892 00:45:45 --> 00:45:48 And the reason I want to use this as an example is, here's 893 00:45:48 --> 00:45:51 my little definition of segment. 894 00:45:51 --> 00:45:53 Again, it's got an initializer, or an instance 895 00:45:53 --> 00:45:56 creator, right there. 896 00:45:56 --> 00:45:59 Takes a start and an end point, just going to bind local 897 00:45:59 --> 00:46:01 variable names start and end to those pieces. 898 00:46:01 --> 00:46:04 But notice now, those aren't just simple things like 899 00:46:04 --> 00:46:08 numbers, those are actually points. 900 00:46:08 --> 00:46:09 And that's where the modularity comes in. 901 00:46:09 --> 00:46:12 Now I have the ability to say, I've got a new class, I can 902 00:46:12 --> 00:46:15 create instances of a line segment, and it's elements are 903 00:46:15 --> 00:46:19 themselves instances of points. 904 00:46:19 --> 00:46:20 OK? 905 00:46:20 --> 00:46:21 And then what might I want to do with the segment? 906 00:46:21 --> 00:46:23 I might want to get the length of the segment. 907 00:46:23 --> 00:46:25 And I know it's kind of, you can see it on your handout, 908 00:46:25 --> 00:46:28 it has the rest of the pieces over here. 909 00:46:28 --> 00:46:29 Ok, what's the geometry say? 910 00:46:29 --> 00:46:30 The length of a line segment? 911 00:46:30 --> 00:46:32 Well, it's Pythagoras, right? 912 00:46:32 --> 00:46:34 I take the difference in the x-values, squared, the 913 00:46:34 --> 00:46:36 difference in the y-values, squared, add them up, take 914 00:46:36 --> 00:46:38 the square root of that. 915 00:46:38 --> 00:46:41 Notice what this says to do. 916 00:46:41 --> 00:46:43 It says if I want to get the length of a segment, going to 917 00:46:43 --> 00:46:49 pass in that instance, it says from that instance, get the 918 00:46:49 --> 00:46:51 start point, that's the thing I just found. 919 00:46:51 --> 00:46:56 And then from that start point, get the x-value. 920 00:46:56 --> 00:47:00 Same thing, from that instance, get the endpoint, from that end 921 00:47:00 --> 00:47:02 point get the x-value, square. 922 00:47:02 --> 00:47:05 Add the same thing to the y-values, squared, 923 00:47:05 --> 00:47:07 take the square root. 924 00:47:07 --> 00:47:07 Yes, ma'am? 925 00:47:07 --> 00:47:13 STUDENT: So are you entering a tuple in for start and end? 926 00:47:13 --> 00:47:14 PROFESSOR: No. 927 00:47:14 --> 00:47:15 I'm entering -- well, let's look at the 928 00:47:15 --> 00:47:17 example right down here. 929 00:47:17 --> 00:47:20 In fact, let me uncomment it so we can look at it. 930 00:47:20 --> 00:47:21 All right. 931 00:47:22 --> 00:47:24 I'm going to uncomment that. 932 00:47:24 --> 00:47:25 So notice what I'm going to do. 933 00:47:25 --> 00:47:28 I'm going to build, this case, a Cartesian point, I'm going to 934 00:47:28 --> 00:47:32 build a second Cartesian point, and my segment passes in 935 00:47:32 --> 00:47:35 those class instances. 936 00:47:35 --> 00:47:36 All right, they're not tuples, they're simply an instance 937 00:47:36 --> 00:47:37 with some structuring. 938 00:47:37 --> 00:47:43 And in fact if I go off and run this, OK, what I was printing 939 00:47:43 --> 00:47:49 here was s 1 dot length, and that's -- What is it doing? 940 00:47:49 --> 00:47:51 S 1 is a segment. 941 00:47:51 --> 00:47:55 It has inside of it pointers to 2 points which are instances. 942 00:47:55 --> 00:48:00 And when I call length on this, it takes that starting point, 943 00:48:00 --> 00:48:02 sends it the message saying give me your x-coordinate, 944 00:48:02 --> 00:48:04 takes the endpoint, says give me your x-coordinate, 945 00:48:04 --> 00:48:06 and add them together. 946 00:48:06 --> 00:48:08 Now, I prefaced this a few minutes ago about saying 947 00:48:08 --> 00:48:10 Professor Guttag wasn't going to like me. 948 00:48:10 --> 00:48:12 He doesn't like me generally, but that's between he and I. 949 00:48:12 --> 00:48:14 He beats me regularly at tennis, which is why 950 00:48:14 --> 00:48:15 I don't like him. 951 00:48:15 --> 00:48:16 Sorry, John. 952 00:48:16 --> 00:48:18 This is being taped, which is really good, isn't it? 953 00:48:18 --> 00:48:19 So why am I saying that? 954 00:48:19 --> 00:48:23 I said that if I was really hygienic, and you can 955 00:48:23 --> 00:48:25 now wonder about how often do I shower? 956 00:48:25 --> 00:48:27 If I was really hygienic. 957 00:48:27 --> 00:48:32 I would only ever access the values through a method. 958 00:48:32 --> 00:48:35 And I'm cheating here, right, because what am I doing? 959 00:48:35 --> 00:48:39 I'm taking advantage of the fact that start is going to be 960 00:48:39 --> 00:48:43 a point, and I'm just directly saying, give me your x-value. 961 00:48:43 --> 00:48:44 So I don't know don't, John, I would argue if I'd written this 962 00:48:44 --> 00:48:47 better, I would have had a method that returned the x- and 963 00:48:47 --> 00:48:49 the y- value, and it would be cleaner to go after 964 00:48:49 --> 00:48:50 it that way. 965 00:48:50 --> 00:48:53 This is nice shorthand, all right, but it's something that 966 00:48:53 --> 00:48:57 in fact I probably would want to do differently. 967 00:48:57 --> 00:48:59 Why would I want to do it differently? 968 00:48:59 --> 00:49:02 Imagine that I've written code like this, written 969 00:49:02 --> 00:49:04 a bunch of code. 970 00:49:04 --> 00:49:06 And I originally decided I was going to have as points, 971 00:49:06 --> 00:49:09 it's going to have internal values of an x and a y. 972 00:49:09 --> 00:49:12 And then somewhere along the line, I decide to store things 973 00:49:12 --> 00:49:14 in a different representation. 974 00:49:14 --> 00:49:18 If I had had a clean interface, that I had a specific method to 975 00:49:18 --> 00:49:20 get those values out, I wouldn't have to 976 00:49:20 --> 00:49:22 change anything. 977 00:49:22 --> 00:49:24 Other than that interface. 978 00:49:24 --> 00:49:27 But here, if I decide I'm going to store things not in x and y, 979 00:49:27 --> 00:49:30 but with some other set of names, for example, I've gotta 980 00:49:30 --> 00:49:33 go back into these pieces of code that use the points, 981 00:49:33 --> 00:49:34 and change them. 982 00:49:34 --> 00:49:35 So I've lost modularity. 983 00:49:35 --> 00:49:38 I'd really like to have that modularity that says, I'm only 984 00:49:38 --> 00:49:41 going to get access to the values, not by calling their 985 00:49:41 --> 00:49:44 names, but by calling some specific method to get 986 00:49:44 --> 00:49:46 access to their names. 987 00:49:46 --> 00:49:48 You could argue, well, x is in some sense inherently a method, 988 00:49:48 --> 00:49:52 but it's not nearly as clean as what I would like. 989 00:49:52 --> 00:49:54 And the last piece I want you to see here, and then I'll let 990 00:49:54 --> 00:49:59 you go is, notice now how that encapsulation, that binding 991 00:49:59 --> 00:50:01 things together has really helped me. 992 00:50:01 --> 00:50:03 Given the abstraction, the notion of a point as an 993 00:50:03 --> 00:50:05 instance with some values, I can now start 994 00:50:05 --> 00:50:07 building segments. 995 00:50:07 --> 00:50:08 And I could now extend that. 996 00:50:08 --> 00:50:10 I could have, you know, polygonal figures, that are 997 00:50:10 --> 00:50:11 a sequence of segments. 998 00:50:11 --> 00:50:14 And I would be able to simply bury away the details of how 999 00:50:14 --> 00:50:16 those other instances are created from how I want to 1000 00:50:16 --> 00:50:20 use them by simply calling methods on the classes. 1001 00:50:20 --> 00:50:23 We'll come back to this next time. 1002 00:50:23 --> 00:50:24