hey everybody welcome in this episode we're going to go hands-on with stacks and queues just by going through some examples we're going to be using the Python programming language so you can use whatever language you want and adapt it to your needs so we're gonna first take a look at using what's built in to our advantage all right so to create a stack we're just going to use a list so we'll say data let me zoom in a little bit for you guys and square brackets to create that that list and we can put some elements in here by default but to show the behavior best it's probably best to limit to just a few operations that are 4 stacks which is the ability to push an element onto the stack and the ability to pop an element off of the stack so to push an element you actually use the append method and you pass the data in as an argument to pop something off of the stack you actually invoke pop so that one fits nice and that's going to be returned so we'll just call the return variable element and then we can do is we can print element a little too zoomed in so i zoomed out a little bit run this and we get a bunch of garbage just ignore that but the main thing is this 5 which is the output from this print statement and afterwards when we print data notice that it is empty so when we invoke that pop method the data is actually removed from that list so the list here is the data structure and we are using it to basically create an implementation of the abstract data type known as a stack so that might have been a little bit theoretical but basically we're using a list as a stack yes lists have other operations so for example we can go data dot and pretty much anything in this list is available to us for use however we probably for best practices want to limit to just a few of these probably pop and probably append now you might be wondering why would you use a list and then pretty much limit its functionality by only using a few of the methods available to us well it's basically for our sake if we are trusting a stack to work a certain way then we want to abide by the rules of a stack if we're expecting a stack to only allow us to put things on top of the stack and remove things from the top of the stack but then I go in here and say insert and pass in some index and put some data in here well that's just going to totally throw it the integrity of our stack into question so it's probably best just to stick to the basic operations of push and pop gosh Claire why do you always torment me now you may also want the peek operation which is to look at the last element and that's pretty easy what we're going to do is we're just going to append that data and what we're gonna print is data and for the index just say the length of data and then subtract one so the length of data is always going to be one higher than the highest index so to peek at the top of the stack you just need to look at that last element so running this and we get five but note that after this if we print data it's going to still have five inside of it so we didn't actually pop that off of the stack we just looked at it now if you want to visualize a little bit more about how a stack works and might help to do a couple of operations so let's go ahead and say data append and we'll do 10 and then data dot append undo 15 data dot append 20 and then data dot pop data dot pop can you predict what the list is going to look like when I say print data well to understand how that works we add five and keep in mind that it's going to be the leftmost number so when we append another number it's going to show up on the right of 5 so we'll have 5 comma 10 comma 15 comma 20 and then when we pop off next two elements worst get rid of that 20 and then we get rid of that 15 so we're left with just 5 comma 10 we run this and that's exactly what we get so that is how a stack works now let's take a look at EQ so the only difference here if you want to continue to use a list as the data structure of choice to implement a queue the only difference here is instead of just using pop with no arguments you're actually going to pass in a zero and in this we're pretty much just considering on the left of the list so if you look down here at the bottom the left is going to be the front of the queue so when we pop index 0 we're actually removing the leftmost element so now what this is going to do is it's going to add 5 then behind it it's going to add 10 behind that it's going to add 15 and then behind that it's going to add 20 when we pop this first element what it's going to do is it's going to remove 5 and then this next pop is going to remove 10 so we should be left with 15 comma 20 we run this and that's exactly what we get and as always this is returned so if we wanted we could assign it to a variable and then use it later on in our code so for example we'll just print element and running this we get the value 10 there so that's the one that's popped right there now the naming here is a little funky but if you want to basically correlate these names to the operations for a queue abstract data type the append is going to be the in queue and this pop down here is going to be the DQ if you want the ability to do the peak operation or to look at the element that's going to be DQ'd it's actually pretty simple all you have to do is say data index 0 and that's going to look at the leftmost element in this case 15 so when we run this we get the value of 15 but that doesn't actually remove it from the queue so that is how you would do it with a list however the downside here is that each time we pop an element all of the other elements in the lists have to be scooted over one index which is a time consuming operation if you were to have a pretty big list another way to think about it is it's an operation that is o of n so it's dependent on the list size pretty much has to go through the entire list moving all the elements over we want to avoid that if possible so there's actually another option we can use and that's going to require an import so here's we're going to do we're going to clear out our code our terminal and we're going to import a a tool that we can use called a deck so from collections import deck I called to say a DQ in the previous video but whatever I'm pretty sure it's pronounced a deck and to create a deck what we can do is we can say data is a new deck and parenthesis and the way you add data to this is pretty similar you just say data dot and then here's all the operations we can use so we'll say a pend let's use some strings this time Caleb and then to remove this data there is a special method on this so we can say data dot pop but not just normal pop we're actually going to pop left and this one doesn't require us to pass in 0 because it already knows we want to remove the leftmost element so doing that should return the data so we'll just say element and assign it that return so then we should be able to after this print element and we'll also print the lists just to confirm that it's empty so running this and you can see we got Caleb and then we got a deck of 0 elements now if you ever need to be absolutely 100% strict with what operations can be used on a stack or queue or pretty much any structure you're creating you can create a custom class so I'm not gonna get super into this but there might be a situation where you need to create a custom stack class or custom queue class or custom any class and if you're in class the teacher is probably going to tell you to create all kinds of useless classes so let's just go through an example of that where we create a class called a stack and in here we're going to define an init method and this is the constructor this is what is invoked when we create a new stack and I'm actually going to give this a capital S here so the only parameter in here that you absolutely have to have is called self which refers to the object that's being created and then inside of this method you can define any attributes for the stack so we'll just pretty much create a wrapper for a list so to do that we can say self dot data is an empty list so it'll initialize it to an empty list whenever we create a stack we can also create methods for the stack so as an example we could say def and we can name it appropriately to match the stack behavior so we can call it push this is also going to require self and in addition to self we're going to take the data to be pushed on to it so we'll just call that data and here's what we're gonna do we're going to say self data which refers to this list here dot append and pass in the data parameter here so you can probably tell we're not doing a whole lot we're just pretty much giving a new name to something that already exists but you could define any kind of custom logic in here or force a certain behavior whatever you need we're also going to create a pop so def pup this is going to have self but we don't need to pass in any other data it's always going to remove from the same index so we don't need to take that as an argument then all we have to do is say self data up and return this now it's a convention inside of Python whenever you have a private variable that it's not really supposed to be exposed you can just preface it with an underscore so we'll put dot underscore data and update that throughout this code and now we can practice using this see if I got any any errors anywhere so what we're going to do is we're going to create a new stack variable so to do that we just use the uppercase stack that will invoke this initializer here and then we can say stack dot and look here the only methods we have available to us now are pop and push so we pretty much restricted just to pop and push now python is fairly open so if they really really really want to access that list they can just by saying underscore data and then they have all of these methods however it is clear from my perspective as the user of this class that I'm not supposed to do that because there's an underscore here I should just be using these methods here so we can for example push some data on and then we'll just get that data back out by saying stack dot pop and then let's print test so let's see if this works I probably screwed something up we'll run this oh hey believe it or not it actually worked alright so that is how we create a custom stack now it might be silly but the point here is that we can basically define particular things that need to be met such as push and pop and then the actual logic to do those can be anything we could do a similar thing by creating a class for a queue or a priority queue a heap a map whatever abstract data type we're trying to represent we can do that using custom classes and the implementation is irrelevant all that matters is how we use that class right now this class is pretty simple but if you wanted to you could build upon this creating any kind of custom methods so for example we could create a method in here to implement the peek capability to see what element is going to be popped next and for this all we would have to do is return self underscore data and then just get that last element so we would get the length of the same structure self dot underscore data and then outside of the length just subtract one so let's try this out before we actually pop something let's print stack dot peek and we should get the value 10 and we do we get the ten for the peek and then we actually end up popping that data off which is where that second ten comes from when we print this variable here so hopefully that lets you see some of the different capabilities we could do when it comes to creating our own custom classes right now we're just using a stack but you could create one for a queue for a heap or priority queue a tree whatever structure you want you can create a class to represent that the class is going to define the different behaviors and different things that need to be stored and then when you actually go and create an object like we did here that's when you create an actual example of whatever we're working with so we're creating an actual stack and using it in these lines of code so hopefully that was helpful I'm sure you could take this code and adapt it for other programming languages and in fact it'd probably be a good practice to try it in a few programming languages to get some experience that's one of those things where like I'm not actually gonna do it myself because I don't really want to so I'm just gonna move on to the next video and hopefully you guys are excited let me know if you enjoy these hands-on videos or if you prefer the conceptual videos in person stay tuned and I'll see you in the next one [Music]