 Welcome back everyone. This is Brian. We're going to continue our journey into Python 3 with the exceptions So basically bad things happen and we need to know how to handle them We've already seen that in these videos and I'm sure you've seen it millions of times working with a computer where it just says like Error unknown error acts a denied or you know some other crazy thing But we need to understand a subtle difference here an error occurs mostly at runtime and it belongs to an Uncheck type. This is things like your hardware failing or your network connection dropping or something like that something completely Unexpected that there's really nothing we could do about it exceptions on the other hand a current runtime and compile time and occur mainly by code written by developers meaning we are now creating our own problems So yes, we can write code to defend against errors, but we can never truly Defend 100% against an error like how you defend against your CPU exploding. You just can't your code will stop working Exceptions on the other hand would be like division by zero wrong data types things like that So that's what we're going to really dive into in this video. Also before we begin I'm going to put a simple decorator in here We covered this in a previous video, but just a quick recap in case this looks like ancient Egyptian algebra a Decorator is a function call that is used by another function call to decorate it and basically we have a Inner function that is going to return a function with any number of arguments or keyword arguments and we're simply going to print out When I say print out so you're going to see a bunch of dashes before and a bunch of dashes after we call that function and just for a Little bit of flavor. I put in the function name and we're going to use this on every single function To begin we're going to look at the try except and finally Now this is going to be a little challenging to really wrap your head around it first But what we're really doing here is we're creating some special scopes and those scopes have special reasons for existing So first things first I'm going to create a function called test one We're going to give it parameters of x and y And I'm just immediately going to call pass We're going to go ahead and use our decorator again If you have no idea what a decorator is or if this looks horrible or if you don't understand this watch the previous video I've done on decorators, but basically when we call this it's going to you print Call the function and then print again. That's really all we're doing even though it looks kind of confusing All right, so to dive in here We are going to use fry and you notice we get some options in our IDE Your ID may look vastly different and these look confusing try except try except else Finally so on and so forth. We're going to go over all of these but the first thing I'm just going to do is just try and Got to end it in a colon I'm going to go ahead and pass for the moment drop down and we are going to accept I'm going to pass again Just going to flesh this out and then finally I want to talk about each one of these in turn If you're coming from another language, this is basically a try catch finally So try means we're going to try some code. It may work. It may not so for example, we could say z equals x divided by y and Then we're just going to print out Whoops, we're going to print out. See what I mean. I'm creating my own errors here the result This code looks just well boring. It's just basic division But what could we do here horribly horribly wrong? We could do like a division by zero and because Python isn't really strongly typed We could send non-numerical values to this and crash this whole thing. We've seen this before I've done this in this series before so we're gonna have to defend against that so We want to do Accept which is the basic version of like another languages version of catch And I'm going to actually put that right here as a comment catch. So if you're coming from another language, this is catch It's easier to explain in other languages because it's like catching the ball You're catching the exemption or somebody's dropping the baby and you're catching it before it hits the floor and the program Of course is your baby in this analogy So we're going to keep our program or catch our program before it fails and we're going to now execute some type of logic Something bad happens. Now the problem with this is we don't really know for sure What happened? We just know that something bad happened And we're gonna look at later on in this video how to determine what happened and the take specific acts and actions based on that All right, but right now we're at really really newbie land here. We just want to know something bad happened now finally Finally is going to be called no matter what? So try is an attempt Except is a catch it if it falls, you know something bad happened. We got to catch it before it meets a horrible untimely death and Moving along is what I call finally. It doesn't matter What happens up here finally is going to be called? Let's take a look. So I'm going to just print out Complete and in case you're wondering with my verbal typing Yes, most of the programming bugs are misspellings miss typings things like that or just bad data types things of that nature So let's see this in action We're going to say test one and Let's do five and zero What is immediately standing out that zero very ugly? Let's check it out Oh function test one something bad happened So immediately instead of having a division by zero error in our program crashing we were able to catch it and Do something now? Let's give it another untimely death here. I'm gonna say test one and let's say five and How do you divide five by cats? I'd be really interested in knowing that but let's try it again And sure enough that's one something bad happened five and cats. So we know that it's not doable let's just take this and Let's divide Copy and paste has failed me. There we go. Let's divide five by two and see what we get here So the result is 2.5 So we know our function now works and we can defend against well exceptions The biggest takeaway from this segment of the video is that you have a try which in an attempt Exempt which is a catch and a finally which is going to be called no matter what happens You can see in Each one of these examples Whether something bad happened or successfully ran Finally was called That's your cleanup code. So we're going to change this to clean up So think about this in terms of like io you're going to write to a file You're going to attempt to open the file and write to it something bad happens and then you would close the file regardless There are tons of built-in exceptions and we're looking at the official python documentation And I'm just going to scroll down. We're not going to go through all these because we'll be here all day But there's the generic high level one and then it gets into very specifics like arithmetic buffer Assertions now we're going to talk about assertions right now But I want you to understand what's going on Assertion is not a true error. It's something that we're actually Creating so we're going to assert that a condition is true And if it's true nothing happens if it's false though an error is raised See it raised when an assert statement fails. We're going to do that right now Also understand that you can have tons and tons and tons of these and you can even define your own so Wow lots of information to take in but I'm going to leave a link That out there and we're going to just take Code from the last one and just copy it And we're going to do a bit of surgery here all this test too All right, so we've got our attempt catch and finally and let's kind of change these around a little bit First thing I want to do is add in an else So think of this now like a giant if statement. We're saying if And then if and then else So when we get to else we trust this code and this code should run I don't like doing this Because what happens if something blows up? So then you end up doing another try Exempt block in here and I don't like doing them in line over and over It just gets really messy. So We're going to move that here I'm gonna call this trusted code and personally I don't trust code. I usually do it up here But you'll see this out there where people are gonna say else just do this and when it gets here you trust this implicitly It can do no wrong So attempt Is now something we have to do some testing So we're going to assert Now if you're a parent, you know exactly what an assertion is because you walk up to your child and say you will Clean your room right now And if they do not comply if you get a false back then well bad things happen They get grounded. So we're going to say x is greater than zero Asserts going to go in and evaluate this condition if it's true nothing bad happens. However If it's false bad things happen very quickly meaning It's going to Say it's failed and it's going to raise an assertion error Which we'll call exempt in any other catch condition that we put in here So let's just grab the previous Tests that we had and let's rename these gotta look copy and paste making life simple All right, so we're gonna do five divided by zero five cat five two and let's go ahead and test this out Move this up All right, so we can see now that Our assertions are working so function is test two something bad happened So it's immediately saying assert failed and then printing this out Assert is a powerful tool, but it's not perfect We want to know exactly what happened and we want to be able to handle things on a case by case basis So typically what I'll do is I'll change this to exception as e Or error or whatever you want to put in here And then I will actually add in the issue And then e of course has other properties if you wanted to dive into them, but we're just going to leave it as you We're just going to print e out here and let's clear this out and rerun this See what's going on Okay, so Something bad happened. The issue is That is not supported between instances of string and int. So now we have some sort of typing issue But notice how division by zero never got caught So we have a couple choices here. We can leave that in the catch all or we can do a division by zero error Or we can make a custom error However, we wanted to do it. So if we wanted to catch a specific condition here I'm gonna say except assertion error Then I'm going to say print f And fail to assert x And y When you look at this now, we have two exceptions that we're handling. We have the assertion error and just the general catch all So I'm going to put here specific And you can chain these out to infinity and you can basically do every single error But what I'll do is I'll do Things that I would expect like if I fail an assertion I want to know it's just garbage data the user gave us Or if something higher level happened, I want to be able to catch that But I want to be able to distinguish In the application the difference between the two So if we fail an assertion That's going to get called if something else happens. This is going to get called All right, let's try it out All right, so something bad happened. All right And then failed to assert So you can see the two different ones firing off here Failed to assert meaning we failed our test Assert y greater than zero. Let me see if I can get some room here That failed which triggered this off But then you notice how Why if this was cat greater than zero, how does how does python even begin to evaluate that? It can't So it skips over and says bad things happen. We cannot compare these two. So then it jumps down to The exemption code right here So for our assertion logic, it's going to do this one for other things our catch all is going to get fired off That is actually really Really powerful, but one thing I want to really caution you on is not to go overboard with this So for example, if you try to do like a exempt What am I looking for your type error And then we could just say like wrong type And let's clear and rerun You see now it's saying wrong type x and cat can't be compared But what I'm doing here is my code is getting longer and longer and more and more complex So I would say Look for the specific errors that you absolutely must handle and let everything else fall into a catch all if At a minimum You have just to catch all that's still acceptable, but you want to be able to catch things I rarely use else because now I am completely trusting all of this code to run without any single issue And what happens if we do something like that? I just hit space. There's just a blank space right here Go ahead and clear that out and let's run Notice how our program even though we have all the security baked in has now crashed And my ide is not showing me. Hey, there's a problem right here This is why I tend not to use else Let me go ahead and fix that before we move on and make sure everything's working As you can see this can get very complex. I mean our little function here is now bigger than the screen I've got to either zoom out, which will make the code small and hard for you to read or I've got to Well figure something else out. So we're going to add another complexity here We're going to make a user defined exception and we're going to raise it Meaning we're going to create our own error and then catch it and show why you'd want to do something like that So this is pretty typical in file i o But first off, let's go ahead and make a class and let's call this cat error Because every cat has some kind of error Why not and so cat error is going to inherit a runtime error So we're going to use the built in class runtime error inherit it now we have all of that functionality baked in Let's go ahead and say death And we're going to init self with and args And I'm just gonna say self dot args I always like that word args sounds like a pirate Anyways, we're going to say that is the args so Very very simple class You can feel free to make that as complex as you want, but just know that These error classes are meant to be very short lived the lifespan of these is basically From the time something happened to the time it's caught you don't want these things lingering around Their sole purpose is just to carry information about what happened All right, so i'm going to say at Outline because we're going to use our decorator again And i'm going to define Let's call this test cats And we're going to test a quantity of cats And then i'm going to do a try now you start to understand what all this gibberish IntelliSense was popping up in the very beginning. We can do a try exempt Um, we can do a try exempt else finally, uh, blah blah blah on any other combination I'm just going to pick try except finally And it's going to do the code for us Now I don't really need all of this stuff So i'm going to just change this a little bit To suit my needs IntelliSense is great, but it doesn't always have to be the way they want it to be So now I just have a try except and finally What we're going to do in here is i'm going to say In our try If not Is instance Then we're going to test to make sure that qty is actually an integer Because you could you know hand it a string and we don't want to take some sort of mathematical operation on a string Now if it's not An integer we want to raise Now raise is basically like throwing a ball. We're saying you know what this is an error you go fix it and we're throwing A rock or a ball at a window saying here go catch it And if you don't catch it your program is going to break and crash much like a window would Maybe I just made a joke about microsoft windows. I don't know. Anyways interpret that as you will So we're going to raise some type of error and when I say type of error, I don't mean This the class type error. I mean this could be an assertion error Or anything that inherits basically a error runtime error But for this case, we're going to do a type error because we know that there is a specific issue And then from here, we're going to say Must be an hint So you want to be very careful when you're raising an error that you raise the correct type And this is one of the few times where python really really really cares about the type If you try to raise like a string or something you're going to get some weird results, although I suspect you could probably do it All right, so now we're going to Check for a quantity. So we're going to go back here and say if Qty and if we got to this point, we know Because this has not Been raised We know that this is an integer and we can work with it mathematically So now I can say the quantity is less than nine then Well, who in their right mind would have less than nine cats? So I'm going to raise our cat error And say must own More than nine cats Because I don't know what lunatic in their right mind would have less than nine cats That's why the cat error exists But now what I'm really demonstrating here is we can make our own custom class as long as it inherits the runtime error And we can throw it or you know raise as it's called Just like any other except type Very very cool Okay, so Now that we've got this I'm just going to say print And we're going to format that out. I'm just going to say oops because this is our catchall We're going to say like oops unknown error. Sorry my bad And we're going to say e.args Now for our finally I'm just going to say print Complete Notice how this is much much much much much more streamlined than this big bulky thing up here This is what I'm talking about Air handling can get very complex very fast. So general rule of thumb try to keep it short simple And to the point All right, let's go ahead and test out our cat's class I'm gonna say test cats and we want to There's some crazy person that only has three cats There's some crazy person that has 12.3 cats. I don't know how you would get a 0.3 cats That's kind of gruesome and then we're going to test for 11 cats And we could if we wanted to even just really throw this thing for a curve ball here and say abc Let's clear out our results and fire it off all right, so We see must be an int Must own more than nine cats Must be an int. I mean, so this is now working as expected. So this must be an int must own more than nine cats Must be an int and then ta-da Finally We have some sane person out there who did follow the directions And i'm just going to for clarity You own x number of cats Play this out fire it off one last time You own 11 cats You can see that you own 11 or you own whatever is not in there because we threw and caught the exceptions So whenever you see try think of this like playing baseball or some sport they have the ball And if something happens, they don't like they're going to throw the ball And it's up to something else to catch it And regardless of what happens the sportscaster is going to well call it like these seasons says and we're done folks I hope you enjoyed this video. You can find the source code out on github.com If you need additional help myself and thousands of other developers are hanging out in the void realms facebook group This is a large group with lots of developers and we talk about everything technology related not just the technology that you just watched And if you want official training, I do develop courses out on udemy.com This is official classroom style training if you go out there and the course you're looking for is just simply not there Drop me a note. I'm either working on it or I will actually develop it I will put a link down below for all three of those and as always Help me help you smash that like and subscribe button The more popular these videos become the more I'll create and publish out on youtube. Thank you for watching