WEBVTT

1
00:00:01.310 --> 00:00:02.740
<v ->Hi, guys, and welcome back.</v>

2
00:00:02.740 --> 00:00:05.973
In this video, we're going to learn about errors in Python.

3
00:00:07.020 --> 00:00:10.060
What we've got here is a simple divide function,

4
00:00:10.060 --> 00:00:11.700
that takes in two parameters.

5
00:00:11.700 --> 00:00:13.100
If the divisor is equal to zero,

6
00:00:13.100 --> 00:00:15.740
it prints that it cannot be zero and then returns.

7
00:00:15.740 --> 00:00:19.480
Otherwise, it'll return the dividend divided by the divisor.

8
00:00:19.480 --> 00:00:22.780
If we run this code, you should see that you get a print,

9
00:00:22.780 --> 00:00:25.080
Divisor cannot be zero.

10
00:00:25.080 --> 00:00:28.420
However, if you use this function inside a programme,

11
00:00:28.420 --> 00:00:30.860
potentially, you may encounter a problem,

12
00:00:30.860 --> 00:00:34.640
which is that your programme expects the function to work

13
00:00:34.640 --> 00:00:37.690
and there's nothing in the function that says otherwise,

14
00:00:37.690 --> 00:00:38.960
other than a print statement,

15
00:00:38.960 --> 00:00:41.533
which really is meant for your users to see.

16
00:00:43.520 --> 00:00:46.200
For example, let's say that we've got a set of grades

17
00:00:49.170 --> 00:00:51.353
and we want to calculate the average,

18
00:00:54.790 --> 00:00:56.420
and we have a programme like this one.

19
00:00:56.420 --> 00:00:58.170
Welcome to the average grade programme,

20
00:00:58.170 --> 00:01:00.010
and the average is equal to divide

21
00:01:00.010 --> 00:01:01.500
of some grades by len(grades).

22
00:01:01.500 --> 00:01:03.830
Obviously, not the most useful programme,

23
00:01:03.830 --> 00:01:06.540
but just bare with me while I explain why errors

24
00:01:06.540 --> 00:01:08.450
are useful in Python.

25
00:01:08.450 --> 00:01:11.610
What we're gonna get here, if we run this programme

26
00:01:11.610 --> 00:01:16.153
and we print the average grade is average,

27
00:01:17.550 --> 00:01:20.850
is, of course, the average grade.

28
00:01:20.850 --> 00:01:23.610
It says the average grade is 90.5, that's it.

29
00:01:23.610 --> 00:01:24.603
Now, very good.

30
00:01:25.660 --> 00:01:30.660
However, if we want to print a nicer error message,

31
00:01:30.910 --> 00:01:34.160
we start having to do some pretty crazy stuff,

32
00:01:34.160 --> 00:01:36.510
if we are not using errors.

33
00:01:36.510 --> 00:01:39.780
For example, let's say that we don't have any grades yet.

34
00:01:39.780 --> 00:01:42.810
For example, imagine our programme adds the grades over time

35
00:01:42.810 --> 00:01:44.850
or something like that, and there are no grades.

36
00:01:44.850 --> 00:01:48.555
What you'll get is, welcome to the average grade programme,

37
00:01:48.555 --> 00:01:51.093
divisor cannot be zero, the average grade is none.

38
00:01:52.580 --> 00:01:57.160
Now, not the greatest functionality here in our programme,

39
00:01:57.160 --> 00:02:02.160
and this is caused by this function printing something out

40
00:02:03.210 --> 00:02:05.910
that is essentially just mathematical,

41
00:02:05.910 --> 00:02:09.660
it's unrelated to the context of the programme.

42
00:02:09.660 --> 00:02:12.050
This programme here talks about student grades,

43
00:02:12.050 --> 00:02:15.080
and that's what the user is expecting to read about.

44
00:02:15.080 --> 00:02:17.030
This programme here, or this bit of code here,

45
00:02:17.030 --> 00:02:18.210
talks about mathematics,

