WEBVTT

00:00:00.790 --> 00:00:03.190
The following content is
provided under a Creative

00:00:03.190 --> 00:00:04.730
Commons license.

00:00:04.730 --> 00:00:07.030
Your support will help
MIT OpenCourseWare

00:00:07.030 --> 00:00:11.390
continue to offer high quality
educational resources for free.

00:00:11.390 --> 00:00:13.990
To make a donation or
view additional materials

00:00:13.990 --> 00:00:17.880
from hundreds of MIT courses,
visit MIT OpenCourseWare

00:00:17.880 --> 00:00:18.840
at ocw.mit.edu.

00:00:30.420 --> 00:00:31.670
PROFESSOR: All right everyone.

00:00:31.670 --> 00:00:33.950
Let's get started.

00:00:33.950 --> 00:00:37.940
So today's lecture and
Wednesday's lecture,

00:00:37.940 --> 00:00:39.950
we're going to talk
about this thing called

00:00:39.950 --> 00:00:41.430
object oriented programming.

00:00:41.430 --> 00:00:43.220
And if you haven't
programmed before,

00:00:43.220 --> 00:00:46.550
I think this is a fairly
tough concept to grasp.

00:00:46.550 --> 00:00:49.730
But hopefully with
many, many examples

00:00:49.730 --> 00:00:55.520
and just by looking at the
code available from lectures,

00:00:55.520 --> 00:00:58.210
you'll hopefully get
the hang of it quickly.

00:00:58.210 --> 00:01:02.770
So let's talk a little
bit about objects.

00:01:02.770 --> 00:01:05.950
And we've seen objects
in Python so far.

00:01:05.950 --> 00:01:09.160
Objects are basically
data in Python.

00:01:09.160 --> 00:01:12.270
So every object that we've
seen has a certain type.

00:01:12.270 --> 00:01:14.185
OK, that we know.

00:01:14.185 --> 00:01:16.150
Behind the scenes,
though, every object

00:01:16.150 --> 00:01:18.530
has these two additional things.

00:01:18.530 --> 00:01:20.280
One is some data representation.

00:01:20.280 --> 00:01:26.050
So how Python represents the
object just behind the scenes

00:01:26.050 --> 00:01:27.580
and what are different
ways that you

00:01:27.580 --> 00:01:31.000
can interact with the object.

00:01:31.000 --> 00:01:35.370
So for example, every one of
these is a different object.

00:01:35.370 --> 00:01:38.970
For example, this
is the number 1,234.

00:01:38.970 --> 00:01:42.120
It's a specific object
that is of type integer.

00:01:42.120 --> 00:01:45.940
The number 5 is a different
object that's of type integer

00:01:45.940 --> 00:01:46.920
and so on.

00:01:46.920 --> 00:01:47.880
We've seen floats.

00:01:47.880 --> 00:01:48.990
We've seen strings.

00:01:48.990 --> 00:01:50.730
We've seen lists.

00:01:50.730 --> 00:01:54.580
Lists and dictionaries are
more complicated objects.

00:01:54.580 --> 00:01:55.280
Object types.

00:01:55.280 --> 00:01:56.590
Sorry.

00:01:56.590 --> 00:01:59.260
But every object has a
type, some sort of way

00:01:59.260 --> 00:02:03.169
that it's represented
in Python and some ways

00:02:03.169 --> 00:02:04.460
that we can interact with them.

00:02:07.020 --> 00:02:07.520
OK.

00:02:07.520 --> 00:02:10.190
So the idea behind object
oriented programming

00:02:10.190 --> 00:02:13.100
is, first of all, everything
in Python is an object.

00:02:13.100 --> 00:02:15.660
We've said that before
and in this lecture

00:02:15.660 --> 00:02:17.690
I think we'll really
get at what that means.

00:02:17.690 --> 00:02:21.320
So we've seen strings,
integers, dictionaries, lists.

00:02:21.320 --> 00:02:22.700
Those are all objects.

00:02:22.700 --> 00:02:24.500
When we did functions,
we saw that we

00:02:24.500 --> 00:02:27.620
could pass as a parameter
another function.

00:02:27.620 --> 00:02:29.740
So functions were also
objects in Python.

00:02:29.740 --> 00:02:33.519
So literally everything
in Python is an object.

00:02:33.519 --> 00:02:35.810
So what are the kinds of
things we can do with objects?

00:02:35.810 --> 00:02:39.230
Well, once you have a type,
you can create a new object

00:02:39.230 --> 00:02:40.544
that is of some type.

00:02:40.544 --> 00:02:41.960
And you can create
as many objects

00:02:41.960 --> 00:02:44.870
as you'd like of that
particular type, right?

00:02:44.870 --> 00:02:46.940
An integer 5 and integer 7.

00:02:46.940 --> 00:02:50.150
Those all work in a program.

00:02:50.150 --> 00:02:52.640
Once you've created
these new objects,

00:02:52.640 --> 00:02:54.290
you can manipulate them.

00:02:54.290 --> 00:02:56.570
So for a list, for example,
you can append an item

00:02:56.570 --> 00:02:59.420
to the end of the list,
you can delete an item,

00:02:59.420 --> 00:03:03.980
remove it, concatenate
two lists together.

00:03:03.980 --> 00:03:07.021
So that's ways that you
can interact with objects.

00:03:07.021 --> 00:03:09.270
And the last thing you can
do is you can destroy them.

00:03:09.270 --> 00:03:11.000
So and with lists,
we saw explicitly

00:03:11.000 --> 00:03:13.976
that you can delete
elements from a list,

00:03:13.976 --> 00:03:15.350
or you can just
forget about them

00:03:15.350 --> 00:03:19.380
by reassigning a variable
to another value,

00:03:19.380 --> 00:03:21.920
and then at some
point, Python will

00:03:21.920 --> 00:03:24.690
collect all of these dead
objects and reclaim the memory.

00:03:27.810 --> 00:03:31.790
So let's continue
exploring what objects are.

00:03:31.790 --> 00:03:34.320
So let's say I have these
two separate objects.

00:03:34.320 --> 00:03:35.450
One is a blue car.

00:03:35.450 --> 00:03:36.950
One is a pink car.

00:03:36.950 --> 00:03:39.740
So objects are really
data abstractions.

00:03:39.740 --> 00:03:43.050
So these two cars can be
created by the same blueprint.

00:03:43.050 --> 00:03:43.670
OK?

00:03:43.670 --> 00:03:47.400
This is a blueprint for a car
and if an object is a data

00:03:47.400 --> 00:03:49.640
abstraction, there's two
things that this abstraction

00:03:49.640 --> 00:03:50.940
is going to capture.

00:03:50.940 --> 00:03:54.200
The first is some sort
of representation.

00:03:54.200 --> 00:03:57.310
What is going to represent the
car, what data represents a car

00:03:57.310 --> 00:03:58.540
object?

00:03:58.540 --> 00:04:00.400
And the second is
what are ways that we

00:04:00.400 --> 00:04:03.080
can interact with the object?

00:04:03.080 --> 00:04:06.010
So if we think about
a car blueprint,

00:04:06.010 --> 00:04:08.380
some general
representation for a car

00:04:08.380 --> 00:04:10.900
could be the number of wheels
it has, the number of doors

00:04:10.900 --> 00:04:13.450
it has, maybe its
length, maybe its height,

00:04:13.450 --> 00:04:19.579
so this is all part of what
data represents the car.

00:04:19.579 --> 00:04:21.149
OK?

00:04:21.149 --> 00:04:22.830
The interface for
the car is what

00:04:22.830 --> 00:04:24.580
are ways that you
can interact with it.

00:04:24.580 --> 00:04:28.115
So for example, you
could paint a car, right?

00:04:28.115 --> 00:04:30.720
So you could change its color.

00:04:30.720 --> 00:04:34.010
You could have the
car make a noise

00:04:34.010 --> 00:04:36.340
and different cars might
make different noises.

00:04:36.340 --> 00:04:38.060
Or you can drive the car, right?

00:04:38.060 --> 00:04:40.610
So these are all ways that
you can interact with the car.

00:04:40.610 --> 00:04:43.130
Whereas the representation
are what makes up the car.

