[MUSIC PLAYING] CARTER ZENKE: Well, hello one and all, and welcome to our short on instance variables. In a prior short on defining classes, we saw a way to create a class or a template for a package, one what we called, in fact, package. And down below, we created several instances of that class of that template to present individual packages here. So notice on lines 11 and 12, I have here some code that defines for me two instances of this class that we called package. It's a bit like me creating a template for something called a package and down below creating two particular packages. Now, I did so as follows. I said down below that this first package has a number one. The sender was Alice. The recipient was Bob. And the weight here was 10. But what actually happens as we call some code on line 11? Well, we said we'd come back to these lines, 3 through 6 here. So let's take a look at exactly what's happening. Well, when I run some line of code, like on line 11, I again am creating some new instance of this class I've defined called package. And along the way, thanks to Python, this method called dunder init is called. Now, we said here that it takes as input self, which refers to the new instance of the class that we are creating. And it seems like what I'm doing here is taking in various inputs, like number, sender, recipient, and weight, and assigning them to various attributes or properties of this class, of this instance of the class here. So it turns out that each of these things, self.number, self.sender, and so on, are called instance variables. They're variables that belong to some instance of this class. And they are defined for me whenever I call package down below. So let's look at number, for instance. Number equals 1. Well, I'm now passing in to dunder init this argument, number, with the value 1. And what happens to that number 1? Well, it actually gets assigned as an instance variable within this instance of the class. So this instance here has a variable called number and so on for sender, recipient, and weight. But let's see this in action here. I'll come down below, and let me try to actually access these instance variables that I claim I set up on lines 3 through 6. Well, I could imagine, let's say, looping through every package that I have inside of this list of packages, maybe printing them out along the way. Well, to do so, I could use a for loop. I want to print for each package I have. So I'll say for package in the list of packages. And then I'll fill this in a little later. Notice first that package will first refer to the package on line 11 and then, on the next iteration, the package on line 12. So very simple here, let's start off by printing something. We could print the package as a whole, but I don't think we'd get a very good output. What I could do instead is try printing, in this case, something like the instance variable that we called number, just to start with, package.number. So if I want to access an instance variable, I can, in this case, refer to the individual instance of the class, package here, followed by dot, followed by the instance variable's name, just like we set up above, in this case, number. So if I try this-- I'll try Python of packages.py. Hit Enter. We'll see 1 and 2. But just to hammer this home, let me try instead 1 and 3 and now hopefully see 1 and 3. So it does seem, as I defined in dunder init, that the input to these various parameters of package, these arguments here, they actually get assigned as instance variables of each instance of my class. Now let's try accessing more and maybe printing these packages in a prettier way. So here I can do this. I could go back to the format I had before but now use a Python f string in the packages instance variables. I could say package and then package.number, just like this. If I were to run this, I could see package 1 and package 2, pretty good. What if I tried maybe the same format from before? I could try colon, and then I could enter in, let's say, the package's sender to package.recipient. And let's see what we see here. Python packages.py. Package 1, Alice to Bob. Package 2, Bob to Charlie. And this is all happening by accessing these instance variables that I set up in dunder init as well. Let's now add in the weight. I'll say comma package.weight. And we said the weight was, in this case, in kilograms. I'll go ahead and now try to run this again. I'll go ahead and go back to my terminal-- python of packages.py-- and we'll see a much prettier way of formatting these individual packages. In fact, we can get the benefits of the strings we saw, let's say, in the short on defining classes, which allows them to be more prettily printed. But we also get the benefits of this class here, this way of encapsulating information now using these things called instance variables. This then was our short on instance variables. And we'll see you next time.