46
00:02:18.210 --> 00:02:21.320
whether you can divide a number by zero or not.

47
00:02:21.320 --> 00:02:23.840
Though they are related, but you don't wanna be

48
00:02:23.840 --> 00:02:27.190
printing divisor cannot be zero, when the user is expecting

49
00:02:27.190 --> 00:02:29.023
an average of a bunch of grades.

50
00:02:30.310 --> 00:02:33.820
However, it is the only way that we can do something

51
00:02:33.820 --> 00:02:37.910
unless we check for the divisor being zero out here.

52
00:02:37.910 --> 00:02:42.070
So if we say, if len(grades) equal zero,

53
00:02:42.070 --> 00:02:44.190
then you can say you don't have any grades.

54
00:02:44.190 --> 00:02:46.263
You don't have grades yet.

55
00:02:48.150 --> 00:02:50.660
Or we could do this instead, and then,

56
00:02:50.660 --> 00:02:53.440
if you want, you can also put that same check here,

57
00:02:53.440 --> 00:02:54.800
you don't need this return.

58
00:02:54.800 --> 00:02:56.700
But as you can see, this is getting a little bit messy now,

59
00:02:56.700 --> 00:03:01.700
because you are removing logic from a division function

60
00:03:01.740 --> 00:03:03.240
that really should be in there,

61
00:03:03.240 --> 00:03:04.453
or it could be in there,

62
00:03:05.370 --> 00:03:06.880
and putting it in your main programme.

63
00:03:06.880 --> 00:03:08.400
It's making your main programme longer,

64
00:03:08.400 --> 00:03:10.010
it's making your function shorter,

65
00:03:10.010 --> 00:03:11.683
but it's doing a bit less.

66
00:03:13.033 --> 00:03:16.840
This function here would check for division by zero,

67
00:03:16.840 --> 00:03:18.400
and then do something a bit more useful,

68
00:03:18.400 --> 00:03:19.800
rather than print think out.

69
00:03:21.290 --> 00:03:24.580
So, here come the errors.

70
00:03:24.580 --> 00:03:28.440
In Python, errors are often used for flow control,

71
00:03:28.440 --> 00:03:30.430
very much like if statements.

72
00:03:30.430 --> 00:03:34.260
Though, by allowing your functions to raise errors,

73
00:03:34.260 --> 00:03:36.380
you're going to then be able to catch them

74
00:03:36.380 --> 00:03:39.240
in your code and handle them.

75
00:03:39.240 --> 00:03:41.963
Here's what we're gonna do, if divisor == 0,

76
00:03:43.420 --> 00:03:45.630
now we are going to raise something

77
00:03:45.630 --> 00:03:47.410
called a ZeroDivisionError,

78
00:03:47.410 --> 00:03:49.220
which is a error that comes with Python,

79
00:03:49.220 --> 00:03:52.433
and you're gonna say divisor cannot be zero.

80
00:03:53.360 --> 00:03:57.440
Now, this message here inside the brackets means

81
00:03:57.440 --> 00:04:01.153
that this error is going to have a message attached to it.

82
00:04:02.150 --> 00:04:04.200
And what we're doing here is we're saying raise,

83
00:04:04.200 --> 00:04:05.490
the keyword raise and a space,

84
00:04:05.490 --> 00:04:08.100
and then the exception name or the error name,

85
00:04:08.100 --> 00:04:10.230
exception and errors are the same thing,

86
00:04:10.230 --> 00:04:11.280
and then the bracket.

87
00:04:11.280 --> 00:04:14.880
So we're creating an exception object in here.

88
00:04:14.880 --> 00:04:17.833
This is another class that is defined inside Python.

89
00:04:18.980 --> 00:04:22.800
So if we try now to divide the sum of grades

90
00:04:22.800 --> 00:04:25.850
by the len of grades, knowing that there are no grades,

91
00:04:25.850 --> 00:04:28.040
what you're gonna get is,

92
00:04:28.040 --> 00:04:30.190
welcome to the average grade programme.

93
00:04:30.190 --> 00:04:34.720
And then you're going to get a very nice traceback.