00:04:43.130 --> 00:04:48.590
What data abstractions
make up the car.

00:04:48.590 --> 00:04:53.630
Let's bring it a little closer
to home by looking at a list.

00:04:53.630 --> 00:04:56.990
So we have this data
type of list, right?

00:04:56.990 --> 00:05:00.770
We've worked with lists before.

00:05:00.770 --> 00:05:05.030
The list with elements 1, 2, 3,
and 4 is a very specific object

00:05:05.030 --> 00:05:07.730
that is of type list.

00:05:07.730 --> 00:05:09.930
Again, we think about it
in terms of two things.

00:05:09.930 --> 00:05:13.500
One is what is the data
representation of the list?

00:05:13.500 --> 00:05:16.337
So behind the scenes how
does Python see lists?

00:05:16.337 --> 00:05:18.420
And the second is, how do
you interact with lists?

00:05:18.420 --> 00:05:20.378
So what are ways that
you can manipulate a list

00:05:20.378 --> 00:05:23.260
object once it's created?

00:05:23.260 --> 00:05:26.360
So behind the scenes
you have a list, L,

00:05:26.360 --> 00:05:29.030
which is going to be made up
of essentially two things.

00:05:29.030 --> 00:05:34.280
One is going to be the
value at specific index.

00:05:34.280 --> 00:05:34.970
OK?

00:05:34.970 --> 00:05:37.250
So at index 0, it has
the value 1, right,

00:05:37.250 --> 00:05:39.770
because it's the first
element in the list.

00:05:39.770 --> 00:05:43.010
And the second thing
that represents a list

00:05:43.010 --> 00:05:47.990
is going to be this second
part, which is a pointer.

00:05:47.990 --> 00:05:49.690
And internally this
pointer is going

00:05:49.690 --> 00:05:52.420
to tell Python
where is the memory

00:05:52.420 --> 00:05:57.610
location in the computer where
you can access the element

00:05:57.610 --> 00:05:58.930
index 1.

00:05:58.930 --> 00:06:02.320
So it's just essentially
going to be a chain,

00:06:02.320 --> 00:06:04.340
going from one
index to the other.

00:06:04.340 --> 00:06:08.505
And at the next memory location
you have the value at index 1,

00:06:08.505 --> 00:06:09.880
and then you have
another pointer

00:06:09.880 --> 00:06:11.620
that takes you to the
location in memory

00:06:11.620 --> 00:06:14.440
where the index 2 is located.

00:06:14.440 --> 00:06:16.330
And in index 2 you
have the value and then

00:06:16.330 --> 00:06:19.490
the next pointer,
and so on and so on.

00:06:19.490 --> 00:06:23.750
So this is how Python
internally represents a list.

00:06:23.750 --> 00:06:25.560
OK?

00:06:25.560 --> 00:06:28.340
How you manipulate lists,
we've done this a lot, right?

00:06:28.340 --> 00:06:34.410
You can index into a list, you
can add two lists together,

00:06:34.410 --> 00:06:37.160
you can get the length, you can
append to the end of a list,

00:06:37.160 --> 00:06:39.860
you can sort a list, reverse a
list, and so many other things,

00:06:39.860 --> 00:06:40.700
right?

00:06:40.700 --> 00:06:42.116
So these are all
ways that you can

00:06:42.116 --> 00:06:45.230
interact with the list object
as soon as you've created it.

00:06:45.230 --> 00:06:48.590
So notice both of these,
the internal representation

00:06:48.590 --> 00:06:50.270
and how you
manipulate lists, you

00:06:50.270 --> 00:06:53.600
don't actually
know internally how

00:06:53.600 --> 00:06:55.070
these are represented, right?

00:06:55.070 --> 00:06:57.710
How did whoever
wrote the list class

00:06:57.710 --> 00:06:59.120
decide to implement a sort.

00:06:59.120 --> 00:07:00.440
We don't know.

00:07:00.440 --> 00:07:03.380
You also weren't aware of how
these lists were represented

00:07:03.380 --> 00:07:03.890
internally.

00:07:03.890 --> 00:07:05.270
And you didn't
need to know that.

00:07:05.270 --> 00:07:08.300
That's the beauty of
object oriented programming

00:07:08.300 --> 00:07:11.140
and having these
data abstractions.

00:07:11.140 --> 00:07:13.870
The representations are
private of these objects

00:07:13.870 --> 00:07:17.950
and they are only known by what
you can find out how it's done,

00:07:17.950 --> 00:07:21.440
but they only should be known
by whoever implemented them.

00:07:21.440 --> 00:07:23.140
You, as someone who
uses this class,

00:07:23.140 --> 00:07:25.540
doesn't really need to know
how a list is represented

00:07:25.540 --> 00:07:27.890
internally in order
to be able to use it

00:07:27.890 --> 00:07:30.980
and to write cool
programs with them.

00:07:30.980 --> 00:07:32.430
OK?

00:07:32.430 --> 00:07:35.930
So just find a
motivation here before we

00:07:35.930 --> 00:07:38.600
start writing our
own types of objects

00:07:38.600 --> 00:07:41.330
is the advantages of
object oriented programming

00:07:41.330 --> 00:07:44.270
is really that
you're able to bundle

00:07:44.270 --> 00:07:47.620
this data, bundle some
internal representation,

00:07:47.620 --> 00:07:51.760
and some ways to interact with
a program into these packages.

00:07:51.760 --> 00:07:55.304
And with these packages,
you can create objects

00:07:55.304 --> 00:07:56.720
and all of these
objects are going

00:07:56.720 --> 00:07:57.928
to behave the exact same way.

00:07:57.928 --> 00:08:00.190
They're going to have the
same internal representation

00:08:00.190 --> 00:08:03.260
and the same way that you
can interact with them.

00:08:03.260 --> 00:08:08.150
And ultimately, this is going to
contribute to the decomposition

00:08:08.150 --> 00:08:11.840
and abstraction ideas
that we talked about when

00:08:11.840 --> 00:08:13.227
we talked about functions.

00:08:13.227 --> 00:08:14.810
And that means that
you're going to be

00:08:14.810 --> 00:08:19.280
able to write code that's a lot
more reusable and a lot easier

00:08:19.280 --> 00:08:20.810
to read in the future.

00:08:20.810 --> 00:08:23.300
OK.

00:08:23.300 --> 00:08:26.150
So just like when we
talked about functions,

00:08:26.150 --> 00:08:28.250
we're going to sort
of separate the code

00:08:28.250 --> 00:08:34.460
that we talk about today into
code where you implement a data

00:08:34.460 --> 00:08:40.309
type and code where you use
an object that you create.

00:08:40.309 --> 00:08:40.850
OK?

00:08:40.850 --> 00:08:42.641
So remember when we
talked about functions,

00:08:42.641 --> 00:08:45.627
you were thinking about it in
terms of writing a function,

00:08:45.627 --> 00:08:47.460
so you had to worry
about the details of how

00:08:47.460 --> 00:08:49.100
you implement a function.

00:08:49.100 --> 00:08:50.750
And then you had
to worry about just

00:08:50.750 --> 00:08:52.140
how to use a function, right?

00:08:52.140 --> 00:08:55.630
So it's sort of the
same idea today.

00:08:55.630 --> 00:09:00.810
So when you're thinking about
implementing your own data

00:09:00.810 --> 00:09:04.750
type, you do that with
this thing called a class.

00:09:08.500 --> 00:09:10.450
And when you create
a class, you're

00:09:10.450 --> 00:09:12.270
basically going to
figure out what name you

00:09:12.270 --> 00:09:13.900
want to give your
class and you're

00:09:13.900 --> 00:09:16.056
going to find some attributes.

00:09:16.056 --> 00:09:17.680
And attributes are
going to be the data

00:09:17.680 --> 00:09:21.864
representation and ways that you
can interact with your object.

00:09:21.864 --> 00:09:23.530
So you, as the
programmer of this class,

00:09:23.530 --> 00:09:25.600
are going to decide
how you want people

00:09:25.600 --> 00:09:29.780
to interact with the object
and what data this object

