 In this video, we're going to see another application, another typical application of the tuple data type. So previously, I told you that tuples are like immutable lists, so whenever you use a list, but you don't need immutability, I suggested that you would use a tuple instead, because this forces you to write code that doesn't change the value of a tuple. But there's a second view of how we want to use tuples, and that is that of a so-called record of data. So let me give you an example, and then you will easily understand that. So tuples as records is what we call the file. So suppose the following. You have two values, two independent values that have to be modeled together all the time to constitute some meaning. So for example, think of a Cartesian plane, so an x and y coordinate. So a point in a Cartesian plane usually is known by its coordinates like an x and y coordinate, right? So given only one of them, you don't know what the point is, so it doesn't make sense to view a point as only one number. It has to be two numbers. So let's say a point in the Cartesian plane, how can you model that? Well, obviously we call it x and y in math, but how could you model that in Python with what you have learned so far? Well, one way would be to use, for example, a list. So let's say if I want to model a point, let's say as an example, the point 1, 2. That is the point you want to model as a Python product, as a Python object. We could write that as a list object with 1, 2 in it, for example. That could be a point. However, I told you that it's not such a good idea to use something that can be mutated if you don't plan on mutating it. So if a point is, let's say, a position 1, 2, and you know for sure that you don't want to change the coordinates because every point has unique coordinates that don't change throughout its lifetime, then probably it's a better way to use a tuple. So let's say 1, 2 would also be a nice model of this point, and also it looks kind of like a tuple because in math notation, when you write a tuple, we usually use parentheses. So why not make Python code look like math? Well, that's a false friend. You should not model something a certain way just because it looks nice. There should be some other reasoning behind that. So let's assume the following. We know that this view of a data point as a collection of fields, this is what we call a record. So maybe let's summarize that here. It's like an important idea. So a collection of so-called, let's call it fields is a record. Now, where do these fields and records appear most often? So how can you think of them in real life? So another example would be, let's say, think of an Excel file that I have for my course and in the Excel file every row is a student. And I may have a column, let's say, for your first name. And then I have another column for the student's last names. And I have another column for the student's age and so on and the grades and whatever. So in this Excel file or CSV file, every row is a record, a record of a student. That is another example of what a record is. So let's first take the example of the Cartesian plane here and then also make a second example of modeling students in a class. So we agree that a record is a collection of independent, otherwise independent fields that only together make sense. And let's assume we don't want to change them. If we later on want to also change the values of a record throughout its lifetime, then you have to wait until chapter 11 classes because that is a good application of object orientation. But for now, let's simply assume we want to model records that we don't want to change after we created them. So we're going to use tuples, but tuples do not tell a story. So there is a better way to do that. And the better way is to use something from the standard library. There is a module in the standard library called the collections module. And it has something in it called named tuple. So a named tuple already sounds like it is related to a tuple and it is. So maybe let's go ahead and let's also maybe before we do that, give the point a name up here because we are going to compare it to what we are about to build. So how can we use a named tuple? So what the named tuple function here does is it is a function that creates for you something that we would refer to as a class in chapter 11. But for now, we can also refer to that as a constructor. So remember in chapter two, we said callables are built-in functions, constructors and user-defined functions. So constructors are simply things we can call. And constructors are used to create objects of a new data of this data type. And similarly, we are now going to create our own constructor. That is how you can think of it. And more formally, this would be known as a class. So let's do that. Let's create a class or a constructor that is called point as a point in a plane, for example, in the XY plane. So a point is defined as a tuple. So as a named tuple that has a name. So the name is usually also the variable. So usually the variable could be anything, but usually the variable that we store the constructor in and also the name of the constructor usually is the same. So if you don't know what to put here, simply put the same thing here as a string. So to indicate that this is the name of the constructor. And then we are going to give it a list. It can be any attribute, but we give it a list. And in the list, we are going to define as string objects the fields. So a coordinate is made up of an X and a Y. So let's do it like that. X and Y. And now I'm going to run the cell. And the result of that is that I now have a point class, a point constructor. So what can I do with that? Well, quite easy. I'm calling it a constructor because we can use it to construct new objects. So let's do that. Let's construct a point in the same way as we would construct, for example, in the same way as we would use any other built-in constructor, we would call it. So it's callable. And so it's another example of a callable. And let's go ahead and give it the two values one and two, because we want to model the point one, two. And we get back a representation that is a bit nicer than simply the tuple notation up here. So if I ask Python what is P, then P is one comma two, which looks kind of nice. Looks like in math, but it's really a tuple notation. And here we see that one comma two is a point. So it tells more of a story. And it says one comma two has a meaning. It has the meaning of X and Y. So let's go ahead and store that in a variable. Let's call it point in lower case. And now let's compare the two. Let's compare P and point. So what can we do with it? So I will do that with by reviewing the four properties every sequence has because tuples are sequences and named tuples are also sequences. So what are the four properties? Well, the four properties are at first the container property. So let's check that. This is the in operator. So let's check if the number zero or the number one is in P. And it is. Let's check if the number one is in point in lower case point, right? And it is. So in other words, named tuple behaves like a tuple when we use the in operator. Second, let's use the second property, the size property. And the size property basically means the object supports being passed to the length function as an argument. So let's ask what is the length of P. And the answer is two because there are two coordinates in a point. Let's ask what is the length of point lower case point. It's also two. Okay. So it works. Let's look at a couple of more properties. Let's see if we can loop over them. So if I say for coordinate in P print coordinate, this works. I can loop over it. Let's see if I can loop over it in reverse and let's see if I can loop over point as well. And it also works. Okay. And now let's quickly do that. Also the fourth property, I wanted to refute the four properties, which I call reversible. And we can simply check that by using the reverse built in and we can pass P to it and we don't get an error message. There's no type error. It works. And we could also say we could also reverse point lower case also works. So what do we learn from that? So the consequences named tuples behaves just like normal tuples. That's the big consequence that we are over at the big conclusion. And also all the other things that you can do with tuples, you can do with named tuples as well. However, named tuples also model the semantics. So what is the semantics of the problem here? The semantics are really here that a coordinate is really an x and a y. So how can we use that? Well, we could ask the point, what is its x coordinate? And I get back one. I could also ask the point, what is its y coordinate? And I get back two. Okay. So by defining up here when I defined the point constructor, by defining x, y or x and y Python remembers that. So the point object, the lower point object now also has an x and a y attribute on it. And just to compare that, if I try to access x on p, on the p object, I of course get an attribute error because the normal tuple does not know what x is, right? It does not know about the semantics of the problem. So that is how we can design tuples and give it some semantic meaning. And usually what we do is we model some record of data with it. And the record, again, is a collection of otherwise independent fields. So that is what we can do with the example of a point. But now let's also do a second example. And the second example is the one that I told you, the one of a student. So maybe let's go ahead and say other example, students in a course. And let's say I want to create a student constructor. And this also going to be a named tuple for now. And the student, well, the student constructor has a name. First of all, it is going to be called student. And now let's define the fields of data. So first, a student may have a name. Second, a student may have an age. Third, a student may have a GPA. Next, a student may have, maybe let's put that in the third position here, a hometown. So let's say city where the student lives. So these are the fields that the student object should have. So now we have a student. So let's say we have a student A. And student A is going to be a guy named Achim. And the person is 20 years old. And let's 20 be an integer. So there is no typing here. So we can use an object of any type for each field. So this could be enforced by later on learning about classes. So classes are really the next natural step to take after named tuples. So named tuples are really like a short version of going into object orientation. So Achim is 20 years old. And maybe he lives in Berlin. And maybe he has a GPA of let's use a German style GPAs. Let's say he's a good student. So let's say he has a GPA of 1.0. For non-German students, 1.0 is usually the best grade you can get at the German university. And depending on the scale, either 5.0 or 6.0 is the worst grade you can get. So let's define student A. And let's also define a student B. And student B may be a woman. Let's call her better German name. She may be 21 years old. And she lives maybe in Frankfurt. And let's also give her a GPA of 1.0. And now if I ask Python, hey, what is A and B? It tells me, well, it's a student by the name of with this age and so on. And now we can say what is the name of A by saying A dot name. And it simply tells me Achim. I can also say B dot, let's say GPA in all uppercase. And that would be 1.0. So probably if you read in chapter one about coding conventions and in Python, usually variables should be lowercase or lowercase. So maybe a good practice would be to lowercase everything, but I will leave GPA uppercase for now. This is good enough. So the main learning from this video is that whenever you have to model records of data, so records as a field of otherwise unrelated data points, you want to always have these data points together. An actual way to do that in the Python world would be to use a tuple. Okay, so that would be probably the best way because it's immutable and it puts together many, many unrelated, otherwise unrelated objects together in one. And yeah, and if you want to go that route, then probably a better way is to simply go ahead and use a named tuple right away, because then you can have everything a tuple can do. So all the functionalities of the tuple are still there, but you can teach your program, so to say, some semantics of a problem that you are defining or a problem that you are solving. So if you're writing software, for example, that captures the crates or that manages the crates of students in my course, then probably there is going to be some student constructor somewhere because students always have the same fields, right? And also note how when we talked about lists in the beginning, in the very first example where I showed you a big nested list, I said, I told you that in lists we can have heterogeneous data, and the reason why is because the data are not in the list really, the list only holds references to the then heterogeneous object, but it's not a good idea. So if you use a list, you should usually have homogenous data because you want to process all the elements in a list with the same operation and in order to make sure that this works, usually the data type of all the elements in the list should be the same, should be a homogenous list. Same holds through usually for a tuple if you use a tuple as an immutable list. However, what we see here now is with the student example, what you see here is that some of the seals are strings like the name and the city, but some so the age for example would be an integer because assuming we are simply modeling whole years, then it can only be an integer and the grade has to be a floating point number because grades in between the full grades have to be possible. So now here we have a tuple with heterogeneous data and whenever you use a tuple to model a record of data, then modeling heterogeneous data is quite normal. So when you use a tuple as an immutable list, then usually you should have homogenous data, but when you use a tuple or a name tuple to model a record of data, then using or having heterogeneous data is absolutely okay. Of course in the long run there will be more sophisticated ways to teach your code semantics. This again will be talked about in chapter 11 when we talk about object orientation in detail. But for now this is the first step where you basically define a so-called, let's call it a blueprint. So the student class or the student constructor is really a blueprint of what a student is, of what feels a student has, and then you can instantiate a concrete student here. So a lot of that stuff will make more sense in the long run once you understand object orientation, but for now simply know that whenever you want to model a record of data in your program, you can use a tuple or a name tuple to give it some names. So that is the last video here covering chapter 7. And in the next couple of videos covering chapter 8, we will talk about another very interesting concept. We will talk about data that we work on, lots of data that is not explicitly in the memory. So we will talk about how to really run your programs in a memory efficient way. It's a topic of iterators and generators and so on. So I will see you in the next videos.