94
00:04:34.720 --> 00:04:37.260
So let me just make that a bit bigger for you.

95
00:04:37.260 --> 00:04:41.160
A traceback shows you where the problem happened.

96
00:04:41.160 --> 00:04:45.760
And here it says that the last set of lines here

97
00:04:45.760 --> 00:04:48.460
tells you where the error originated,

98
00:04:48.460 --> 00:04:50.740
and it says it originated in code.py,

99
00:04:50.740 --> 00:04:52.250
which is our file, line three,

100
00:04:52.250 --> 00:04:55.730
which is this one here, in the divide function.

101
00:04:55.730 --> 00:04:58.540
And the problem was that you raised the error yourself.

102
00:04:58.540 --> 00:05:01.190
So because you raised an error the error happened.

103
00:05:01.190 --> 00:05:02.480
If you didn't raise the error

104
00:05:02.480 --> 00:05:03.940
the error wouldn't have happened,

105
00:05:03.940 --> 00:05:05.835
so that it what it's telling you there.

106
00:05:05.835 --> 00:05:08.510
And then it's saying that the next thing up,

107
00:05:08.510 --> 00:05:11.220
what called this divide function,

108
00:05:11.220 --> 00:05:13.720
was this line here, line 11.

109
00:05:13.720 --> 00:05:15.000
And it's showing you the line there

110
00:05:15.000 --> 00:05:17.870
that caused this function to be called,

111
00:05:17.870 --> 00:05:19.220
which then caused the exception.

112
00:05:19.220 --> 00:05:21.150
So you can see how it bubbles up,

113
00:05:21.150 --> 00:05:23.070
and in our case it's only got two lines here,

114
00:05:23.070 --> 00:05:24.870
but sometimes these can be really long,

115
00:05:24.870 --> 00:05:26.500
and they can tell you, this called that

116
00:05:26.500 --> 00:05:27.567
and that called that, and that called that,

117
00:05:27.567 --> 00:05:29.890
and so on, and eventually an error happened.

118
00:05:29.890 --> 00:05:30.990
And what you've got at the very end

119
00:05:30.990 --> 00:05:33.670
is the error itself, a ZeroDivisionError,

120
00:05:33.670 --> 00:05:34.943
divisor cannot be zero.

121
00:05:36.020 --> 00:05:38.630
Clearly we don't wanna be showing our users this,

122
00:05:38.630 --> 00:05:41.930
but this is excellent and really helpful

123
00:05:41.930 --> 00:05:42.860
for when you're coding.

124
00:05:42.860 --> 00:05:45.640
So errors help you track down problems

125
00:05:45.640 --> 00:05:47.690
and where and why they happened.

126
00:05:47.690 --> 00:05:51.540
So errors give developers a great tool for debugging,

127
00:05:51.540 --> 00:05:53.170
or finding where the problem is.

128
00:05:53.170 --> 00:05:56.840
So that's one great plus of using errors.

129
00:05:56.840 --> 00:06:00.220
The other thing is that now you can catch the error.

130
00:06:00.220 --> 00:06:03.430
You can say, okay, if an error happens in this line

131
00:06:03.430 --> 00:06:05.440
I wanna do something.

132
00:06:05.440 --> 00:06:09.300
And the syntax for that in Python is a try-except block.

133
00:06:09.300 --> 00:06:11.740
So we're going to try to do that,

134
00:06:11.740 --> 00:06:14.790
and then if a ZeroDivisionError happens,

135
00:06:14.790 --> 00:06:18.713
then we can print, there are no grades yet in your list.

136
00:06:21.450 --> 00:06:24.270
So, try, and then in an indented block,

137
00:06:24.270 --> 00:06:25.800
we put the code that we wanna try,

138
00:06:25.800 --> 00:06:27.940
this can be one line or it can be many lines.

139
00:06:27.940 --> 00:06:31.410
And then in the same indentation level as the try,

140
00:06:31.410 --> 00:06:34.190
we put except and the type of exception