00:09:29.780 --> 00:09:32.860
is going to have.

00:09:32.860 --> 00:09:35.280
So for example,
someone wrote code

00:09:35.280 --> 00:09:37.380
that implements a
list class, right,

00:09:37.380 --> 00:09:39.870
and we don't actually
know how that was done.

00:09:39.870 --> 00:09:43.180
But we can find out.

00:09:43.180 --> 00:09:47.710
So creating the class is
implementing the class

00:09:47.710 --> 00:09:49.690
and figuring out data
representation and ways

00:09:49.690 --> 00:09:52.270
to interact with the class.

00:09:52.270 --> 00:09:55.570
Once that's done, you
can then use your class.

00:09:55.570 --> 00:09:57.910
And you use the
class by creating

00:09:57.910 --> 00:10:02.164
new instances of the class.

00:10:02.164 --> 00:10:03.580
So when you create
a new instance,

00:10:03.580 --> 00:10:05.710
you essentially
create a new object

00:10:05.710 --> 00:10:09.430
that has the type, the
name of your class.

00:10:09.430 --> 00:10:11.560
And you can create as many
objects as you'd like.

00:10:11.560 --> 00:10:14.380
You can do all the
operations that you've

00:10:14.380 --> 00:10:16.660
defined on the class.

00:10:16.660 --> 00:10:18.655
So for example,
someone wrote the code

00:10:18.655 --> 00:10:20.530
to implement list class
and then you can just

00:10:20.530 --> 00:10:21.920
use the list class like this.

00:10:21.920 --> 00:10:25.330
You can create a new list, you
can get the length pf the list,

00:10:25.330 --> 00:10:28.320
you can append to the end of
the list, and so on and so on.

00:10:33.550 --> 00:10:37.840
So let's start defining
our own types, OK?

00:10:37.840 --> 00:10:39.802
So now you're going
to define classes,

00:10:39.802 --> 00:10:41.260
you're going to
write classes which

00:10:41.260 --> 00:10:45.660
are going to define your
own types of objects.

00:10:45.660 --> 00:10:47.750
So for today's
lecture we're going

00:10:47.750 --> 00:10:50.240
to look at code
that's going to be

00:10:50.240 --> 00:10:53.210
in the context of a
coordinate object.

00:10:53.210 --> 00:10:54.860
And a coordinate
object is essentially

00:10:54.860 --> 00:11:02.980
going to be an object
that's going to define

00:11:02.980 --> 00:11:07.400
a point in an xy plane.

00:11:07.400 --> 00:11:12.052
So x, y is going to be a
coordinate in a 2D plane.

00:11:12.052 --> 00:11:13.510
So we're going to
write code that's

00:11:13.510 --> 00:11:15.885
going to allow us to
define that kind of object.

00:11:18.830 --> 00:11:22.804
So the way we do that is
we have to define a class.

00:11:22.804 --> 00:11:25.220
So we have to tell Python,
hey, I'm defining my own object

00:11:25.220 --> 00:11:26.270
type.

00:11:26.270 --> 00:11:28.070
So you do that with
this class key word.

00:11:28.070 --> 00:11:31.880
So you say class, then you
say the name of your type.

00:11:31.880 --> 00:11:34.460
In this case, we're creating
a type called coordinate.

00:11:34.460 --> 00:11:37.170
Just like we had type list,
type string, and so on.

00:11:37.170 --> 00:11:40.620
This is going to be a
type called coordinate.

00:11:40.620 --> 00:11:42.120
And then in
parentheses here, you

00:11:42.120 --> 00:11:44.490
put what the parents
of the class are.

00:11:44.490 --> 00:11:48.590
For today's lecture, the
parent of the classes

00:11:48.590 --> 00:11:50.480
are going to be this
thing called object,

00:11:50.480 --> 00:11:56.180
and object is the very
basic type in Python.

00:11:56.180 --> 00:11:58.250
It is the most basic
type in Python.

00:11:58.250 --> 00:12:02.210
And it implements things like
being able to assign variables.

00:12:02.210 --> 00:12:03.980
So really, really
basic operations

00:12:03.980 --> 00:12:06.740
that you can do with objects.

00:12:06.740 --> 00:12:08.330
So your coordinate
is therefore going

00:12:08.330 --> 00:12:09.945
to be an object in Python.

00:12:12.630 --> 00:12:13.130
All right.

00:12:13.130 --> 00:12:16.580
So we've told Python we
wanted to define an object.

00:12:16.580 --> 00:12:19.470
So inside the class definition
we're going to put attributes.

00:12:19.470 --> 00:12:21.820
So what are attributes?

00:12:21.820 --> 00:12:24.610
Attributes are going to be
data and procedures that

00:12:24.610 --> 00:12:27.000
belong to the class, OK?

00:12:27.000 --> 00:12:29.950
Data are going to be the data
representations and procedures

00:12:29.950 --> 00:12:33.630
are going to be ways that we
can interact with the object.

00:12:33.630 --> 00:12:35.910
The fact that they
belong to the class

00:12:35.910 --> 00:12:38.670
means that the data and the
procedures that we write

00:12:38.670 --> 00:12:41.490
are only going to work with
an object of this type.

00:12:41.490 --> 00:12:42.270
OK.

00:12:42.270 --> 00:12:45.102
If you try to use any of
the data or the procedures

00:12:45.102 --> 00:12:46.560
with an object of
a different type,

00:12:46.560 --> 00:12:51.030
you're going to get an
error because these data

00:12:51.030 --> 00:12:56.880
and these attributes will
belong to this particular class.

00:12:59.410 --> 00:13:04.810
So the data attributes is,
what is the object, right?

00:13:04.810 --> 00:13:07.490
What is the data that
makes up the object?

00:13:07.490 --> 00:13:09.220
So for our coordinate
example, it's

00:13:09.220 --> 00:13:12.424
going to be the x and y
values for coordinate.

00:13:12.424 --> 00:13:13.840
We can decide that
can be ints, we

00:13:13.840 --> 00:13:15.910
can decide that we can
let them be floats,

00:13:15.910 --> 00:13:19.000
but it's going to have one
value for the x-coordinate

00:13:19.000 --> 00:13:20.757
and one value for
the y-coordinate.

00:13:23.960 --> 00:13:25.680
So those are data attributes.

00:13:25.680 --> 00:13:29.610
And procedure attributes
are better known as methods.

00:13:29.610 --> 00:13:32.089
And you can think of a
method as a function.

00:13:32.089 --> 00:13:33.630
Except that it's a
function that only

00:13:33.630 --> 00:13:37.330
works with this
particular type of object.

00:13:37.330 --> 00:13:40.910
So with a coordinate
object, in this case.

00:13:40.910 --> 00:13:42.660
So the methods are
going to define how you

00:13:42.660 --> 00:13:44.100
can interact with the object.

00:13:44.100 --> 00:13:45.875
So in a list, for
example, we've said

00:13:45.875 --> 00:13:48.000
that you can append an item
to the end of the list,

00:13:48.000 --> 00:13:50.520
we can sort a list,
things like that.

00:13:50.520 --> 00:13:52.590
So when you're defining
methods, you're

00:13:52.590 --> 00:13:55.120
defining ways that people can
interact with your object.

00:13:55.120 --> 00:13:56.800
So for example, for
a coordinate object,

00:13:56.800 --> 00:13:59.190
we can say that we can take
the distance between two

00:13:59.190 --> 00:14:00.650
coordinate points.

00:14:00.650 --> 00:14:01.380
OK?

00:14:01.380 --> 00:14:03.463
And that's going to be a
way that you can interact

00:14:03.463 --> 00:14:06.360
with two coordinate points.

00:14:06.360 --> 00:14:09.630
And just to be clear,
these are going

00:14:09.630 --> 00:14:11.130
to belong to this
class, which means

00:14:11.130 --> 00:14:14.310
that if you try to use this
distance method on two lists,

00:14:14.310 --> 00:14:16.140
for example, you're
going to get an error.

00:14:16.140 --> 00:14:19.260
Because this distance method was
only defined to work with two

00:14:19.260 --> 00:14:20.531
coordinate type objects.

