Welcome back, everyone, to part two of our discussion of.
Let's get started actually coding and creating a class.
All right.
So here I am inside visual studio code.
Let's begin by understanding that in Python, everything is actually an object.
How can I prove this to you?
Well, I'm going to say that NUM is equal to 10, and I'm going to say print.
The type of NUM wear type is a built in function within Python that reports back the type of object
that you passed into it.
So if I save those changes and I run this code, I get back Class A. For an integer class, less changes
to be something like ten point three saved that change and run this and I see this as a float class
object and maybe less changes to be a string.
So we'll say 200, but it's around that in quotes.
Next, I run this and I can see this is class STR for string.
Now, clearly everything in Python is an object.
Now the question arises How do we get to define our own objects?
And that's where we have to use the class keyword and to come back here.
Let's go ahead and clear this out.
And let's begin by creating probably the simplest class possible.
I call the class keyword and then by convention classes are capitalized and follow camel casing.
So we're going to call this our sample class open and close parentheses.
And keep in mind that you don't technically need parentheses here.
You could also just say Colon, but I like open and close parentheses.
And I'll show you why.
Later on, we learn about inheritance.
But again, keep in mind, technically speaking, you don't need these parentheses here, which is why
sometimes you don't actually see this and documentation.
But moving along, what I'll do is I'll simply put pass.
So this is just a keyword in Python says Pass.
Don't do anything.
Essentially, this class does nothing except define itself as a sample class.
Let's make what's known as an instance of a class.
So I'm going to say now NUM is equal to an instance of sample.
So I say sample open, close parentheses.
And now let's print out the type of NUM.
Notice how similar this is what we just said previously.
Except this time, instead of calling this a float or integer or string, we're actually defining it
as our own user defined class.
Also, be very careful to note my indentation here.
Classes are kind of like functions in the sense that everything indented is part of the class.
Here I have this in line with the class call, and if you're confused, you can always use the collapse
method here to see what code is actually inside the class.
But now I saved this and I run this and I can see it says, Hey, this is class main.
The sample main is actually a reference to the fact that it's running within the same Python file that
it was defined then.
And then sample is just telling you this is an instance of the sample class.
All right.
So now we understand this idea that in Python, everything is an object, and I can use this class keyword
to actually define my own objects.
So what's next?
Well, we need to do is sometimes to find attributes.
So let me show you how to define attributes within a class.
What I'm going to do is here, inside class sample, I'm going to say.
And instantiation method, which is a method that gets run every time you create a new instance of an
object and it's thief underscore underscore I and I t underscore, underscore and keep in mind that
there's two sets of underscores on each side here.
Really common beginner mistake is that they only put one underscore and here what I'm going to do is
I'm going to pass in the self keyword.
The self keyword is this special keyword.
Technically speaking, it doesn't need to be self, but by convention, we always use self.
And this basically allows Python to understand that this particular method that we're creating and this
is a special one called in it for instantiation.
What's going to happen is when we actually create a instance of sample class, the self keyword is going
to allow me to actually refer to attributes of the class from any other method in that class.
So we're going to say self here and then I'm going to pass in one more parameter.
And let's go ahead and have this say something like name.
So now I can actually pass in a name upon creating an instance of sample class.
And then here we're going to say self-taught name is equal to name.
What I want to make clear here is if I'm attaching self-taught name to this particular variable, what
this does is it allows self but name to later on be used within any method that we end up creating within
the class name on this side without a self attached.
Basically, it refers to the fact that the user, upon creating a sample class, will have to provide
a name.
So let me show you what I mean by that.
I'm actually going to start calling this X just so we don't get confused with any numbers we pass in.
And if I just run this, I should expect to see an error.
So again, I have my class.
I created this instantiation method in it call and it says that you have to pass in some name parameter
and then it gets assigned to self that name attribute.
If you just run it like this, we should get an error and it says, Hey, type error in it is missing
one required positional argument called name.
So now you have to actually say a name here, and we have been super clear or explicit on what this
name actually is.
But let's just assume that they kind of want a string.
So I'll say that.
And now when I run this, I can see that it's still a class main that sample, but now it has this attribute.
And how can I actually access this attribute once this instance of the class is created?
Well, I could say print type X, but now I can also do the following I can say print x dot.
And then the name.
Say that.
Run this and now I get to see the result.
Jose, so now we understand that if I have an attribute as part of a class call, I use Dot and then
the attribute name and notice the similarity here we say in between saying the actual variable name,
variable name, dot name and then self that name.
So this syntax is reflective of what you're going to do after you instantiate that instance of the class.
In fact, let's start changing this.
So maybe we're trying to create a student class, so we're trying to organize a school.
And so I create this student class and a student could have a name, and maybe a student also has a
GPA.
And then I want to make sure that when they pass on that, I'm actually storing it to be part of an
attribute of the student.
So I can say salta GPA is equal to the GPA that's passed into the user.
So now I can actually then create instances of these objects.
For example, I'm going to create student one as equal to Jose and will be generous myself to give myself
a 4.0 GPA, whether or not that was actually true.
We'll leave it up to history to decide, and we're going to say Student two is equal to and I remember
sample's no longer the fine.
So I have to actually call this students.
Help me expand our space here a little bit so you can see everything I'm doing.
So we have our student class now takes a name and GPA as attributes that are defined upon creating a
new student.
So Student one is named Jose GPA for Let's Create Another Student.
The name will be say me, me.
And this is going to be, let's say, three point five.
OK, so if you just create those students, nothing actually really happens here.
So if you're own Python, example that pi expanding this a little bit.
You can see we don't actually get any sort of output because I haven't printed anything.
So what I can do is let's go ahead and say print student one dot GPA.
Save that change.
Run this now I can see 4.0, and later on we'll actually discuss what actually happens if you want something
more displayed.
Because if I just say print stu one, I don't actually see name or it just says, Hey, this is a student
object at this point in memory.
This is not super useful.
So later on in the series of lectures, we will discuss how to create customization for what is printed
out.
But just keep that in mind.
If you actually print out an instance of an object, then you're going to see, Hey, this is a student
object at this point in memory at your computer.
So one thing to notice here is, unlike method calls, attributes are not actually called with parentheses.
So I just said, Stu, that name, I did not say name.
Open close parentheses.
Open close princes later on will be used when we actually create new methods for that class.
But right now, we can think of attributes as descriptors of an instance of the class, like a name
and a describe an instance of a student.
Now there may be something called a class object attribute, which is going to be an attribute that
should be the same regardless of the actual instance of the class.
So, for example, what would be true for any student at the school that maybe their name will be different,
but their GPA will also be different.
But I want something that's going to be true for any instance of a student.
So what could I do for something like that?
Maybe I could just say that all students are going to be human students.
So this is not a school for dogs.
So maybe I say something like species is equal to and then say human.
Or maybe they're all on planet Earth.
So I say, OK, for all these students, their planet is going to be Earth.
So what's kind of special to note here?
You should know that this is known as a class object attribute.
So this is a class object attribute and this is different than name and GPA here, which are just attributes.
So what's the difference?
The difference is for one.
This actually doesn't go inside the init call.
If you want an attribute that is going to be the same for every instance of an object you create.
You actually put it outside the init call.
The other thing you should know is it doesn't actually need self-talk.
Why does it not need self, but, well, notice that this is going outside of any of these method calls
that we're creating.
So hence, it's kind of obvious to Python that, yes, planet is associated with an instance of student.
It's not hidden within some sort of method.
And the reason self is here inside this method is to make sure you have the capability to connect these
user defined attributes to an attribute that you can later on use with an other method of calls.
So this is a class object attribute and not what happens when I save this code and I run this again.
I don't get any sort of error.
Remember student one, their name is Jose, but what I can also do is say student one now and ask for
what planet are they from?
Run this, and now I can see it's Earth.
Now here for student one, I didn't have to actually declare planet.
In fact, we should expect that we never have to declare planet because the whole point of a class object
attribute is that it's going to be the same for any instance of a students.
And again, you can always use the collapse mechanism here to give yourself a little more space to view
what the class has as far as attributes and methods.
OK, so that's pretty much it.
For this lecture, we created our first class, and along with that, we also created attributes.
What I'm going to do is just from scratch create another class of something kind of related to students
just to get us a little familiar with the idea of creating a class.
Let's imagine I'm creating a secret agent class, so I'm running the CIA or some sort of secret intelligence
agency.
And I want to create an agent class.
So I'm going to say class agent.
And maybe since I'm running this at our national organization, I know that the birth or place of origin
for all these agents is going to be United States or something like that.
So we're going to see Origin is USA.
So origin as USA, that means all these agents.
I'm going to say their origin is USA, regardless of what's actually passed it.
Then when I want to actually create an instance of an agent class automatically, the in its method
is going to be called.
So in that method is called upon creating an instance of agent.
So we pass in self so we can begin to assign attributes.
And then what else can we do here?
Well, I can say something like maybe the agents are going to have a name.
Maybe they have a height, and maybe they also have a weight or something like that.
Well.
What I do, then, is in order to accept these are these parameter calls and assign them as attributes
as I buy conventions say the same parameter name just with herself in front of it.
So if that name is name and then we're going to say soft that height.
Is height.
And then self thought, wait.
Is wait here.
OK, so here we have again, a very simple class.
Every instance of an agent is going to be Origin USA.
And then when you create an agent, you have to define their name, their height and their weight.
So we also think of this maybe as like a patient or something.
If I wanted to change the class, so now I'm going to create an instance of an agent so I can say X,
for instance, is equal to an instance of an agent.
I remember I need to define their name, their height and their weight.
So I could say something like Kosi weight or height two six and then weights is 170 or something like
that.
We're not worried too much about the metrics right now.
And then I can say prints.
X name, for instance.
Save that, and when you run this code, you should see now, Josie.
So he created an instance of an agent that I can now actually use.
Now I can also update the actual attributes.
So let's say the agent lost some weight.
I could say x dot weight is equal to 160 and then print out x that weight.
So this is one way of actually grabbing an attribute and then updating it just to prove to you that
the update works.
Before I update, I will print.
It's that way.
So notice what I'm doing, I'm initially defining Jose having weight 170, I print out that weight.
The uptake happens and then I print out the new updated weight.
So I start see 170 and then 160 to show that the update worked.
And there it is, 170 upon creation, and then later on, I updated it using one 60.
So clearly there's this idea of I'm able to grab attributes, report them, and I can also update attributes.
Keep in mind, we shouldn't really keep keeping the effect of updating class object attributes.
That's not really what they're there for.
So that is the basics of creating a class.
The instantiation method that can then allow us to define attributes.
Coming up next, we're going to learn about methods which are essentially functions defined inside the
body of a class.
And then it's going to make a lot more sense why we can use things like self that name instead of just
name.
OK, I'll see you at the next lecture.