141
00:06:34.190 --> 00:06:35.850
that we wanna look out for.

142
00:06:35.850 --> 00:06:38.800
If this exception happens in this code,

143
00:06:38.800 --> 00:06:41.290
then we will run this stuff here.

144
00:06:41.290 --> 00:06:46.180
So now our code can handle this ZeroDivisionError,

145
00:06:46.180 --> 00:06:48.570
meaning that if we get a ZeroDivisionError,

146
00:06:48.570 --> 00:06:51.140
we're not going to print the traceback,

147
00:06:51.140 --> 00:06:53.810
we are not going to print divisor cannot be zero.

148
00:06:53.810 --> 00:06:56.530
We are going to print, there are no grades yet in your list.

149
00:06:56.530 --> 00:06:58.830
However, if you use the divide function

150
00:06:58.830 --> 00:06:59.980
somewhere else in your programme

151
00:06:59.980 --> 00:07:03.370
and you don't wrap it in a try-except block,

152
00:07:03.370 --> 00:07:05.510
the error will still happen and the divisor cannot be zero

153
00:07:05.510 --> 00:07:08.173
will still be printed out, and the traceback.

154
00:07:09.060 --> 00:07:12.040
So this allows you to handle these errors

155
00:07:12.040 --> 00:07:13.810
in different ways throughout your programme,

156
00:07:13.810 --> 00:07:16.250
which means that this divide function

157
00:07:16.250 --> 00:07:19.530
is concerned about the mathematics of division,

158
00:07:19.530 --> 00:07:21.120
this piece of code here is concerned

159
00:07:21.120 --> 00:07:22.750
about how to handle the mathematics

160
00:07:22.750 --> 00:07:24.550
in the context of your programme,

161
00:07:24.550 --> 00:07:26.850
which is there are no grades yet in your list.

162
00:07:27.760 --> 00:07:28.967
Notice that here in the except block

163
00:07:28.967 --> 00:07:32.680
you can do as e, and what this does in Python

164
00:07:32.680 --> 00:07:35.340
is it creates a variable called e,

165
00:07:35.340 --> 00:07:39.130
and puts inside it the value of the error, if there is one.

166
00:07:39.130 --> 00:07:42.970
So if the ZeroDivisionError is created with this message,

167
00:07:42.970 --> 00:07:44.990
then e will contain that.

168
00:07:44.990 --> 00:07:46.450
And e can be anything you want,

169
00:07:46.450 --> 00:07:48.060
so you can call it exception,

170
00:07:48.060 --> 00:07:50.910
or you can call it e, or you can call it Bob if you want.

171
00:07:51.760 --> 00:07:53.740
And we can print e as well, if you like,

172
00:07:53.740 --> 00:07:58.740
just to see what happens, and what you get is this stuff.

173
00:07:58.750 --> 00:08:01.490
So you get there are no grades yet in your list,

174
00:08:01.490 --> 00:08:04.123
and you get divisor cannot be zero.

175
00:08:06.100 --> 00:08:09.133
Afterwards, because there was an error in this line,

176
00:08:10.440 --> 00:08:12.780
the average variable was never created,

177
00:08:12.780 --> 00:08:14.660
because this caused the error,

178
00:08:14.660 --> 00:08:16.843
which means our code jumped directly here.

179
00:08:17.780 --> 00:08:21.913
So, when you run line 17, the variable does not exist.

180
00:08:22.890 --> 00:08:27.120
Therefore, you may wanna put your variable in the same block

181
00:08:27.120 --> 00:08:28.960
as your variable definition.

182
00:08:28.960 --> 00:08:31.940
Now running that will give you,

183
00:08:31.940 --> 00:08:33.210
welcome to the average grade programme,

184
00:08:33.210 --> 00:08:36.060
divisor cannot be zero, there are no grades in your list.

185
00:08:37.410 --> 00:08:40.430
If you remove this print e, then that will get rid of

186
00:08:40.430 --> 00:08:43.230
the divisor cannot be zero, and you'll get,