00:14:23.120 --> 00:14:26.680
All right, so let's
carry on and continue

00:14:26.680 --> 00:14:28.750
implementing our class.

00:14:28.750 --> 00:14:31.300
So we've written this
first line so far,

00:14:31.300 --> 00:14:32.640
class coordinate object.

00:14:32.640 --> 00:14:35.740
So now let's define attributes.

00:14:35.740 --> 00:14:39.640
First thing we're going to
define are data attributes.

00:14:39.640 --> 00:14:44.720
Generally you define data
attributes inside this init,

00:14:44.720 --> 00:14:47.200
and this is underscore,
underscore, init, underscore,

00:14:47.200 --> 00:14:52.510
underscore, and it's a special
method or function in a class.

00:14:52.510 --> 00:14:55.997
And the special
method tells Python,

00:14:55.997 --> 00:14:57.580
when you implement
the special method,

00:14:57.580 --> 00:15:00.940
it tells Python when you first
create an object of this type,

00:15:00.940 --> 00:15:03.010
call this method or
call this function.

00:15:06.470 --> 00:15:08.080
So how do we do that?

00:15:08.080 --> 00:15:09.760
So let's implement it.

00:15:09.760 --> 00:15:14.290
So we say df because
it's just a function.

00:15:14.290 --> 00:15:17.590
The name is the
special name, init.

00:15:17.590 --> 00:15:19.390
And we give it some
parameters, right,

00:15:19.390 --> 00:15:22.680
just like any other function.

00:15:22.680 --> 00:15:26.250
These last two
parameters are x and y,

00:15:26.250 --> 00:15:31.340
which are going to represent how
you create a coordinate object.

00:15:31.340 --> 00:15:33.300
So you give it a value
for the x-coordinate

00:15:33.300 --> 00:15:36.320
and you give it a value
for the y-coordinate.

00:15:36.320 --> 00:15:39.550
The self, however, is
a little bit trickier.

00:15:39.550 --> 00:15:42.090
So the self is going
to be a parameter when

00:15:42.090 --> 00:15:44.880
you define this
class that represents

00:15:44.880 --> 00:15:49.830
a particular instance
of the class.

00:15:49.830 --> 00:15:52.500
So we're defining
this coordinate object

00:15:52.500 --> 00:15:54.540
in sort of a general way, right?

00:15:54.540 --> 00:15:56.670
We don't have a
specific instance

00:15:56.670 --> 00:15:59.850
yet because we haven't
created an object yet.

00:15:59.850 --> 00:16:02.010
But this self is
going to be sort

00:16:02.010 --> 00:16:04.830
of a placeholder for
any sort of instance

00:16:04.830 --> 00:16:07.810
when you create the object.

00:16:07.810 --> 00:16:10.320
So in the definition
of the class,

00:16:10.320 --> 00:16:12.270
whenever you want to
refer to attributes

00:16:12.270 --> 00:16:17.530
that belong to an instance,
you have to use self dot.

00:16:17.530 --> 00:16:19.330
So this dot notation.

00:16:19.330 --> 00:16:26.230
And the dot is going to say
look for a data attribute

00:16:26.230 --> 00:16:28.420
x that belongs to this class.

00:16:31.240 --> 00:16:34.050
So for methods that
belong to the class,

00:16:34.050 --> 00:16:37.314
the first parameter is
always going to be self.

00:16:37.314 --> 00:16:38.730
It can be named
anything you want,

00:16:38.730 --> 00:16:41.790
but really by convention
it's always named self.

00:16:41.790 --> 00:16:44.280
So try to stick to that.

00:16:44.280 --> 00:16:46.170
And then any other
parameters beyond it

00:16:46.170 --> 00:16:47.910
are going to be just
parameters as you

00:16:47.910 --> 00:16:51.190
would put in a normal function.

00:16:51.190 --> 00:16:51.871
OK.

00:16:51.871 --> 00:16:53.370
In this particular
case, we're going

00:16:53.370 --> 00:16:56.340
to choose to initialize
a coordinate object

00:16:56.340 --> 00:17:00.810
by two values, one for
the x and one for the y.

00:17:00.810 --> 00:17:03.690
And inside this
init method, we're

00:17:03.690 --> 00:17:07.839
going to have two assignments.

00:17:07.839 --> 00:17:11.579
The first one says,
the x data attribute

00:17:11.579 --> 00:17:12.990
of a coordinate object.

00:17:12.990 --> 00:17:17.589
I'm going to assign it to
whatever was passed in.

00:17:17.589 --> 00:17:20.609
And the y data attribute
for a particular object

00:17:20.609 --> 00:17:23.520
is going to be assigned
whatever y was passed in.

00:17:30.420 --> 00:17:34.150
Questions so far about
how to write this init?

00:17:34.150 --> 00:17:35.000
Yeah, question.

00:17:35.000 --> 00:17:35.970
AUDIENCE: [INAUDIBLE]

00:17:40.597 --> 00:17:42.430
PROFESSOR: How do you
make sure that x and y

00:17:42.430 --> 00:17:44.010
are inits or floats?

00:17:44.010 --> 00:17:45.700
So this is something
that you could

00:17:45.700 --> 00:17:48.370
write in the specifications,
so the docstring

00:17:48.370 --> 00:17:49.570
with the triple quotes.

00:17:49.570 --> 00:17:52.900
So whoever uses the
class would then

00:17:52.900 --> 00:17:55.930
know that if they do something
outside the specification,

00:17:55.930 --> 00:17:58.060
the code might not
work as expected.

00:17:58.060 --> 00:18:00.340
Or you could put
in a cert statement

00:18:00.340 --> 00:18:03.880
inside the definition
of the init just

00:18:03.880 --> 00:18:06.530
to sort of force that.

00:18:06.530 --> 00:18:08.470
Force that to be true.

00:18:08.470 --> 00:18:09.195
Great question.

00:18:09.195 --> 00:18:09.820
Yeah, question.

00:18:09.820 --> 00:18:10.760
AUDIENCE: [INAUDIBLE]

00:18:14.520 --> 00:18:16.839
PROFESSOR: Does the x,
does this self x and this x

00:18:16.839 --> 00:18:17.880
have to be the same name.

00:18:17.880 --> 00:18:19.710
The answer is no.

00:18:19.710 --> 00:18:22.260
And we're going to
see in class exercise

00:18:22.260 --> 00:18:24.160
that you can have
it be different.

00:18:27.030 --> 00:18:28.050
OK.

00:18:28.050 --> 00:18:28.740
Great.

00:18:28.740 --> 00:18:34.260
So this defines the way
that we create an object.

00:18:34.260 --> 00:18:39.120
So now we have sort
of a nice class.

00:18:39.120 --> 00:18:41.490
It's very simple, but
we can start actually

00:18:41.490 --> 00:18:43.897
creating coordinate objects.

00:18:43.897 --> 00:18:45.480
So when you create
coordinate objects,

00:18:45.480 --> 00:18:48.930
you're creating
instances of the class.

00:18:48.930 --> 00:18:52.440
So this line here, C is
equal to coordinate 3,4,

00:18:52.440 --> 00:18:55.240
is going to call
the init method.

00:18:55.240 --> 00:18:58.180
It's going to call the init
method with x is equal to 3

00:18:58.180 --> 00:18:59.380
and y is equal to 4.

00:19:01.940 --> 00:19:07.190
I'm just going to go over here
and I wrote this previously,

00:19:07.190 --> 00:19:13.980
because notice when we're
creating an object here,

00:19:13.980 --> 00:19:16.890
we're only giving
it two parameters.

00:19:16.890 --> 00:19:20.190
But in the init method, we
have actually three parameters,

00:19:20.190 --> 00:19:21.060
right?

00:19:21.060 --> 00:19:22.894
We have these three
parameters here,

00:19:22.894 --> 00:19:24.310
but when we're
creating an object,

00:19:24.310 --> 00:19:25.950
we only give it two parameters.

00:19:25.950 --> 00:19:28.600
And that's OK because
implicitly, Python

00:19:28.600 --> 00:19:31.830
is going to say self is going
to be this object C, so just

00:19:31.830 --> 00:19:33.317
by default, OK?

