Python Object Oriented Example Project

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right let's get this on the road welcome everyone welcome back for those who were there yesterday or both days yesterday and the day before and hello to everyone joining new today uh today on this stream i'm gonna talk about some object-oriented programming with python and again i'm gonna do this in a very practical approach just by building out a little pokemon type game so it's don't expect too much functionality from it but you're going to be able to let two like different instances of pokemon battle against each other and feed them so that's what we're going to build out in this in the stream and just as a quick introduction that's me i'm martin i do mentorship and content creation at coding nomads and i am the creator of the python django course that we have on our platform and i got a bunch of years of teaching python under my belt by now i also want to share with you again a couple of links that are relevant i forgot so far to give you this link which is relevant this is a nice and important one which is actually the github repository for this three-day python training where you can find the code that i'm writing um and also some explanations about the different topics and what are the concepts that that i'm covering in these different parts of the of this three-day mini course so check that out there's also a link to our twitch and youtube which i'm gonna yet again pop in here into the chat so that you can check it out if you want and we're also thinking about doing just some weekly hangout sessions on our twitch channel so if you're interested in that maybe right in the chat if you would want something like that and then we could just hang out for an hour every week and build work a little on projects or discuss some programming related topics so if you're interested in that let us know and here's also the link to our learning platform where you can get access to a bunch of free materials and start learning if you're interested all right so much for links in here now i'm gonna go back to the project at hand and today while building out this uh little program the little game we're gonna talk uh about we're gonna cover a couple of concepts again in a similar way that how this happened in the in the last two days so i'm just going to mostly focus on writing the project and once we hit something you know a new concept or something that is important to understand in order to move on or to build out a specific thing then i'm going to talk a little bit about what this is and object-oriented programming is generally like quite used quite widely in the programming world and i think that writing a game is a really nice way of getting an idea of what object-oriented programming is about and so we might not even have to cover too much theoretical stuff but just you'll see how it makes sense and why it makes sense by the project that we're going to build okay so there's a couple of these topics that are going to be covered these things might or might not mean something for you for now but you'll see me address them when the time is there so to see okay so that's back to vs code that's the same project that i've been using during the past two days as well and i'm gonna start off by creating a new file in here and i'm gonna call it pocket.py because we're gonna gonna build a little pokemon game okay so i will make this also a bit bigger so everyone can read this maybe that's a little too big i'm gonna stick with this size uh if anyone can if it's too small let me know i can still increase it i put it up one notch okay um so again i'm going to start off with writing a little bit of pseudocode just to get the idea of what this game is going to be about and oh one thing i forgot to mention pops in my head right now is for the recordings we're also recording these sessions and we're going to send them out should be they should be all up and you're going to get an email by tomorrow i believe should work out so if you're interested in re-watching these then you're going to get a chance to do that as well okay time for this game i'm going to start off with a little pseudocode and this is going to be um just the topics of what do i want to cover in this in this program um i want to be able to create i'm going to get create a pokemon then i want to be able to take a look at it um what else i want to be able to feed them to increase the health right and what else of course i want to be able to make them battle and decide for a winner so we're going to need some sort of game logic in here as well then but if you think about this if you're familiar with the pokemon games if you played them at all you it's it's actually a glorified rock paper scissors so there's some sort of different types that battle against each other and one type wins over the other it's it's more complex than that obviously in the real game but that's pretty much what i'm going to implement here so it's just going to depend on the on the types which types battle against each other um but that's a very rough outline of the topics that are kind of like want to implement in this little game okay so let's start with the first one if there's any questions or anything that you want to explore more just like the last days just feel free to put it in the in the chat i have the chat up so i can see when you write something and i'm happy to discuss anything i like live sessions for the fact that they're interactive so let's make them interactive right it's more interesting okay so if you have a little bit of experience with python like you might have uh you know even if you've just been on the streams before we already explored a little like we did stuff like creating a number or creating a string and assigning it to a variable right all of these things in python because python is built in an object-oriented way are actually objects so when i when i do this when i make 42 when i write it down like this i create an integer object that's what these ones are called in python and if i do this if i create a greeting and assign it to a string then i create a string object so all of these things are actually objects so you've already worked with objects but it's not really necessary that you understand a ton about it but um you now we're going to peel a little under the hood by making our own object so instead of just using some that python already comes with we're actually going to create a new one and in python you can do this with the keyword called class and then this is the one time when you use capitalization in python usually you also always want to write everything in lowercase and snake case that looks like this snake case so instead of spaces you you put this underscores and everything in underscore but if you define a class then it is capitalized and that's also why you shouldn't capitalize other variables because then it's clear already when when you go and read something like that that you know that this is actually an object okay and you might remember if you were on the streams before you might remember that we worked with something like that which was the path leap so we did we said from path lib which is a module in the standard library we import that uh you can dab it whoops there you go path so you see that this is uppercase so what this indicates for you when you see something like that in python is that you know and if i hover i also get more information in vs code that this is an object so this is a class that is defined somewhere in the path lib module and the path capitalized thing is an object so we're making something similar now by saying class pokemon that's what we're gonna make and you could just think of it of an instance of a pokemon so uh bulbasaur for example right and uh for now i'm not gonna do anything in here i'm just gonna say paths which is a python keyword that says i am valid python code so don't don't throw many errors i know this class should have some content in there i'm going to implement it later just relax interpreter it's all good okay so i can i can just say don't do anything for now this this is just gonna create the class and nothing else and uh let's hop back over into the python repel in here and i wanna show you something new here as well from in the first stream we look just at the plain python repo by typing python and entering it like that but and it's good for exploration but you see it's like it's a little i know it's a little what's the right word it's just black and white and you don't have auto completion or anything like that so it's a little dire to work with and then later yesterday we looked into using breakpoint for debugging so you hop into this pdp debugger which is also pretty much plain text just like that um but they're all like value ways of interacting on a you ask a question you get feedback right away from python so i want to show you a third one which is essentially just an arrow like this one but it adds a bit of color and makes it a bit easier with auto completion functionalities and this one is called be python and i already have it installed if you don't have it you can install it using pip install be python and then you call you enter this shell in the same way as you would up there you saw like as i type python to enter the python shell and if i say be python then i enter this b python shell again it's very similar but you see already i get a bit of color here and when i type you will see that it has a couple of advantages so it's more fun to work with okay so i want to play around with this pokemon class that i defined in my script how can i get access to it in here in the repo well since the repo is starting in the same folder in this python days folder is where i'm currently at and that's where i started the rebel and this file that contains my pokemon class is just lying there i can go ahead and import it in the same way as you did any sorts of imports so far in python so you can import your code in in the same in the same way as long as you're in the same folder otherwise this you can also do it otherwise but there's a little more fiddling you need to do but if you're inside of the same folder it's very easy you can just say import and you see i already get some auto completion from the be python repo that i can then just with pressing the right error i don't even need to type it out everything okay so now this is not working because it's not called pokemon but it's called poke so that must have been something that i typed before that's why it showed me this auto completion okay so i need to type exactly the name that this file has and also one thing that i try to always highlight when you're working with programming is that if you get an error if you get a trace back don't get scared of this right this is not a problem at all it's just python telling you we have some sort of miscommunication and something that you tried to do doesn't really make sense to me and that's what i know so it gives you this this very helpful feedback usually which in this case is oh i couldn't find this module by just naming it module not found error very descriptive and then gives you even more descriptive information this specific one that i typed called pokemon doesn't exist it couldn't i couldn't find it and the reason is like i just said before because it's named differently it's called okay you don't need to put this py at the end if you import a module it it needs to be a python file anyways to be recognized so like this i can say input okay and you see no problem here let me make that bigger now that doesn't work i i don't actually know how to clear the ripple so that it would be further up so yeah it's just going to be here at the bottom i hope you can still see it okay so i imported this this was fine right i got no error here this second error is just because i typed something that doesn't exist in there and now i can create i can create an instance of this pokemon class that i defined i can say bulbasaur equals and here something interesting also that you already discovered that with the pathflip module i think maybe we tried importing at the beginning just saying import path lib and then i later changed it to from lib import path okay and this touches on the concept of namespaces so i can't directly call pokemon.class in here it doesn't exist i don't get any autocomplete because it's hidden in the name namespace of the file that they imported so it's it's hidden inside of this poke file and then inside of there is this pokemon class so i can say ok dot pokemon and then i get the autocompletion so this concept of namespaces is also a really really useful one in programming because it allows you to like avoid running into problems with same named type of things because i could have something dif i could declare a different class with the same name also called pokemon inside of my rebel in here now and they wouldn't override each other they wouldn't clash with each other because this specific one that's defined in that file is hidden inside of that namespace and that's already that's already um maybe gives you a bit of a feel for an object oriented nature because uh you will see that this works very similar so in a way with objects it's gonna work very similar so in a way you can think of these files as big objects that then have smaller objects in there as well because the access to them are similar as you will see okay so let me create this instance and i can do this by calling the class so you've seen me call methods before and we'll look some more about methods in here now also because they're a concept they're functions on top of a specific object but if you do this on the class name then it's going to create an instance of it so now i have this thing here bulbasaur and you can see that it is a pokemon object from the pokey module that i imported at a specific memory location this is the output that i currently get okay so that's all like there's no other information in here right now i don't know anything about its type i don't know anything about its name et cetera et cetera because there's nothing i put in this class at this point but i can already create an empty object it's kind of cool and then i can do things like i can say publisher.name equals oh sorry or bulby maybe it's going like that and now you see with the same syntax this dot is like kind of like a a little portal you can think of it like a little portal that you can step into the class or the object that you're working with and do something in there in that space what i did is i stepped into this into this instance space of that specific object and added an attribute to it so similar as if i would define in here i would say name equals hello this name variable here would be and you could think of it as an attribute to this pokey um module essentially right like it's a it's a module level variable in here and the one that i created down here is an instance attribute so it's a variable that lives only inside of this specific instance of a pokemon because every pokemon is going to have its own name right so every instance of a pokemon that i make it's going to have a different name associated to it so i want that name i want all of them to have a dot name attribute but i want it to be different for each instance that i make okay so um fine so this has a name but what happens if i exit this and then maybe i want to go back in look at this again from import pokey and then do i still have access to this what if i say if i give if i give it the same name right i say oops or it's pokey dot here you see the autocompletion makes it a bit easier gotta spell it right name okay so this doesn't exist anymore uh oh i have a question will the data inside the instance persist between sessions yeah there you go this is what i'm just trying but i'm just trying out it it will not right so this is just a rebel session so any data that i make in here gets lost and also because um this name attribute isn't at all defined in the class that i wrote like i didn't do anything in this class it's just an empty class um there's no way like that the python would even would even know about the attribute at all so it's telling me if i try to access this attribute in this new session where i didn't define it it's telling me this doesn't even exist there's no such attribute on that class which is right right if you look back at the class that i made in here there's nothing such in there but i guess we want all of our poke we want to have a name right so in order to do this i can go back over to the class and instead of not doing anything in here i can do something that should happen to it should happen every time that i make a new instance of this class so every time i want to define a new pokemon i want it to have a name so i can say and just look at it for now these methods i'm going to talk about the more are called dunder methods and their special methods in python they aren't actually that special they're just normal methods but by having these two underscores in here you're kind of indicating that these are methods that only the person who writes the class should do anything with so anyone who's using the class later on by importing your module and doing something with it or playing your game they shouldn't have to worry about this at all what's going on with with these types of functions they're called thunder methods because of the double underscore and uh the first one that you get to know here is the dunder init which stands for initialize and this is going to um allow us to give and to give a name to each pokemon instance that we're creating okay so you might um let's do a pass in for now you might see that uh there's this little self that i put in here additionally to the name parameter here and this um the best way for now to think about it is just like this allows you like passing this thing here gives um a reference to the instance that you're creating it might be a bit confusing don't worry about it now this but for every instance method that you create inside of a class you're going to have to pass self if you want to have access to anything that is created that is part of that specific pokemon in that case the name right so this allows us yeah to make this connection and then i'm gonna say self.name so here i'm defining an attribute on that on every instance of that object and i'm gonna say assign to self.name the name that comes in when you're creating the pokemon okay so these two are the same right and if you're familiar with functions you can see that this is something that is going to get passed at the beginning and then goes in here and then gets assigned to a new variable that's just called the same because that makes sense right but it's part of the self object so again it's it's the same concept right you see there's this dot in here similar to how we here it said this is going to be the object and then dot name so you can see that self is gonna be replaced by whatever the object is that you're creating okay so like this i can give it a name and now let's go back over here i'll always have to exit this and then restart it again because it needs to pull in the code again and it only does that at the beginning when i say import okay okay so now i can make a new one dot pokemon and what do you think is going to happen when i just call it like it did before well i'm going to get an error and the reason is similar to if you would call any function that requires a specific argument it's just telling you exactly that you're i'm trying to call it without passing an argument but it actually needs this argument to properly run and here you can already see that what's happening when i do this this open close brackets on an object is that this init function method is going to get called and it's telling me that it's missing one required position and argument called name you can see that it's not talking about self yeah because self is something that you're passing by creating it already so that's that already comes in because you're making this instance but this instance wants to have a name and i'm not giving it the name so it just doesn't know what to do with it and gives me a information informative message let's try it again and now instead i'm going to pass a name right and no complaints python is happy and now i'm able to say b dot name and i get the name back now this dot name attribute on my objects on each pokemon object that i'm going to create is already going to exist because every yeah on each creation it gets assigned automatically not in this manual way that i did it before on an empty class okay cool so what else do we need for defining one of these pokemons for this simple game another input that you want to have is going to be primary type type okay so in the same way that i did this before with self.name i'm not going to say self.primarytype and then assign it whatever i'm passing when creating the this pokemon the instance of it okay so i have these two things that describe it it has a name i guess it could have a number it could have a couple of other things but i'm gonna keep it simple just with the name and the type for now and we're gonna expand on this in a little later a little down the road okay i was able to take a look at it let's get let's exit this and work a little from within the script and running the script so you could also take a look at it by running this by running the script and printing it out so i can say print and then i need to just like i did in the script before i need to create an instance of it let's do that i can do it directly in the call as well so i'm gonna say this pokemon i'm gonna create an instance of a pokemon i'm gonna give it a name that'll be bulbasaur and i'm going to give it a primary type i type and which is a nice thing to see here as well is that vs code is very helpful and gives me already some suggestions on what i should actually put in there even though this is a class that i wrote myself so it has this introspection and can figure out that it understands i'm making here a pokemon object it understands the class definition before it knows that it needs these two positional arguments and so it already gives me a suggestion to to put them in there right okay and that's going to be grass so now i can go ahead and run this code the script and i'm going to in here in the print call create an instance of a pokemon pass it the two attributes that it needs and then print it out and there it is well but that's not very informative right this looks the same as it did before when we had this empty pokemon object so there's no if i let's let's make another one right let's make another one charmander right and that's fire now if i run this and print both of them there's not a lot of difference that i could see by just printing them out in this way they're both pokemon objects okay that's correct and they are at different they look like they're at the same memory location i'm not sure where where that's the case should be at different memory locations anyways um but there's no way that i could distinguish them even you know like there's just i don't really have much information about it at all which brings up the question what do python objects do to give this informative printouts for example when you remember making a path object right let's look at this for a second yeah and then we created a couple of those so now i'm just going to print one out path object and pass in let's do this.home yeah so i'm making this and if i look at just printing that out i get some much more useful feedback from a path object than i get from my custom pokemon object this is the default and it doesn't tell me much but you can change what comes out in a print call which is what most python objects do they implement something to give more informative output and this something is another dunder method look at that next and it's called dunder string so under sdr again you need to pass this self and in this case nothing else this self just gives me access to these two attributes in here or anything that's defined within the instance of this of this class okay so i want uh to read something else instead of this kind of cryptic feedback um and so whatever i return in here is what's going to get printed out when i call when i call the print function on one of these objects so i'm going to return an f string with these two variables in there and so if i want to access it i have to again honor the namespace right that's the object itself that i'm passing in there so i can say self.name and then maybe in brackets i'm gonna put also the type self.primarytype okay so now if i run this i'm gonna get the information that i actually have and i'm gonna be able to distinguish these two pokemon there you go now i get the name of it and then it brackets the types so now i see that i have two different pokemon objects and that they're actually quite different pokemon cool so that's what you can use the standard string method for again you see it has this double underscores which is kind of telling you that you shouldn't mess with it unless you're the person who actually who actually creates this class okay so um i want to take a chance here also to show you something that's pretty confusing for a couple of people that get started um with python if you have seen this this one there's an autocomplete somewhere i don't have it now so it doesn't matter if dunder name equals equals you might have seen this before and that's something that's pretty confusing for some people who are more used to doing procedural or or functional programming which is what we did in the last two streams essentially like we did if you remember the other two scripts they just all they did was running from top to bottom both of those right they were just executing line by line now in this object oriented way there might be and also when you're working with functional programming more there might be other types of like ways that you want to execute this and you've already seen one here i've been using it by importing the class into a rebel session instead of just running the script right so that might be a way that you want to execute it and you're maybe you're building a game that other people could use as a startup maybe you're just building out a couple of different types of um players in this game like there's pokemon maybe there's some trainers or whatever and you want to give this option this as an opportunity for someone else to build on top of so that they can just say from your poke module import pokemon and trainer for example so it that that in that case you wouldn't be running the script from top to bottom as we've been doing here but instead you allow them to import it and i'll show you now what's the difference in this so i have two i have two these two print calls in here and if i would leave them in there and then import this module somewhere else for example in this interpreter session so i can say import okay you can see that it executes the code that is sitting in here right so i get the printouts of this too and it runs every like all the code that's in there is getting executed so if there's some sort of functionality that you actually don't want to run maybe it's just for testing or maybe it's for when you run the script explicitly then what you want to do is to move it inside of this standard main watch the indentation so because this is just uh it's a co it's just a conditional if statement that checks for something that's part of each script there's like the global name space that has a definition for the standard name variable and if it is main which it is only if you run this script directly so if you press play here then this variable in the global namespace of python is going to be under double underscore main and only then are these two lines of code going to run so i can show you yeah let's show this first here so i press play the output still happens those two objects get created and printed out but it's when i now go inside of the repl and i import it and then you see that the code didn't run this time so before i was just importing it and it ran this code as well but now the namespace the double underscore name isn't main but it's going to be instead this the name of this module and so this code is not gonna run so in case you're encountering this line of code that looks kind of confusing with all these underscores now you maybe have a bit of a better idea of why this is useful and when you would want to use it okay take a look at it i'm going to keep that here and let's think a little more about the functionality because so far we've talked a lot about object-oriented programming but we haven't done much of the game functionality yet so let's bring it back to there what else was the plan two more we want to be able to feed to increase health health and also make them battle and decide for a winner okay so to in order to increase health we're going to have to have some sort of variable that keeps track of the health of of an individual pokemon right it's going to be different for each instance of it but we definitely need some sort of space where we can keep track of that so i will add some variables in here when creating a pokemon and this is going to be we're going to have something called max hp so this is the maximum that it can ever have and then also assign this to a self variable yep max hp and then we can when initializing the pokemon it should just be like it should have some way of counting down the current let's just call it self.hp so what it has at the moment and this can at the beginning when you initialize it it can also be that max hp so we don't we just want it to come into being being all the way healthy right so you see i'm assigning max hp i only need to put this input once and i'm just assigning it to two different variables here max hp and hp and then i'm not going to be changing max hp i'm just going to leave that as is and use it as comparison to how how high up can it get etc but this one i'm gonna uh change in the feed one for example right so um so here's now a second big thing about object-oriented programming so far we've only talked about attributes dot name dot primary type also did two new ones hp and max hp they're all uh they're all attributes to it they don't do anything they're just like a color or a name etc right there an adjective attribute yeah they're called attributes now you also want to want them to have this class to have some functionality and these things are called methods specifically if you make them inside of a class they're called instance methods if they're that's the most common ones if they apply to an instance and take this self as an input so both init and sdr the one the two ones that we made so far there are instance methods on on each pokemon instance now i'm going to make a third one which i will call def feed you see that i'm not using any double underscores here because this is not a python inherent thing this is not like a somewhat private method that you should leave around alone and not access directly but i want someone who plays this game to be able to actually feed the pokemon and give it some berries or whatever to increase the health so that's why i'm not putting any underscores but it's still going to be an instance method so i still need to pass this self and then let's just keep it simple i also could give this one some some some arguments like maybe what type of parry but feel free to work on this game more and like build it out some more if you're interested in it for now i'm just gonna say anything that you feed to it is gonna increase the uh current self.hp by one let's say so i'm gonna say self.hp and i have access to this variable because i'm passing the instance into it and say plus equals 1. all right so that's a very simple implementation of this i can increase health by feeding it this but there is a little bug in this right now because i defined a specific max hp when creating the pokemon so i don't want it to go higher than that so i can just add into this inside of this function and i can say oh it's actually let's run this first and see what's going on maybe i will copy this so it can be a bit faster inside of my repo okay so b python and i'm also gonna from pokey import just a class because that's the only thing i need and then i can create one and i will also need to pass so if i just run it like that i'm going to get an error but because my initialization function is missing a required positional argument called maxhb so let's add this as well max hp is let's say 100 okay so i don't wait because i didn't print it you see so why did i when i just in a rebel if i just uh press this like b and press enter then i still get this kind of like cryptic output and the reason for this i'm not going to go into this too much but there's another one called thunder wrapper i don't know actually how to pronounce this but it's written like this and this is like some defines the representation of the object and this one you could define as well and that's just it's a more um it's a more direct and very specific description of what's the content of this class while the string is more just what's the most important part that you want to show to someone when they print it so if i print this one you see i get the output that we defined in the string okay so i might also want to add here something we're noticing it could be fun to add the hp maybe something like i'm going to say max no hb of max hp max hp there it is and i'm going to need the self for both of those so that it knows which ones to pick okay um so next time i start this it would also print those out i'm not gonna redo it right now but uh by having this feed function defined in here i'm now able to say well let's first look at it actually b dot hp is 100 right now because that's what i gave in as max hp which means that it got assigned also to the current hp now i can use this method and feed it to increase the hp so i can say b dot feed and i need to use these brackets because that's a method that's a method that actually does something on the instance of this object if i don't use the brackets it's just going to tell me about what this is it's going to tell me look you're talking about a bound method called on a pokemon object called feed and it's inside of this module and that object at the specific memory location but that's not what i'm interested in i actually want to execute it i want to feed the pokemon so i say b.feed don't get any feedback but if i now look at b dot hp you see that it increased by one so i can change the state of the data by using one of its um instance methods and you see that this is gonna be like this this is persists throughout like the state of the whole object if i would be using this hp anywhere else and we might want to use it later in when battling then you this is going to be available the feeding is going to influence the hp state that is that is yeah accessible throughout the whole instance of this specific pokemon if that makes sense okay so now but we have this problem we don't want it to go higher than the max hp so i'm going to introduce a conditional here that says if self.hp is smaller than self.maxhb then we will do this otherwise the function is just not going to do anything or why not let's give some feedback otherwise we print out a little string that says self.name and you see i'm reusing all of these variables i can use them anywhere as long as i have access to self name is full and here i can say maybe also given give some sort of feedback self that name has now and then self.hp hp or health or whatever health points let's stick with it okay so this gives us the opportunity to feed and increase the health of each of each instance of pokemons that we would create um and it doesn't you can't feed them to be uh have more hp than they can have in their what's whatever is the maximum hp that you define when you create it cool so we have one part done and now there's another one left which is actually allowing them to battle with each other and deciding for a winner this might be a couple of steps so i'm just going to start off and often off off off with it like this here you go and it it will work in a similar way than this feed function did just i'm going to define that another instance method here and i'm going to call it battle so that we're going to be able able to call b battle and then make something happen right so it again needs to self because it's going to be able to change the state of that specific pokemon is going to be able to it has to be able to decrease the hp for example if it loses or maybe increase it if it wins we can decide what's going to happen so it needs to have access to the self but there's more right i need to be able to interact with a different object a different instance of a pokemon so i also need to have access to another one and i'm just going to call it other this is a default by the way also self is just a it's a default way you could it's just a variable name you could name it anything but it's very very common to name itself and just for readability for you and for other programmers this is just the default that you should use so i'm going to say self and other which means that it's going to take itself as an input like it does here for feed and then inside of the brackets it's going to take another pokemon object another pokemon instance as an as input as well and then we can make something happen in here so let's start by just printing them out and see whether this is working so i'm going to say print out self dot print out i guess self.name and other dot name as well so this requires now you see there is no autocompletion or anything in there because for now vs code doesn't know what is this other gonna be and that's something to be aware of also with python when you write code in there there's no i'm not enforcing that this other that is being passed in here is actually going to be a pokemon object i could pass anything in here but my code the way that i'm writing it right now is going to rely on it actually being a pokemon object so that it will be possible to access the dot name attribute on it and there's ways to make this more secure by type checking which is something that python has introduced to just make sure that there's actually only gonna be a pokemon object that can be passed in here otherwise your code is gonna error and there's other languages that are much more strict about this but python is like you you kinda like like allow for a lot and you catch these kind of things um and and write your code in a way that it's not a problem if someone actually puts in something else and there's a whole bunch of stuff that you can do for this for example writing exceptions or this type checking that i'm not going to go into now because not so much time within an hour all right but let's check this out anyway so i should be able to now get the name of both of these pokemons when they battle maybe let's say battle and then print out both of the names for this let's do it in here and that's a nice thing about using b python that i can cycle through previous commands i get it just now uh 150 maybe it's going to be a different type okay oh so this wasn't smart i over wrote one with the other so now we've now i made it very confusing now b is going to be charmander and c is going to be bubbles or so just for a little confusion adding a bit of confusion in here for both of them i can call and now hb also battle hp okay so this is b is the charmander it has 150 b dot name charmander and c dot name is bubble sorry and now depending on whom i start with i can fight the other ones i can say b dot battle and then i pass in the other pokemon object that i created and i see that now we have a battle between charmander and bulbasaur all right so this is working we can access the second pokemon object in the same way that we access the first one with through this other variable here now we just need to actually get them to battle instead of just printing out the names so for this logic i guess it depends on a bit on uh how you want to implement it there's obviously there's different ways of doing this um i would just say maybe we make it simple so we make it dependent on what type they are whether they're gonna win or lose and i want to break out this functionality on deciding who wins against whom essentially into a separate function that but this function is still going to be part of my class in here right so i will take it out and i'm gonna say i'm gonna call this one just the type wheel or something like that type wheel and this is gonna need as an input type one and type two in order to decide which one which of them wins now you see that i didn't i don't have to put self in here because i don't really need access to the instance in this case i just need to get these two types from the two instances but i'm gonna call the function in here call typewheel right i'm gonna call it from within battle and it's just gonna take instead of self.name and other.name it's to take the primary type attributes of these two different objects and it's going to pass it to this function and the function is then going to decide which of the ones is winning and functions like this that you make part of a class so i still have the indentation here right so it's part of the pokemon class and i needed to be part of it so that this this method can access it and they are called static methods because i don't need the actual i don't need the instance access to the instance so i can just tell it look this is a static method if i wouldn't put this in front of it it might complain that it needs to self in there but because it doesn't need it i can just say no no don't worry about it it's a static method it's just part of the namespace of a pokemon but it could run anywhere otherwise okay and now what are the different options i can say what's going to be the result uh we can i'm going to make a dictionary here and just map a couple of options two numbers i'm going to say 0 is the loose condition and then 1 is going to be the wind can oops it's going to be a number one is a win condition and let's say -1 is a tie if they're from the same type for example um and again actually so let's as in every step where you have a couple of programming pieces that you need to figure out you can always write down your pseudocodes so i want to now i need to figure out like some some mappings between the types and the win conditions or result conditions so i need to do that and there's different ways of doing this um when i looked into it the one that i like as a as a way of implementing this is so called the windows matrix matrix so i'm going to implement this one and then we will also need to declare a winner okay so these are three steps and i'm going to start off with implementing this win-lose matrix i'm going to say um win-lose matrix is going to be a list and this list has a couple of conditions in there so i'm going to i'm going to make this a list of lists a list that contains um other lists and has specific win-lose conditions but for in order for this to make sense i guess we're going to first need to see what what different types exist so i'm going to make a game map here and do this as a dictionary yet again and i'm just going to keep it very simple i'm going to say there's three types there's water which maps to zero there's fire which oops maps to one and then there is grass which maps to two so you can think of this similar to um what uh not tic tac toe the scissors rock paper scissors right so we just need to have some sort of type wheel where it decides this one wins against this one this one wins against this one this one wins against the first one again and now need to implement this in a way so we're gonna need three of these little lists here one for water one for fire and one for grass and in here i want to define the conditions of what's going to happen if they if the two different types battle against each other right so water for for water if water petals against water about the first one then the condition is going to be a tie right so i'm going to say if it's water against water i'm going to have -1 the tie then if it's water against fire then water is going to win so that's going to be a 1. and then if it's water against grass it's two then water is going to lose so there's going to be a zero here right and i can do the same thing for the other ones so this would be zero tie here and wins against this one and this one's gonna win here it's gonna lose here and then tie against itself again okay so um now there's a way that i connected these two the results and the game map with each other and now i can declare a winner using like a little maybe complex seeming list look up so to say so i'm going to look inside of this wl matrix and now i'm going to see okay i'm going to look at the spot let me actually build this in a couple of steps so it's easier to understand so we have a game map and i can this is a dictionary sorry there it is this is a dictionary the game map so i can look up stuff in there and why not let's put a little break point in here maybe we can okay we don't really have the time for this so i'm just going to keep going um so in the game map you can look up the the two types we have like grass or fire or water that's gonna be passed in there and then i i can map these two numbers right and this numbers are gonna help me to look up specific positions uh index positions in the wind lose matrix so on the game map i can say game map at the space of water for example is going to give me zero right this means that in the wind loose matrix i want to look up what happens if water so wind loose matrix t-rex what happens if game map water here something like that right i could put this in here because this is going to go for a number it's going to return 0 1 or 2 which means it's going to refer to either 0 the first list the second list or the third list so like that i have identified the first step so i want to look in here and then inside of that list i want to look up what is it fighting against so the second one which is going to be another lookup to game map but in this case it's going to be for example fire right so that's the second lookup inside of here i want to look up the position so where there would be water and then the minus one so it wins against so this one fire is one right so the zero first position so if we look up game map fire it's gonna go to one and find the wind condition in this case so by adding this another lookup in here game map fire this is essentially going to translate to matrix look up the first one and then inside of the inner list look up the first one and so this result is gonna be uh here one so like this i have decided um i have determined that water is gonna win against fire hope that makes sense it's a little it's a little brain twist in here but try to if you try it again at home then just try to piece it piece it apart and figure out how it works or just build a different type of way that you can decide who wins against whom there's different ways that you can implement this okay but this works i want to return i don't want to return the number i would i didn't want to return the result so i'm going to do another lookup i'm going to say result and look it up at the result of this maybe this is a bit too long so my result is going to be her win lose result let's call it like that it's going be this long string and then i'm gonna look up what that means is it a loose is it a win or is it a tie i'm gonna look that up in the results table again okay so i get rid of this because i don't really need this and of course these two things shouldn't be hard coded right this was just for as an example but now i actually want it to be these two different types so i'm gonna say type one so whoever starts the fight is gonna be type one and whoever gets fought is gonna be type two and these two things these two variables are gonna be the input to the static type will method and then we should be able to get a result that's gonna be one of those strings either lose win or tie okay so that's the static method that can decide it and now we're back to battle where i can just say self dot type wheel i still need to use this self here because static the method is part of the object but i don't need to pass it anything otherwise and instead of giving the names here as we saw that works i can say self.primarytype and primary type okay and then we have a return statement here which should give us back a string so i can assign the output of this to result let's move this one up just say the battle is starting and then we calculate who wins and then print out the result just the result it's not going to make much sense but i can again make a f string that makes this a bit more readable and we need to know who fought self.name for other.name and result and what did i call them and lose wind tie and the and now i can put this into a proper english sentence the result is a win lose or tie anyways so this is not a great english sentence but you get the point of what's going on here okay so now let's give this a spin because we're already over the time so i'm gonna give this a spin and then give you a couple of ideas how you can still improve this let's head back over into the python console and then import create two of them no b okay so i have two pokemon here and now i can make them battle each other so i'm gonna say c dot battle and pass in the other object and then i get some output here it says the battle is between these two bulbasaur fought charmander and the result is the loose which is um accurate with if you think of the types right so bulbasaur is a grass pokemon as we defined it charmander is a fire pokemon so bobossa is not going to win against charmander what if we let them fight the other way i can say b dot battle c charmander fights bulbasaur and then charmander fought bobossa and the result is a win so this seems to work now if we make another instance of another bulbasaur object let's call it x now i can say x dot battle and because i named them so confusingly i have to think about it for a second this is going to be c it's going to be the other bulbasaur object bubble so fought bulbasaur and the result is a tie all right so this is um this would be a very basic way to implement this i wanted to show you still how you can go ahead and inside of the where is it the battle function here you could do more things than just calling the win and lose conditions but you can have some sort of yes i'm going to link up i'm going to link the github too it has a little more implemented there too what you can do additionally for example is you could depending on the result depending on the result have some effects right so you could say if but you could for example say if um equals equals lose then we can say self dot hp minus equals 10. right and then you could also um you can again have a little message that comes here that says [Music] self.name lost and now has self.hb hp right so this would be a loose an effect that happens as a as a loose condition to the to the pokemon that started the fight so to say and um you could implement other things like that you can implement a condition where what happens when the pokemon wins you could maybe gain some um hp because it got happy for winning or whatever and you could implement some sort of conditionals that say if it's below a certain hp it actually can't start a fight etc etc so you can you can like extend your program from here on but i hope you understand that you have some sort of a basis here that uh shows you how it's useful to to use this object-oriented programming let me still run this so that we can see also the results of something like that max xp x 100 and then here 150 i'm going to define these two instead of printing them so this is bobby and this is going to be charm and then we can have a fight that battle charm uh this one's gonna lose here so we can see we're gonna see the output so let me run this as an example you get a syntax error looks like i made a mistake somewhere probably a bracket somewhere so this is just because i'm still inside of the b python interpreter so i couldn't run the code now if i run this now you see some output of the game so it says there's a battle between bubble certain chairman the bubbles are lost and now has only 90 hp also for jammer and result is a loose okay so you see like also you can obviously play a lot with this out with these outputs and make them be much nicer and make more sense than they do right now but yeah this is my this is my general introduction to object-oriented programming in python by building a little game you've seen how to use the init under init function that you saw that you can make objects and then you can persist specific attributes for each of the instances of the objects like just make sure that each of them have specific attributes you can define that with the indeed method that you can that you don't need to pass when you actually instantiate one of these objects then you looked at this down the string as a method that you can use to di to define what gets shown when you print out um and one of your custom objects that you created right then you looked at using instance methods so methods that use the specific instance of of the object that you created and does something with it we built two of those one called feed where you can add some some health back to the pokemon by giving it a berry right and it gives you some output as well and then another one that allows you to battle two pokemon with each other and gives you some sort of output depending on which which of them lost which is in this game it's only dependent on what type they are but feel free to work this out in a more complex way of course and it gives you some sort of feedback again what happens and you see the interesting parts in this that is when you're working with self.something you see that you always have access to the state of the instance that you're working with so this self.hp starts off with the maximum hp but over the course of your program or an interactive game that you're building like this this self.hp could change constantly like you could lose you could decrease the hp when you lose a battle or you could increase it when you feed the pokemon or maybe also if you implement it you could increase it when it wins etc etc and then you also saw a static method that is part of the class but it doesn't actually work with the instance as the other ones do but instead it just has some functionality that would work anywhere also outside of the class but but in this case we want to make it as part of the namespace of the class yeah you also heard about namespaces just like this one is part of the namespace of the class how you can uh how you have a module namespace when you import something and how this is helpful this if done the name equals main is helpful in order to avoid printing out certain things when you just want to import a module and use it in some other code and here we are so yes that's it thanks for listening and thanks for being part of this if you're interested to learn more more python feel free to check out the github like if you want to work more on this code the code is up on github and kim sent the link in the chat and if you want check out the python course check out our courses on the platform platform.codingnomins.co you can get started for free learning there and yeah check out the twitch channel we maybe gonna implement some sort of a weekly hangout where we can code together and where i'm happy for some inputs and some ideas that we can just talk about code together and figure something out um yeah and that's all check out the youtube channel we're gonna have these videos up uh really soon and gonna send out an email to you uh everyone who's on this list so that you can re-watch it if you want to and then i'm also gonna put in a link to the github repo in case you don't have it so that you you will have it with the video as well all right that's all thanks for joining glad you liked it and yeah hope to see you around hey everyone thanks for watching if you enjoyed this video please let us know by liking and subscribing if there's another topic that you'd like to learn more about leave us a comment we would love to hear from you and if you want to become a coding pro visit our website at codynomads.com see you next time you
Info
Channel: CodingNomads
Views: 9,867
Rating: 4.8808513 out of 5
Keywords:
Id: 2AK7j8pIh-0
Channel Id: undefined
Length: 69min 21sec (4161 seconds)
Published: Tue Feb 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.