 Hello everyone. So I have we're going to get started with the implementation of your linked list. I am working here with the code for your next assignment. So I have downloaded the code. I have unzipped it into a directory and I'm going to work in here for a little bit. So I encourage you to do the same. We're going to write some code together and some pseudo code. All right. So I am in the linked list.py class and you will see that there are a couple of other files in here for what those are. Just read the details of the assignment. For now I'm going to work in this linked list.py class. Okay. Now from the previous slides we know that there are going to be two classes involved with implementing a linked list. The first is our node that represents one node in the list. And do not change this class. It is written for you. It's got a constructor here and the constructor takes two optional parameters to default parameters. If you remember go check out the short video on default parameters. The constructor can take data which is going to be the item that lives at the node. And the next variable which is the thing that comes next in the chain. And if you don't give it anything when you call it these both default to none. And that's what we want. But be aware of that. If you do not specify values for data and next they will default to none. I also give you string methods and wrapper methods for printing these things out. All right. Now onto the meat of this assignment. Again you do not change the node class. But you are going to use it inside the linked list class which you are responsible for implementing. Okay. So the linked list has a class constructor. Don't modify it. Do not change this method in any way. But here are the variables you will be working with. There is the head variable. It is initialized to none when the list is initially constructed because it's an empty list. There's nothing in it. The head variable must always point to the first item in the list. So when we go to add and append things you're going to write methods called add and append. We're going to have to work with this variable. The tail variable must always point to the last item in the list. Okay. So again we're adding and removing things from the list. You may have to update this variable. And then we have a size variable. We're going to use this. We're going to keep track of the number of nodes in the list as we're adding and removing things. So this is just going to be an integer but we are going to have to update it. Okay. I also provide you with this method which is called ITER. Okay. Don't touch this method. What it allows you to do is loop over the list. Okay. It's special code. Again, please don't look at this code. Don't modify it. Don't try and adapt it. If you have questions about it, absolutely ask. But don't look at this code as a blueprint for doing anything. Okay. What it just lets you do is it lets you loop over a linked list that you have created. Okay. And that may be useful to you as you go to work on this assignment and try and debug things. Okay. But don't modify this method. I have to find the lend method here. So the lend method is one of those magical dunder methods. We worked with it in the last assignment. It supports calls like this. The length of the list, it returns you the number of items in the list. That's all. Okay. So all this stuff you don't deal with. Now, let's talk about putting data in the list. Let me scroll just a little bit so my head isn't in the way of the code. Okay. So we're making a list. One of the things we need to do with a list is add items to it. Now, regular Python's list with the brackets does not have a notion of add. Add is an alias for insert at index zero. Okay. Put something at the front of the list at the very beginning of the list. Okay. When you call add, so I give you extraordinarily specific instructions on what the behavior I expect out of each of these list methods. Okay. You must have this behavior to get full credit for the salient points in the assignment. Okay. So add an item to the beginning or the head of the list. This method does not return anything. And this method must have a big O of 1 implementation. Okay. So big O of 1 means this thing needs to run quick and constant time, regardless of the number of elements in the list. Okay. Add takes one parameter, which is the data item that we want to add to the beginning of the list. Okay. So I raise this not implemented error. This is just for me and for you for testing. So one thing I'll mention right here, you can run this code and it will automatically test itself. If you scroll, see there's these test add things and it says failed. Add is not implemented. Aborting tests. Down at the very bottom of this file is some code, some test code that runs a lot of different stuff. So you can run your code and it will kind of tell you, hey, did you get it right? Did you get it wrong? At least from an input and an output perspective. Okay. So if you start seeing past tests down here, you know, you're in good shape. If you start seeing failed tests down here, you know, you've got something to fix and hopefully the test will give you a clue about that. Okay. So all right. Let's start implementing. Step one of like our programming mantra is you've got to think about how you want to approach the problem. Okay. Well, let's think about this in terms of the special cases that it might run into. Okay. That's usually a good starting place. So let me switch over to my whiteboard for just a second. Okay. So I'm writing in red now because my black marker died. We're talking about the add method. Okay. So when we start out by calling the constructor with a linked list, sorry, I should be at this camera now. When I'm talking about, I instantiate empty linked lists. So there's nothing there at the beginning. Head and the tail of the list are both going to be none, right? When this first line executes. Now I'm going to add Alice. Okay. So what impact should that have? Well, conceptually, if I do it on an empty list, right? If I do it on an empty list, Alice will be the only thing in the list. And both the head and the tail of the list need to refer to Alice, right? And then the other thing I have to have a length of one. Okay. So this is kind of a special scenario, right? Something I need to think about. Adding to an empty list. Okay. What if the list is not empty, right? What would that look like, right? Adding to non-empty list. Okay. Well, if the list is not empty when I add to it, like let's, let's add Bob here. If I add Bob, what happens? Well, if I add Bob, Bob, he becomes the head of the list, right? Bob is going to now be the head of the list. Is now Bob, right? But Alice stays there as well. So we've got to tell Bob, now that you're the head, you've got to point, you've got to refer to the next person. So Bob's next needs to refer to Alice's node. And nobody comes after Alice. Alice has no next. She is the tail. And then we will also have to update the length. Okay. So what we do is going to be just both so slightly different depending on whether this list is empty or not empty. Okay. All right. So let's do the code here. Get back over to my code view. All right. So let's think about it. If, give me just one second here, apologize. If, okay. First thing we need to do is we're going to put some data in our list. So I need to create a new node to hold that data. Okay. So I have my constructor class or my node class. So I'll say node gets, right? I got a new node here. And the node takes two parameters, the data value that I want to put in there. Well, that is going to be item. Okay. Again, we're looking, we're calling this guy up here, the nodes class constructor. And it takes two things, data and the next node. Okay. So actually, let's be explicit about this first. Here, I've got an empty node, nothing in it. What should this node's data be? Well, the node's data should be the item. Okay. And what should the nodes next be? Okay. Well, in the case where it's empty, I can't see where I'm pointing. And there's only one node in the list. That node's next value is none, right? Because there's one item. Okay. That's it. Okay. So I've created my node. I've got a link in the fence. Now what I need to do is I need to put that node into my list. Okay. Where does it go in my list? Well, the head and the tail both need to refer to, right? But let's start at the head, right? The head, we're adding items at the head of the list. Okay. So self.head gets my new node. Okay. See what we did? We inserted it at the head, right? The head now refers to this new node that we created. Okay. Now, but we need to think a little bit, right? What would happen though, if somebody is already in the list? If somebody is already in the list, they kind of get bumped down, right? They get bumped down the list. What happened on our board? Well, we inserted Bob down here. We had to tell Bob's next point to Alice, right? Because Bob is now the head of the list. So we have to tell Bob, hey, point to Alice. Well, where was Alice before we inserted this, right? When Alice was the only person in the list, she was the head, right? So Alice is the old head of the list. Hmm. So, actually, this new node we're making, this is the Bob node, right, from earlier. The item value is Bob. But next needs to point to Alice. Well, where was Alice? She was the old head of the list, so we need to modify this. Okay. Alice is the old head of the list. Alice was the old head of the list. Okay. So this is really important. Self.head contains a reference to a whole node. And previously, that node was the node containing Alice. Now we're saying we've made this new node that holds Bob. And Bob's nodes next needs to point to Alice. Okay. So take a minute. Pause here. Make sure you really, really, really, really understand what these four lines of code does in relation to the example on the board and in relation to what conceptually is happening. Feel it. Make sure you understand each and every line. It's so critical that you do. Okay. So again, pause here. Take a minute. This is big concept stuff. Make sure you understand what self.head is. Play with it. Look again at the example on the board. Understand that whether this is an empty list, whether this is a list with one item, whether this is a list with 10 million items, this code works. Okay. Take the time to really grasp it. Write out some examples on paper. Okay. All right. Now, this code is fine. I'm going to shrink it down in a minute. We haven't taken care of all the housekeeping we need to do. Remember that there is a tail here. Right. Now, if there's already data in the list, if it's already got a node in it and we're adding to the head of the list, we don't need to worry about the tail. The tail is always the tail. And unless we delete something, the tail is just going to keep, you know, moving on out. Okay. But in that special case where the list is empty, where there's nothing in there, we need to set the tail to be the only node that is inside. Right. In the case where we only have Alice in there, where we're adding one node, the first node, we also need to remember to set the tail. It's the only time we need to do it. Okay. So we can, we have a variety of ways of figuring out if the list is empty. One very simple way is to ask the list, hey, is your size zero? Are you empty? If so, then I need to set the tail equal to the new node as well. Okay. Right. When I insert into an empty list, when size is zero, both the head and the tail must point to the same thing. But as I add things, as I insert them at the head when there's already an item, I don't need to mess with the tail. The tail kind of, the tail's tail, as the thing grows, the tail stays the same. Okay. All right. So I'm going to take advantage of my constructor here and shorten this up. Okay. So remember, the constructor can take two parameters, the first being the data. So node is item and node gets self.head. Right. I'm just making, taking advantage of the constructor parameters here. It has the exact same effect as these lines of code right here. Okay. So go check out the constructor. Right. I'm just doing this stuff in one line. Okay. So I can get rid of these lines. Okay. Now there's one more thing I have to do, one more little housekeeping thing, which is what? I need to update the size. Okay. All right. I'm ready to test this thing now. When I go to test, you need to remove this line, this raising and not implemented error, just from the method you wrote. Okay. So we completed the add method here. Let's run it. Okay. Right. So my testing add. So this kind of tells you what it's doing, how it's testing it, add calling add Alice to the list. And this little arrow here is the return value. Now adding does not return something. Okay. It just changes it kind of like when you append to a list just changes it, doesn't return anything, just changes the list. But after I add Alice, the head points to Alice's node. That's good. The tail points to Alice's node. That's good. The length of the list is one. That's good. Then I add Joe. Remember adding inserts at the beginning of the list. So now the head is pointing to Joe. That's good. And the tail is pointing to Alice. That's good. And so on and so forth. So kind of like what would be a really good exercise for you would be to conceptually follow these steps, you know, where it adds in here. You do that conceptually on paper and convince yourself that the head and the tail are remaining updated. Okay. Remember the linked list, it only has three variables it knows about. The head, the tail and the sides. So you got to keep those current and up to date. All right. So take some time to wrap your head around this. Make sure you understand it. And we'll see you in the next video where we're going to talk about appending.