00:19:33.317 --> 00:19:35.150
So when you're creating
a coordinate object,

00:19:35.150 --> 00:19:40.260
you're passing it all the
variables except for self.

00:19:44.930 --> 00:19:47.350
So this line here is
going to call the init

00:19:47.350 --> 00:19:49.740
and it's going to do every
line inside the init.

00:19:49.740 --> 00:19:54.650
So it's going to create
an x data attribute for C,

00:19:54.650 --> 00:19:56.930
a y data attribute
for C, and it's

00:19:56.930 --> 00:20:01.800
going to assign 3 and 4
to those respectively.

00:20:01.800 --> 00:20:05.300
This next line here is
origin equals coordinate 0,

00:20:05.300 --> 00:20:08.810
0 creates another object.

00:20:08.810 --> 00:20:10.170
OK?

00:20:10.170 --> 00:20:13.770
It's another coordinate
object whose value for x is 0

00:20:13.770 --> 00:20:16.200
and whose value for y is 0.

00:20:16.200 --> 00:20:19.210
So now we have two
coordinate objects.

00:20:19.210 --> 00:20:21.540
We can access the
data attributes

00:20:21.540 --> 00:20:24.852
using this dot notation and
we've seen that before, right?

00:20:24.852 --> 00:20:27.060
When we've worked with lists
we'd say something like,

00:20:27.060 --> 00:20:30.130
L dot append, right,
when we create a list.

00:20:30.130 --> 00:20:34.830
So the same dot notation can
be used with your own objects

00:20:34.830 --> 00:20:37.350
in order to access
data attributes.

00:20:37.350 --> 00:20:39.720
So here, this is
going to print 3

00:20:39.720 --> 00:20:47.180
because the x value
for object C is 3,

00:20:47.180 --> 00:20:49.100
and the next line,
print origin x

00:20:49.100 --> 00:20:53.150
is going to print 0 because the
x value for the object origin

00:20:53.150 --> 00:20:54.830
is 0.

00:20:54.830 --> 00:20:55.780
OK.

00:20:55.780 --> 00:20:59.450
So we've created a
coordinate object.

00:20:59.450 --> 00:21:01.060
We have to find the
init method so we

00:21:01.060 --> 00:21:05.210
have a way to create objects
when we use the class.

00:21:05.210 --> 00:21:08.260
And then we can access
the data attributes.

00:21:08.260 --> 00:21:11.530
But that's kind of lame, right,
because there isn't anything

00:21:11.530 --> 00:21:12.560
cool we can do with it.

00:21:12.560 --> 00:21:15.790
There isn't ways to
interact with this object.

00:21:15.790 --> 00:21:17.770
So let's add some methods.

00:21:17.770 --> 00:21:21.670
Remember methods are going to
be procedural attributes that

00:21:21.670 --> 00:21:25.030
allow us to interact
with our object.

00:21:25.030 --> 00:21:27.880
Methods are like functions
except that there's

00:21:27.880 --> 00:21:30.790
a couple of differences
which you'll see in a moment.

00:21:30.790 --> 00:21:33.790
And when you're
calling methods, you're

00:21:33.790 --> 00:21:38.380
using the dot operator, like
L dot append, for example,

00:21:38.380 --> 00:21:38.920
for lists.

00:21:41.810 --> 00:21:45.650
So let's go back to defining
our coordinate class

00:21:45.650 --> 00:21:48.240
and let's define
a method for it.

00:21:48.240 --> 00:21:50.910
So so far we've defined
that part there,

00:21:50.910 --> 00:21:52.440
class coordinate and an init.

00:21:52.440 --> 00:21:53.790
So we have that.

00:21:53.790 --> 00:21:58.160
So in this slide we're going
to add this method here.

00:21:58.160 --> 00:21:59.930
So this method here
is going to say

00:21:59.930 --> 00:22:04.280
I'm going to define a
method called distance

00:22:04.280 --> 00:22:06.170
and I'm going to pass
in two parameters.

00:22:06.170 --> 00:22:08.720
Remember self, the
first parameter,

00:22:08.720 --> 00:22:11.330
is always going to be
the instance of an object

00:22:11.330 --> 00:22:14.740
that you're going to
perform the operation on.

00:22:14.740 --> 00:22:19.630
So pretty much by convention
it's always named self.

00:22:22.700 --> 00:22:25.010
And then for this
particular method,

00:22:25.010 --> 00:22:26.990
I'm going to give it
another parameter,

00:22:26.990 --> 00:22:29.410
and I can name this
whatever I want.

00:22:29.410 --> 00:22:31.110
I'm naming it other.

00:22:31.110 --> 00:22:34.190
And this is going to represent
the other coordinate object

00:22:34.190 --> 00:22:38.142
for which I want to find
the distance from my self.

00:22:38.142 --> 00:22:39.600
So here I'm going
to just implement

00:22:39.600 --> 00:22:46.320
the Euclidean distance formula,
which is x1 minus x2 squared,

00:22:46.320 --> 00:22:50.750
plus Y1 minus Y2 squared,
and square root of all that.

00:22:50.750 --> 00:22:54.370
So that's what I'm
doing inside here.

00:22:54.370 --> 00:22:56.255
Self and other are
coordinate objects.

00:22:59.150 --> 00:23:04.940
Inside this method, I have
to refer to the x data

00:23:04.940 --> 00:23:06.890
attributes of each
object if I want

00:23:06.890 --> 00:23:11.220
to find the difference between
the 2x values from them.

00:23:11.220 --> 00:23:14.270
So that's why I'm doing
self dot x here, right.

00:23:14.270 --> 00:23:17.240
If I just did x, I would be
accessing just some variable

00:23:17.240 --> 00:23:22.250
named x in a program which
actually isn't even defined.

00:23:22.250 --> 00:23:26.984
So you always have to
refer when as we're

00:23:26.984 --> 00:23:28.400
thinking about
classes, you always

00:23:28.400 --> 00:23:30.770
have to refer to
whose data attribute

00:23:30.770 --> 00:23:32.870
do you want to access?

00:23:32.870 --> 00:23:35.000
In this case, I want
to access the x data

00:23:35.000 --> 00:23:38.840
attribute of my self, and I
want to subtract the x data

00:23:38.840 --> 00:23:41.270
attribute of this
other coordinate,

00:23:41.270 --> 00:23:45.740
square that, same for y,
square that, and then add those

00:23:45.740 --> 00:23:48.320
and take the square
root of that.

00:23:48.320 --> 00:23:51.110
So notice this method is pretty
much like a function, right?

00:23:51.110 --> 00:23:54.830
You have DF, some name,
it takes in parameters.

00:23:54.830 --> 00:23:57.920
It does some stuff and
then it returns a value.

00:23:57.920 --> 00:24:01.270
The only difference is the
fact that you have a self here

00:24:01.270 --> 00:24:04.850
as the first thing and
the fact that you always

00:24:04.850 --> 00:24:07.760
have to be conscious about
whose data attributes

00:24:07.760 --> 00:24:08.510
you're accessing.

00:24:12.140 --> 00:24:14.080
So you have to use the
dot notation in order

00:24:14.080 --> 00:24:17.840
to decide whose data
attributes you want access.

00:24:17.840 --> 00:24:21.222
So we've defined the
method here, distance.

00:24:21.222 --> 00:24:22.680
So this is in the
class definition.

00:24:22.680 --> 00:24:25.170
Now how do we use it?

00:24:25.170 --> 00:24:28.120
So let's assume that the
definition of distance

00:24:28.120 --> 00:24:29.000
is up here.

00:24:29.000 --> 00:24:32.320
I didn't include the code.

00:24:32.320 --> 00:24:34.560
But really all you need
to know is what it takes.

00:24:34.560 --> 00:24:37.060
It takes a self and an other.

00:24:37.060 --> 00:24:39.490
So when you want
to use this method

00:24:39.490 --> 00:24:42.130
to figure out a distance
between two coordinate objects,

00:24:42.130 --> 00:24:43.490
this is how you do it.

00:24:43.490 --> 00:24:47.110
So the first line, I create
one coordinate object.

00:24:47.110 --> 00:24:50.320
Second line, I create
another coordinate object.