187
00:08:43.230 --> 00:08:44.310
Welcome to the average grade programme,

188
00:08:44.310 --> 00:08:46.540
there are no grades yet in your list.

189
00:08:46.540 --> 00:08:48.030
This is exactly what we wanted,

190
00:08:48.030 --> 00:08:50.870
and using errors allows our programme to handle

191
00:08:50.870 --> 00:08:52.860
both the maths of the operation

192
00:08:52.860 --> 00:08:55.303
and also the programme context.

193
00:08:56.680 --> 00:08:58.162
As well as ZeroDivisionErrors,

194
00:08:58.162 --> 00:09:00.440
there's a whole bunch more built-in errors,

195
00:09:00.440 --> 00:09:01.690
errors that come with Python,

196
00:09:01.690 --> 00:09:04.000
that you can create for different things.

197
00:09:04.000 --> 00:09:06.300
All errors are handled the same way,

198
00:09:06.300 --> 00:09:08.040
but when you see in your programme

199
00:09:08.040 --> 00:09:10.070
that a ZeroDivisionError has happened,

200
00:09:10.070 --> 00:09:11.540
it tells you that you probably tried

201
00:09:11.540 --> 00:09:13.350
to divide something by zero.

202
00:09:13.350 --> 00:09:14.630
Know there are other types of errors,

203
00:09:14.630 --> 00:09:17.300
so that you as the programmer can more easily tell

204
00:09:17.300 --> 00:09:19.010
what happened and what went wrong.

205
00:09:19.010 --> 00:09:21.650
Some examples are a TypeError,

206
00:09:21.650 --> 00:09:23.010
or when something was the wrong type,

207
00:09:23.010 --> 00:09:26.330
and you would raise a TypeError, that.

208
00:09:26.330 --> 00:09:28.900
You've got ValueError, or when something

209
00:09:28.900 --> 00:09:31.560
had the wrong value, or an unexpected value.

210
00:09:31.560 --> 00:09:35.350
You've got RuntimeError, or most other things.

211
00:09:35.350 --> 00:09:37.990
And you can also create your own errors,

212
00:09:37.990 --> 00:09:40.250
but we're going to be doing that in the next video.

213
00:09:40.250 --> 00:09:44.170
Finally, instead of putting this line of code here

214
00:09:44.170 --> 00:09:48.860
together with the try, you can actually put it afterwards,

215
00:09:48.860 --> 00:09:53.770
but tell Python to only run it if this succeeded.

216
00:09:53.770 --> 00:09:54.950
So the way you do that in Python

217
00:09:54.950 --> 00:09:58.220
is you put an else, actually, in there.

218
00:09:58.220 --> 00:10:01.180
And you put this line of code in here.

219
00:10:01.180 --> 00:10:04.420
So this is a different way of running that same code,

220
00:10:04.420 --> 00:10:07.800
and what happens here is you try to run this,

221
00:10:07.800 --> 00:10:10.420
if an error happened then you run this,

222
00:10:10.420 --> 00:10:13.600
and if no error happened that means that this line of code

223
00:10:13.600 --> 00:10:17.410
ran successfully, then you run this.

224
00:10:17.410 --> 00:10:20.330
So the reason why we may wanna use the else,

225
00:10:20.330 --> 00:10:22.550
instead of putting this line of code here,

226
00:10:22.550 --> 00:10:26.130
is if we want to catch some specific errors

227
00:10:26.130 --> 00:10:28.240
in a specific line of code, and we don't wanna put

228
00:10:28.240 --> 00:10:31.470
all of our code in the same block.

229
00:10:31.470 --> 00:10:34.110
Finally, if you wanna run a piece of code always,

230
00:10:34.110 --> 00:10:36.850
no matter whether there is an error, or no error,

231
00:10:36.850 --> 00:10:39.820
you can use the finally clause here

232
00:10:41.460 --> 00:10:42.790
to print something else out,

233
00:10:42.790 --> 00:10:44.110
or you need to do anything else.

234
00:10:44.110 --> 00:10:45.920
So these are the different clauses,

