Code that errors out is likely to kill your program.
That's not good for the end user.
That's not good for you as a programmer, because then someone
else is going to complain to you, which honestly gets a little bit
annoying after a little while.
So we might as well catch what could be a problem and fix it beforehand.
So luckily we have this 'try-except-finally' keywords,
these three keywords here.
Now, what if you're executing some code and it could error
out for multiple reasons.
So let's 'try: 1/0', and we could 'except' this
'Exception as e:', and we can 'print(type(e))', and we can also
print what the error actually is.
Now, this is actually a really nice little, not really a hack,
but it's a nice little way of doing things that I like to do.
So I don't actually know all of Python's internal errors.
There's a lot of them, and it's pretty hard for the average
person to know all of them.
So what I can do, is I can 'try' something, and then 'except' the
'Exception', and if I don't know what that is, this will tell me what it is.
So let's go ahead and run this.
And this says, 'try: 1/0'.
The exception was a 'class'.
So 'e', we did 'print(type(e))'. 'class ZeroDivisionError'.
And the error is, actually the message itself is, "division by zero".
So now we can do this, throw 'ZeroDivisionError' in there
and say, 'print("Cannot divide by zero")'.
And just like that, we now have a nice way of handling this.
So it's going to 'try' to do some code,
the code does not work,
we can catch this, this very specific error, and we can handle it.
And if it's anything else, it will print what it is.
So let's go ahead, comment this out and let's add a dictionary,
and it's going to be a 'person'.
And in here there's going to be, I don't know, a 'course'
that they're enrolled in called "Python for Everybody".
I don't know who's heard of that course, but sounds pretty
good, doesn't it? Maybe. Bad humor.
Anyways. We could try to say 'print(person)', and then I don't
know their favorite food, 'fav_food', because maybe we didn't know
that there isn't a 'fav_food' key in here.
Let's go ahead and execute this, and we get a 'KeyError'.
Now, this one says the dictionary key does not exist, and
the 'KeyError' is actually the key itself.
So now we can 'except' this as well.
'except KeyError: print("Missing key")', and we don't know what tht is,
so let's do 'KeyError as e:',
[no audio]
and let's rerun this.
And it says "Missing key: fav_food".
Now, that's cool that we can change these all together, but
it's not really a realistic example, I guess of trying and catching something.
I mean, it's sort of realistic, but let's do something else
a little more bound to reality.
So let's try to get some user input.
We want two numbers.
We want 'num1 = input(
"Enter the first number: ", and 'num2' is going to be the
exact same thing, but it is going to be, "Enter the second
number: ". Now, what we're going to 'try' here? Well, we actually don't
need to 'try' that at all.
[no audio]
We know that that's not going to fail on us.
But what we want to 'try' here, is let's say casting these numbers,
because we know these are going to come back as strings.
So let's cast these as floats in case someone types 7.5.
We want to be able to support that.
So let's do 'num1 = float(num1)'.
And let's do the same thing with 'num2'.
[no audio]
And let's just go ahead and throw a general exception in here 'as e'
and so we can figure out what it is.
We're going to 'print(type(e))', and then we're going to 'print(e)'.
[no audio]
Now, there could be an error in here.
Someone could type in a string that cannot be turned into a float.
But let's assume that it does work, and the program needs
to continue. So we want a new total in here.
We can say the 'total',
actually, no, we want the division.
So let's say 'div = num1/num2',
and let's try this out.
"Enter the first number: ", let's do 10,
and the second number is going to be 20.
And what we should have done was also printed 'div'.
Let's try that again.
10; 20; 10 / 20 is in fact 0.5.
So that worked out well.
But what if we run this again,
and first number is 10 and someone spells out the word 20, "twenty".
Users can be weird that way.
We get this thing called a 'ValueError:
could not convert the string to float'.
So we now have one that we can 'except' in here.
We have a particular exception that we can catch in here rather.
So except ValueError:
Print whatever the error is. We could print it or we just say
"There was a value error WOOPS".
Let's try that again.
10, 20,
and our program no longer errors out on us.
What if someone says 10 and 0?
Well, now we have a 'ZeroDivisionError'.
We can catch that one as well.
'except ZeroDivisionError:
print("Cannot divide by zero")'.
Simple as that. 10, 0,
and it says, "Cannot divide by zero".
So now essentially, we're on our way to creating a calculator
program. Let's take a look at one more.
Let's say there is a typo in here.
Now, this is actually a bad example for a 'try-except',
but this will show us one more error in here.
So let's do a typo of 'num3',
and let's say that was just a typo.
We meant to say 'num2', but accidentally typed 'num3', that happens.
So your first number is going to be, I don't know, 19
The second one is going to be 56.
And we get a 'NameError' in here.
'num3' is not defined. So we can now go ahead and catch
this as well.
'print("There was an undefined variable somewhere")'.
We could say 'as e', and put that in there.
Let's go ahead and try this again.
10, 34.
"There was an undefined variable
somewhere. name 'num3' is not defined".
Okay, that's pretty cool.
And this is actually a better example of something that
is a little more likely to happen in a Python program because
you will probably be accepting user input to some degree,
and you need to be able to cast data.
So we got to turn the string into a number.
You need to be able to, maybe not check for typos necessarily,
but maybe you don't know what those numbers are going to be,
and if one of those numbers ends up being 0 because
you have a malicious user, you need to be able to catch that
'ZeroDivisionError'.
And if it's anything else, what I like to do is just print
the type and the error so that I can create an exception
for it as I go along.
Now, there's one more thing we can do in here. Two more things
actually. We can do an 'else' statement, and we can do a 'finally'
statement. So 'print', in an 'else' statement if there are no
exceptions, so no exceptions were raised,
this worked out perfectly,
we can say, "Huzzah, success!
We divided and ", and let's turn this
into an f-string.
And 'finally' will always run.
"This will always run no matter what".
[no audio]
Let's try our little program here.
Let's do 75.
Divided by 25 is 3.0. That's correct.
It says, "Huzzah success!
We divided 75 by 25".
And then the 'finally', that kicked in and said, "This will always
run no matter what". And so a 'try-
except-finally' block is a lot like an 'if-elif-else' statement
but it has a slightly different purpose.
So we're not trying to separate our code into different paths,
which is what 'if-else' statement does.
What we're trying to do, is perform some sort of logic,
and if the program has a problem with that, we need to catch
the program's error, not the user's error.
We don't want to direct, we don't want to direct the user flow necessarily.
We want to catch the program error, and when it errors, then
we can sort of move the user into the right direction.
We can make certain assumptions, or we could try things again.
So let's go ahead and let's create a loop that will run forever
until it can successfully divide a number. So let's do
'while True: num1 = input()', we're just going
to ask for number one, and 'num2' is also going to be
input, we're going to ask for a second number.
'num3' variable is going to be 'num1 / num2'.
Now, this is where we would put our 'try' block because we
know that this is likely to run into an error.
Then we could 'except', and in that exception
if it fails for any reason, we could say, "Nope.
Try again".
And let's put a 'print' statement in here.
'print("Make a successful division")'.
[no audio]
Let's go ahead and run this.
[no audio]
It's going to ask for the first number,
10; second number is going to be 0.
Says, "Nope".
Okay, going to ask for that first number again.
10, 10.
Nope. That's not going to work either.
Now, why is that not working?
Well, we said remember, this comes back to loops,
we said, while this is True, this is always True, this will
never, ever change.
So because we know if this is going to cause an error, the
code below it is not going to work in the 'try' block. It's
going to automatically jump out, and jump into the first 'except',
in which case we can say 'break'.
And this cell is actually still trying to run.
Okay. So that was just running infinitely.
So I just went up to 'Kernel', went into 'Interrupt'.
So what I'm going to do here is now rerun this with 'break'.
[no audio]
It's going to ask me for the first number,
10; second number,
let's do 20, and it didn't work.
10 and 10, also not going to work.
Now, we don't know why this is going to work, so, and this is
starting to get, to get a little more realistic here.
Let's go ahead and hit 'Kernel', 'Interrupt'.
And let's 'except' this as an 'Exception as e', and 'print(e)', or
'print(type(e))', and 'print(e)' as well.
And all 'e' is, is a variable for 'Exception' here, and we can
run that inside of our 'except' block.
So let's go ahead and rerun this.
10, 20. 'TypeError'.
Guess what?
You cannot divide a string by string.
Let's go ahead. Interrupt this.
Let's cast this as a 'float'.
Let's rerun it.
10, 20.
Cool. That worked.
10, 0.
Nope. Got a division error in there.
Okay. Let's try that again.
10, 1.
And it worked, dnd then it exited.
So that's a little more of a real life use case of 'try and
except' in a loop that's essentially supposed to run forever
until it's told not to.
Anyways, that is 'try and except'.
If you would like,
and I would like you to,
if you have a couple of minutes, go ahead and give this a shot.
Create a 'try' block, cause some sort of error on purpose.
You can even 'try: 1/0'.
That's a common one.
And then 'except' that particular 'exception',
and then also run an 'else' statement and a 'finally' statement.