00:24:50.320 --> 00:24:52.630
First one is named C, the
second one is named 0.

00:24:52.630 --> 00:24:55.890
These are two separate objects.

00:24:55.890 --> 00:25:00.410
And I'm going to
find the distance.

00:25:00.410 --> 00:25:03.400
And I want to first
call it on one object,

00:25:03.400 --> 00:25:07.340
so I'm going to say C dot,
so I'm using the dot notation

00:25:07.340 --> 00:25:14.740
to call the method
distance on object C.

00:25:14.740 --> 00:25:18.124
So Python says this object
C is of type coordinate.

00:25:18.124 --> 00:25:19.540
It's going to look
up at the class

00:25:19.540 --> 00:25:20.770
coordinate that you defined.

00:25:20.770 --> 00:25:23.350
It's going to find this
method called distance

00:25:23.350 --> 00:25:26.290
and then it's going to say
what parameters does it take?

00:25:26.290 --> 00:25:29.620
So it takes another parameter,
right, for the other

00:25:29.620 --> 00:25:31.690
and then, in the
parentheses, I just

00:25:31.690 --> 00:25:35.590
have to give it this
other perimeter.

00:25:35.590 --> 00:25:37.870
An easier way to
see what happens

00:25:37.870 --> 00:25:42.910
is by looking at what this
line here is equivalent to.

00:25:46.000 --> 00:25:48.560
So the third line
here prints C dot

00:25:48.560 --> 00:25:51.659
distance 0 is equivalent
to this one on the right.

00:25:51.659 --> 00:25:53.200
And this one on the
right essentially

00:25:53.200 --> 00:25:57.620
says, what's the
name of the class,

00:25:57.620 --> 00:26:01.680
dot, dot notation, what's
the method you want to call,

00:26:01.680 --> 00:26:03.900
and then in
parentheses you give it

00:26:03.900 --> 00:26:06.330
all of the variables
including self.

00:26:06.330 --> 00:26:06.930
OK.

00:26:06.930 --> 00:26:09.750
So in this case you're
explicitly telling Python

00:26:09.750 --> 00:26:16.030
that self is C and other is 0.

00:26:16.030 --> 00:26:22.080
So this is a little bit easier
to understand, like that.

00:26:22.080 --> 00:26:25.320
But it's a little cumbersome
because you always

00:26:25.320 --> 00:26:27.900
have to write coordinate dot,
coordinate dot, coordinate dot,

00:26:27.900 --> 00:26:29.525
for every data
attribute you might want

00:26:29.525 --> 00:26:31.630
to access, for every
procedural attribute you

00:26:31.630 --> 00:26:34.110
might want to access.

00:26:34.110 --> 00:26:36.960
So by convention,
it's a lot easier

00:26:36.960 --> 00:26:40.010
to do the one on the left.

00:26:40.010 --> 00:26:42.860
And as I mentioned,
Python implicitly says,

00:26:42.860 --> 00:26:45.490
if you're doing the
one on the left,

00:26:45.490 --> 00:26:47.900
you can call this method
on a particular object

00:26:47.900 --> 00:26:49.900
and it's going to look
up the type of the object

00:26:49.900 --> 00:26:52.900
and it's going to essentially
convert this on the left

00:26:52.900 --> 00:26:54.841
to the one on the right.

00:26:54.841 --> 00:26:56.590
And this is what you've
been using so far.

00:26:56.590 --> 00:26:59.620
So when you create a list,
you say L is equal to 1, 2,

00:26:59.620 --> 00:27:05.160
and then you say L.append,
you know, 3 or whatever.

00:27:05.160 --> 00:27:09.680
So we've been using this
notation on the left

00:27:09.680 --> 00:27:14.240
pretty much from the
beginning of class.

00:27:14.240 --> 00:27:17.280
So we have a
coordinate class, we

00:27:17.280 --> 00:27:19.110
can create a
coordinate object, we

00:27:19.110 --> 00:27:22.116
can get the distance
between two objects.

00:27:22.116 --> 00:27:23.490
As you're using
the class, if you

00:27:23.490 --> 00:27:25.860
wanted to use this
coordinate class,

00:27:25.860 --> 00:27:29.580
and you were maybe debugging
at some point, a lot of you

00:27:29.580 --> 00:27:32.160
probably use print as a
debug statement, right?

00:27:32.160 --> 00:27:37.799
And maybe you want to print the
value of a coordinate object.

00:27:37.799 --> 00:27:39.340
So if you create a
coordinate object,

00:27:39.340 --> 00:27:41.620
C is equal to
coordinate 3, 4, right?

00:27:41.620 --> 00:27:43.400
That's what we've done so far.

00:27:43.400 --> 00:27:48.100
If you print C, you
get this funny message.

00:27:48.100 --> 00:27:49.570
Very uninformative, right?

00:27:49.570 --> 00:27:53.800
It basically says, well,
C is an object of type

00:27:53.800 --> 00:28:00.289
coordinate at this memory
location in the computer.

00:28:00.289 --> 00:28:02.080
Which is not what you
wanted at all, right?

00:28:02.080 --> 00:28:04.990
Maybe you wanted to know what
the values for x and y were.

00:28:04.990 --> 00:28:08.190
That would be a lot
more informative.

00:28:08.190 --> 00:28:14.260
So by default, when you
create your own type, when

00:28:14.260 --> 00:28:15.820
you print the
object of that type,

00:28:15.820 --> 00:28:17.620
Python tells you this
sort of information

00:28:17.620 --> 00:28:19.670
which is not what you want.

00:28:19.670 --> 00:28:21.190
So what you need
to do is you need

00:28:21.190 --> 00:28:24.190
to define your own
method that tells

00:28:24.190 --> 00:28:27.460
Python what to do
when you call print

00:28:27.460 --> 00:28:31.000
on an object of this type.

00:28:31.000 --> 00:28:34.210
So this is going to be
a special method, just

00:28:34.210 --> 00:28:36.760
like init is, because
it starts and ends

00:28:36.760 --> 00:28:39.650
with double underscores.

00:28:39.650 --> 00:28:42.700
And the name of the method is
underscore, underscore, str,

00:28:42.700 --> 00:28:44.380
underscore, underscore.

00:28:44.380 --> 00:28:48.550
And if you define this method in
your class, that tells Python,

00:28:48.550 --> 00:28:51.010
hey, when you see a
print statement that's

00:28:51.010 --> 00:28:54.250
on an object of type
coordinate, call this method,

00:28:54.250 --> 00:28:58.750
look what it does, and do
everything that's inside it.

00:28:58.750 --> 00:29:02.440
And you can choose to make
it do whatever you want

00:29:02.440 --> 00:29:05.920
inside your definition of str.

00:29:05.920 --> 00:29:08.620
In this case, let's say when
we print a coordinate object,

00:29:08.620 --> 00:29:11.290
we're going to print its
x and y values surrounded

00:29:11.290 --> 00:29:13.120
by angle brackets.

00:29:13.120 --> 00:29:14.950
That seems reasonable, right?

00:29:14.950 --> 00:29:20.240
So then from now on when you
print coordinate objects,

00:29:20.240 --> 00:29:22.090
you're going to see
things like this, which

00:29:22.090 --> 00:29:25.660
is a lot more informative.

00:29:25.660 --> 00:29:27.630
So how do we define this?

00:29:27.630 --> 00:29:32.610
So so far we've defined
all that and the last part

00:29:32.610 --> 00:29:35.030
is going to be new.

00:29:35.030 --> 00:29:37.150
So we define the init
and the distance,

00:29:37.150 --> 00:29:38.335
and let's define this str.

00:29:42.170 --> 00:29:45.830
So underscore, underscore,
str, underscore, underscore, is

00:29:45.830 --> 00:29:47.770
a method.

00:29:47.770 --> 00:29:51.060
It's only going to take self
because you're just calling

00:29:51.060 --> 00:29:54.030
print on the object itself.

00:29:54.030 --> 00:29:57.550
There's no other
parameters to it.

00:29:57.550 --> 00:30:03.100
Str has to return a string,
and in this particular case,