235
00:10:45.920 --> 00:10:50.313
try, except, else and finally, and they run in that order.

236
00:10:51.200 --> 00:10:56.200
You can have multiple except clauses if you want.

237
00:10:56.860 --> 00:10:59.770
For example, if this function here could raise

238
00:10:59.770 --> 00:11:02.440
a ZeroDivisionError, or potentially somewhere else,

239
00:11:02.440 --> 00:11:03.950
it could raise a ValueError,

240
00:11:03.950 --> 00:11:05.710
you can catch them separately,

241
00:11:05.710 --> 00:11:07.923
and handle them differently if you want.

242
00:11:09.090 --> 00:11:10.270
I'm just showing you the syntax there,

243
00:11:10.270 --> 00:11:13.840
but we're gonna look as some examples in just a moment.

244
00:11:13.840 --> 00:11:16.160
Imagine you have a list of students

245
00:11:16.160 --> 00:11:18.163
and each one has a bunch of grades,

246
00:11:18.163 --> 00:11:21.890
here is when using this function might come in handy.

247
00:11:21.890 --> 00:11:23.330
'Cause you've got Bob, Rolf, and Jen,

248
00:11:23.330 --> 00:11:25.730
and Rolf doesn't have any grades.

249
00:11:25.730 --> 00:11:29.380
Though we can try to iterate over the student's list,

250
00:11:29.380 --> 00:11:31.670
get the name and grades, and calculate the average

251
00:11:31.670 --> 00:11:35.250
for a given student, printing their average afterwards.

252
00:11:35.250 --> 00:11:38.090
Of course, Rolf's average will fail,

253
00:11:38.090 --> 00:11:40.600
though we can except in a ZeroDivisionRrror,

254
00:11:40.600 --> 00:11:44.220
and say, error, Rolf has no grades.

255
00:11:44.220 --> 00:11:46.440
Otherwise, if all of them have grades,

256
00:11:46.440 --> 00:11:48.770
we can print that all the student averages

257
00:11:48.770 --> 00:11:51.750
were calculated and finally at the end, no matter what,

258
00:11:51.750 --> 00:11:54.900
we can print the end of the student average calculation.

259
00:11:54.900 --> 00:11:56.800
So if we run this we will encounter an error,

260
00:11:56.800 --> 00:12:00.760
we will print Bob's average and then Rolf will error as out.

261
00:12:00.760 --> 00:12:03.710
Note, Bob averaged 82.5 and we get an error,

262
00:12:03.710 --> 00:12:05.110
Rolf has no grades.

263
00:12:05.110 --> 00:12:08.960
But if we put a grade for Rolf and we press play again,

264
00:12:08.960 --> 00:12:11.060
now you see that all of them run to completion

265
00:12:11.060 --> 00:12:12.510
and we get back a message saying

266
00:12:12.510 --> 00:12:14.790
that all student averages were calculated,

267
00:12:14.790 --> 00:12:17.120
because that's in our else.

268
00:12:17.120 --> 00:12:20.890
So to recap, a try allows you to run a piece of code,

269
00:12:20.890 --> 00:12:24.100
then you can catch or except some exception,

270
00:12:24.100 --> 00:12:25.760
or multiple exceptions if you want,

271
00:12:25.760 --> 00:12:28.660
handling them in that block of code.

272
00:12:28.660 --> 00:12:31.160
The else keyword, together with try and except,

273
00:12:31.160 --> 00:12:34.960
allows you to run some code if there are no errors.

274
00:12:34.960 --> 00:12:37.470
And finally, you can run a piece of code at the very end,

275
00:12:37.470 --> 00:12:40.340
no matter what, whether there's an error, or not,

276
00:12:40.340 --> 00:12:41.590
in case you wanna print a message,

277
00:12:41.590 --> 00:12:43.140
or do some clean up at the end.

278
00:12:44.030 --> 00:12:46.110
That's it for this video, thank you for joining me,

279
00:12:46.110 --> 00:12:47.760
and I'll see you in the next one.