00:30:03.100 --> 00:30:05.380
we're going to return
the string that's

00:30:05.380 --> 00:30:10.040
the angle brackets concatenated
with the x value of the object,

00:30:10.040 --> 00:30:13.360
self.x, concatenated
with a comma,

00:30:13.360 --> 00:30:17.080
concatenated with the y value
of this particular instance

00:30:17.080 --> 00:30:19.965
of an object, self.y,
and then concatenated

00:30:19.965 --> 00:30:20.965
with the angle brackets.

00:30:23.720 --> 00:30:26.510
So now any time you have
print on an object of type

00:30:26.510 --> 00:30:29.660
coordinate, you're going to
call this special method str,

00:30:29.660 --> 00:30:32.480
if it's implemented
in your code.

00:30:32.480 --> 00:30:33.230
Any questions?

00:30:37.570 --> 00:30:38.070
OK.

00:30:41.460 --> 00:30:46.235
So let's try to wrap our
head around types and classes

00:30:46.235 --> 00:30:47.526
because we've seen a lot today.

00:30:50.780 --> 00:30:54.240
Let's create a
coordinate object,

00:30:54.240 --> 00:31:00.290
assign it 3, 4, as we have been,
and assign it to variable C.

00:31:00.290 --> 00:31:04.760
We've implemented the str
method, so when we print C,

00:31:04.760 --> 00:31:07.430
it's going to print out this
nice three comma for our angle

00:31:07.430 --> 00:31:07.930
brackets.

00:31:11.140 --> 00:31:13.120
If we print the type
of C, this is actually

00:31:13.120 --> 00:31:17.550
going to give us class main
coordinate, which tells us

00:31:17.550 --> 00:31:27.770
that C is going to
be an object that

00:31:27.770 --> 00:31:30.564
is of type class coordinate.

00:31:33.370 --> 00:31:37.500
If we look at
coordinate as a class,

00:31:37.500 --> 00:31:40.320
if we print what coordinate is,
coordinate is a class, right?

00:31:40.320 --> 00:31:42.840
So this is what Python tells
us, if we print coordinate,

00:31:42.840 --> 00:31:46.730
it's a class named coordinate.

00:31:46.730 --> 00:31:48.480
And if we print the
type of a coordinate,

00:31:48.480 --> 00:31:50.400
well that's just
going to be a type.

00:31:50.400 --> 00:31:51.720
So class is going to be a type.

00:31:51.720 --> 00:31:53.428
So you're defining
the type of an object.

00:31:56.770 --> 00:32:01.950
If you'd like to figure out
whether a particular object is

00:32:01.950 --> 00:32:03.800
an instance of a
particular class,

00:32:03.800 --> 00:32:07.080
you use this special
function called is instance.

00:32:07.080 --> 00:32:10.320
So if you print is instance
C comma coordinate,

00:32:10.320 --> 00:32:13.710
this is going to print true
because C is an object that

00:32:13.710 --> 00:32:15.571
is of type coordinate.

00:32:23.430 --> 00:32:26.110
Couple more words on
these special operators.

00:32:26.110 --> 00:32:27.720
So these special
operators allow you

00:32:27.720 --> 00:32:31.770
to customize your classes which
can add some cool functionality

00:32:31.770 --> 00:32:33.410
to them.

00:32:33.410 --> 00:32:36.800
So these special
operators are going

00:32:36.800 --> 00:32:39.710
to be things like
addition, subtraction,

00:32:39.710 --> 00:32:42.140
using the equal equal sign,
greater than, less than,

00:32:42.140 --> 00:32:44.690
length and so on and so on.

00:32:44.690 --> 00:32:48.140
So just like str,
if you implement

00:32:48.140 --> 00:32:52.400
any of these in your classes,
this is going to tell Python.

00:32:52.400 --> 00:32:56.310
So for example, if we've
implemented this underscore,

00:32:56.310 --> 00:33:00.590
underscore, add, underscore,
underscore in our class,

00:33:00.590 --> 00:33:01.970
this is going to
tell Python when

00:33:01.970 --> 00:33:04.700
you use this plus operator
between two objects of type

00:33:04.700 --> 00:33:08.990
coordinate to call this method.

00:33:08.990 --> 00:33:10.850
If you have not
implemented this method

00:33:10.850 --> 00:33:13.070
and you try to add two
objects of type coordinate,

00:33:13.070 --> 00:33:15.110
you're going to get an error
because Python doesn't actually

00:33:15.110 --> 00:33:16.610
know right off
the bat how to add

00:33:16.610 --> 00:33:18.260
two coordinate objects, right?

00:33:18.260 --> 00:33:20.454
You have to tell
it how to do that.

00:33:20.454 --> 00:33:22.370
And you tell it how to
do that by implementing

00:33:22.370 --> 00:33:26.360
this special method.

00:33:26.360 --> 00:33:27.350
Same with subtract.

00:33:27.350 --> 00:33:28.550
Same with equals.

00:33:28.550 --> 00:33:31.740
So if you want to figure out
whether two objects are equal.

00:33:31.740 --> 00:33:35.180
And when you implement these
methods in your own class,

00:33:35.180 --> 00:33:39.204
you can decide exactly
what you want to do.

00:33:39.204 --> 00:33:41.370
So what happens when you
add two coordinate objects?

00:33:41.370 --> 00:33:43.849
Do you just add the x values,
do you just add the y values,

00:33:43.849 --> 00:33:45.390
do you get them both
together, do you

00:33:45.390 --> 00:33:48.210
do whatever you'd like to do.

00:33:48.210 --> 00:33:51.400
And then you document
what you've decided.

00:33:51.400 --> 00:33:54.256
So let's create a
fraction object.

00:33:54.256 --> 00:33:55.630
So we've looked
at coordinate, we

00:33:55.630 --> 00:33:58.400
saw sort of a higher
level car object.

00:33:58.400 --> 00:34:01.800
Let's look at a fraction object.

00:34:01.800 --> 00:34:04.800
Fraction object
is going to be, is

00:34:04.800 --> 00:34:09.159
going represent a number that's
going to be a numerator slash

00:34:09.159 --> 00:34:11.400
denominator.

00:34:11.400 --> 00:34:11.900
OK.

00:34:11.900 --> 00:34:14.130
So that's going to
be a fraction object.

00:34:14.130 --> 00:34:17.810
So the way I've decided to
internally represent a fraction

00:34:17.810 --> 00:34:20.810
object is with two numbers.

00:34:20.810 --> 00:34:24.020
And I've decided that I
will not let them be floats.

00:34:24.020 --> 00:34:29.710
They have to be integers,
hence the assert over here.

00:34:29.710 --> 00:34:31.750
So inside the init,
I've decided I'm

00:34:31.750 --> 00:34:37.719
going to represent my
fracture with two numbers, one

00:34:37.719 --> 00:34:41.880
for the numerator and
one for the denominator.

00:34:41.880 --> 00:34:43.460
So when I create
a fraction object,

00:34:43.460 --> 00:34:48.050
I'm going to pass in a
numerator and a denominator.

00:34:48.050 --> 00:34:51.050
And a particular
instance is going

00:34:51.050 --> 00:34:53.510
to have self dot
numerator and self dot

00:34:53.510 --> 00:34:55.780
denominator as its
data attributes

00:34:55.780 --> 00:34:59.995
and I'm assigning those to be
whatever's passed into my init.

00:35:03.250 --> 00:35:07.420
Since I plan on debugging this
code maybe possibly sometime

00:35:07.420 --> 00:35:10.900
in the future, I'm also
including an str method

00:35:10.900 --> 00:35:20.350
and the str method is going
to print a nice looking string

00:35:20.350 --> 00:35:22.750
that's going to represent
the numerator, and then

00:35:22.750 --> 00:35:26.566
a slash, and then
the denominator.

00:35:30.300 --> 00:35:33.650
And then I've also implemented
some other special methods.

00:35:33.650 --> 00:35:35.570
How do I add two fractions?

00:35:35.570 --> 00:35:38.180
How do I subtract two fractions?

00:35:38.180 --> 00:35:42.410
And how do I convert
a fraction to a float?

00:35:42.410 --> 00:35:44.120
The add and subtract
are almost the same,

00:35:44.120 --> 00:35:48.190
so let's look at the
add for the moment.

00:35:48.190 --> 00:35:49.450
How do we add two fractions?

00:35:52.520 --> 00:35:59.410
We're going to take self, which
is the instance of an object

00:35:59.410 --> 00:36:02.210
that I want to do
the add operation on,

00:36:02.210 --> 00:36:03.710
and we're going to
take other, which

00:36:03.710 --> 00:36:05.860
is the other
instance of an object

00:36:05.860 --> 00:36:09.130
that I want to do the
operation on, so the addition,

00:36:09.130 --> 00:36:11.350
and I'm going to
figure out the new top.

00:36:11.350 --> 00:36:15.160
So the new top of the
resulting fraction.

00:36:15.160 --> 00:36:20.110
So it's my numerator multiplied
by the other denominator

00:36:20.110 --> 00:36:24.010
plus my denominator multiplied
by the other numerator

00:36:24.010 --> 00:36:26.410
and then divided by the
multiplication of the two

00:36:26.410 --> 00:36:28.810
denominators.

00:36:28.810 --> 00:36:32.250
So the top is going to be that,
the bottom is going to be that.

00:36:32.250 --> 00:36:34.950
Notice that we're
using self dot, right?

00:36:34.950 --> 00:36:36.480
Once again, we're
trying to access

00:36:36.480 --> 00:36:39.430
the data attributes of
each different instance,

00:36:39.430 --> 00:36:42.760
right, of myself and the other
object that I'm working with.

00:36:42.760 --> 00:36:46.660
So that's why I have
to use self dot here.

00:36:46.660 --> 00:36:51.450
Once I figure out the top and
the bottom of the addition,

00:36:51.450 --> 00:36:55.130
I'm going to return,
and here notice I'm

00:36:55.130 --> 00:36:58.190
returning a fraction object.

00:36:58.190 --> 00:37:00.680
It's not a number, it's not
a float, it's not an integer.

00:37:00.680 --> 00:37:03.890
It's a new object that is of
the exact same type as the class

00:37:03.890 --> 00:37:07.140
that I'm implementing.

00:37:07.140 --> 00:37:10.410
So as it's the same
type of object,

00:37:10.410 --> 00:37:12.304
then on the return
value I can do

00:37:12.304 --> 00:37:14.220
all of the exact same
operations that I can do

00:37:14.220 --> 00:37:17.960
on a regular fraction object.

00:37:17.960 --> 00:37:19.587
Sub is going to be the same.

00:37:19.587 --> 00:37:20.920
I'm returning a fraction object.

00:37:24.250 --> 00:37:30.330
Float is just going to
do the division for me,

00:37:30.330 --> 00:37:31.860
so it's going to
take the numerator

00:37:31.860 --> 00:37:34.350
and then divide it
by the denominator,

00:37:34.350 --> 00:37:37.130
just divide the numbers.

00:37:37.130 --> 00:37:42.790
And then I'm defining here
my own method called inverse.

00:37:42.790 --> 00:37:45.580
And this is just going to take
the inverse of the instance I'm

00:37:45.580 --> 00:37:47.260
calling this method on.

00:37:47.260 --> 00:37:51.820
And so it's going to also return
a new fraction object that just

00:37:51.820 --> 00:37:53.830
has the denominator
as the top part

00:37:53.830 --> 00:37:55.531
and the numerator
as the bottom part.

00:37:58.900 --> 00:38:00.280
So then we have some code here.

00:38:00.280 --> 00:38:04.970
So that's how I implement
my fraction object.

00:38:04.970 --> 00:38:08.040
So now let's use it and
see what it gives us.

00:38:08.040 --> 00:38:09.290
A is equal to a fraction 1, 4.

00:38:20.940 --> 00:38:28.870
This is going to
be 1 over 4 for a.

00:38:28.870 --> 00:38:31.600
And b is going to
be 3 over four.

00:38:35.240 --> 00:38:41.400
When I do C, notice I'm using
the plus operator between two

00:38:41.400 --> 00:38:42.930
fraction objects, right?

00:38:42.930 --> 00:38:45.180
A and b are fraction
objects so Python's

00:38:45.180 --> 00:38:48.759
going to say, OK, is there an
underscore, underscore, add,

00:38:48.759 --> 00:38:50.550
underscore, underscore,
method implemented?

00:38:50.550 --> 00:38:54.730
It is and it's just going to
do whatever's inside here.

00:38:54.730 --> 00:38:56.980
So it's going to say self
dot numerator plus other dot

00:38:56.980 --> 00:38:57.962
denominator.

00:38:57.962 --> 00:38:59.920
It's going to calculate
the top and the bottom.

00:38:59.920 --> 00:39:01.656
It's going to turn a
new fraction object.

00:39:05.470 --> 00:39:27.100
So this is going to be 4 plus 12
divided by 16, and 16 over 16.

00:39:27.100 --> 00:39:29.800
So C as a fraction
object is going

00:39:29.800 --> 00:39:35.260
to be 16 for the numerator
and 16 for the denominator

00:39:35.260 --> 00:39:38.058
because it's a fraction object.

00:39:43.890 --> 00:39:46.290
If I print C, it should
print 16 over 16,

00:39:46.290 --> 00:39:50.760
so we can even run it,
so print 16 over 16.

00:39:50.760 --> 00:39:54.570
If I print floats C, so this
special method float here

00:39:54.570 --> 00:39:58.920
is going to say, is there a
method that converts a fraction

00:39:58.920 --> 00:40:00.090
to a float and there is.

00:40:00.090 --> 00:40:02.229
It's this one
implemented right here.

00:40:02.229 --> 00:40:04.770
So it's just going to divide
the two numbers, top and bottom,

00:40:04.770 --> 00:40:07.020
which gives me 1.

00:40:07.020 --> 00:40:10.720
So it's this one here and here.

00:40:10.720 --> 00:40:13.380
Notice I'm doing the
exact same method call,

00:40:13.380 --> 00:40:15.270
except I'm doing it
the other way where

00:40:15.270 --> 00:40:20.610
you type in the name of the
class, name of the method,

00:40:20.610 --> 00:40:22.350
and then what you're
calling it on,

00:40:22.350 --> 00:40:27.430
and this gives the exact
same value here, 1.0.

00:40:27.430 --> 00:40:30.640
And then here I'm calling
the method inverse

00:40:30.640 --> 00:40:36.850
on object B which is going to
invert 3 over 4 to be 4 over 3.

00:40:36.850 --> 00:40:39.040
And then I'm converting
it to a float

00:40:39.040 --> 00:40:40.420
and then I'm printing the value.

00:40:40.420 --> 00:40:43.350
So it gives me 1.33.

00:40:43.350 --> 00:40:50.820
So take a look at this
code in more detail

00:40:50.820 --> 00:40:54.060
and see if you can trace through
all of those different things

00:40:54.060 --> 00:40:57.560
and see if you can also write
your own new fraction objects.

00:40:57.560 --> 00:40:58.260
OK.

00:40:58.260 --> 00:41:00.360
So last slide.

00:41:00.360 --> 00:41:02.730
Power of object
oriented programming

00:41:02.730 --> 00:41:04.740
is that you can bundle
together objects that

00:41:04.740 --> 00:41:06.240
are of the exact same type.

00:41:06.240 --> 00:41:07.680
And all of these
objects are going

00:41:07.680 --> 00:41:09.720
to have the same
data representation

00:41:09.720 --> 00:41:13.030
and the same methods
that you can do on them.

00:41:13.030 --> 00:41:15.730
And ultimately, you're
going to be building

00:41:15.730 --> 00:41:17.240
these layers of abstraction.

00:41:17.240 --> 00:41:20.170
So you're going to be building
on a basic object type

00:41:20.170 --> 00:41:27.160
in Python, you're going to have
integer objects, float objects.

00:41:27.160 --> 00:41:30.106
On top of those, you can
create lists, dictionaries.

00:41:30.106 --> 00:41:31.480
And on top of
those, you can even

00:41:31.480 --> 00:41:37.080
create your own object types as
we saw in this lecture today.