1
00:00:05,400 --> 00:00:07,580
In this video, we're going to take a break

2
00:00:07,580 --> 00:00:10,450
from databases, and we're gonna look at exceptions

3
00:00:10,450 --> 00:00:13,370
and exception handling in Python.

4
00:00:13,370 --> 00:00:16,650
Let's start by creating a new project.

5
00:00:16,650 --> 00:00:19,020
You should always select Python, as always.

6
00:00:19,020 --> 00:00:23,190
Next, and we're gonna call this project ExceptionHandling.

7
00:00:30,730 --> 00:00:33,480
Okay, and let's create a new file

8
00:00:34,450 --> 00:00:36,950
in the project, and we'll call that Examples.

9
00:00:36,950 --> 00:00:39,120
New Python file, Examples.

10
00:00:41,910 --> 00:00:44,060
Okay, let's go to full screen.

11
00:00:44,060 --> 00:00:46,570
All right, so let's experiment with some code.

12
00:00:46,570 --> 00:00:49,180
Now, there's two types of errors we can get.

13
00:00:49,180 --> 00:00:52,730
There's syntax errors and exceptions.

14
00:00:52,730 --> 00:00:54,750
Now, syntax errors, I'm sure you've seen before,

15
00:00:54,750 --> 00:00:57,360
are where we make a mistake in the code.

16
00:00:57,360 --> 00:00:58,800
As an example, if I type something like

17
00:00:58,800 --> 00:01:00,470
x equals 8 equals 5,

18
00:01:02,620 --> 00:01:05,120
instead of x equals 8 minus 5,

19
00:01:05,120 --> 00:01:06,700
we actually get a syntax error.

20
00:01:06,700 --> 00:01:09,280
If I actually try and run this,

21
00:01:10,260 --> 00:01:11,240
we get this error over here,

22
00:01:11,240 --> 00:01:14,320
which I'll just change to the bottom.

23
00:01:15,800 --> 00:01:19,230
We can see we got the error: can't assign to literal.

24
00:01:19,230 --> 00:01:21,720
Now, we can fix these types of errors, obviously,

25
00:01:21,720 --> 00:01:25,330
by fixing our code so that it's valid part in code,

26
00:01:25,330 --> 00:01:29,080
and then of course, the programme is gonna run.

27
00:01:31,330 --> 00:01:33,280
Okay, no surprises there,

28
00:01:33,280 --> 00:01:35,400
but when our programmes are running, though,

29
00:01:35,400 --> 00:01:37,860
we may actually get other errors as a result

30
00:01:37,860 --> 00:01:40,040
of flaws in the code's logic,

31
00:01:40,040 --> 00:01:42,650
or conditions that we couldn't predict.

32
00:01:42,650 --> 00:01:45,860
For example, we might attempt to create a new database,

33
00:01:45,860 --> 00:01:49,880
but there isn't enough space on the drive that we specify.

34
00:01:49,880 --> 00:01:52,500
These types of errors are exceptions.

35
00:01:52,500 --> 00:01:53,640
In the next few videos, we're going

36
00:01:53,640 --> 00:01:56,610
to look at dealing with them when they happen.

37
00:01:56,610 --> 00:01:58,600
Now, the thing to remember is if you don't handle

38
00:01:58,600 --> 00:02:01,490
an exception in your code when it occurs,

39
00:02:01,490 --> 00:02:03,210
then the programme actually crashes,

40
00:02:03,210 --> 00:02:05,210
and that's almost always not a good thing

41
00:02:05,210 --> 00:02:07,030
from a user's perspective.

42
00:02:07,030 --> 00:02:08,710
Now, it turns out that it is very easy

43
00:02:08,710 --> 00:02:11,270
to generate an exception.

44
00:02:11,270 --> 00:02:13,140
We can come up here, and on the second line,

45
00:02:13,140 --> 00:02:17,800
I can put something like y equals x divided by 0,

46
00:02:17,800 --> 00:02:20,050
and if I run that, we should see an error,

47
00:02:20,050 --> 00:02:22,800
an exception, rather, a ZeroDivisionError.

48
00:02:22,800 --> 00:02:24,610
You can see we've got just that on line two,

49
00:02:24,610 --> 00:02:27,580
ZeroDivisionError: division by zero.

50
00:02:27,580 --> 00:02:29,960
If we don't handle an exception,

51
00:02:29,960 --> 00:02:32,260
it is called an unhandled exception,

52
00:02:32,260 --> 00:02:34,770
and execution of the programme stops,

53
00:02:34,770 --> 00:02:37,070
as you can see has happened in this case.

54
00:02:37,070 --> 00:02:39,960
Python then prints out the details of the exception

55
00:02:39,960 --> 00:02:43,200
and a stack trace showing where the exception occurred.

56
00:02:43,200 --> 00:02:45,900
In our case, as you can see, it was on line two,

57
00:02:45,900 --> 00:02:48,280
and the exception details are, again,

58
00:02:48,280 --> 00:02:51,570
ZeroDivisionError: division by zero.

59
00:02:51,570 --> 00:02:54,380
This first part over here before the colon

60
00:02:54,380 --> 00:02:58,150
is the type of the exception, its name, if you like,

61
00:02:58,150 --> 00:03:02,340
but the details after the colon are the extra information

62
00:03:02,340 --> 00:03:05,480
added to the exception when it occurs.

63
00:03:05,480 --> 00:03:08,440
In this particular case, it's quite a simple description,

64
00:03:08,440 --> 00:03:10,370
but you can add the values of variables

65
00:03:10,370 --> 00:03:12,050
to the exception, if you want.

66
00:03:12,050 --> 00:03:13,160
We'll be seeing how to do that

67
00:03:13,160 --> 00:03:17,090
when we raise our own exceptions a little bit later.

68
00:03:17,090 --> 00:03:19,060
You can get a list of all the built-in exceptions

69
00:03:19,060 --> 00:03:20,890
by going to this link.

70
00:03:26,500 --> 00:03:28,610
There's quite a few exceptions as you can see here,

71
00:03:28,610 --> 00:03:29,970
so I'm scrolling down.

72
00:03:29,970 --> 00:03:30,890
I'm certainly not going to attempt

73
00:03:30,890 --> 00:03:34,580
to go through them all now, but this page is useful

74
00:03:34,580 --> 00:03:35,980
because it goes into the mechanics

75
00:03:35,980 --> 00:03:38,370
of exception handling in great detail,

76
00:03:38,370 --> 00:03:41,060
but I recommend you don't read through it just yet,

77
00:03:41,060 --> 00:03:44,940
because much of it will be quite confusing at first.

78
00:03:44,940 --> 00:03:46,980
It is interesting to skip through or skim through

79
00:03:46,980 --> 00:03:50,150
the list of exceptions in section 5.2.

80
00:03:51,220 --> 00:03:52,470
Down here.

81
00:03:52,470 --> 00:03:53,940
Really just to, more or less, get a feel

82
00:03:53,940 --> 00:03:56,650
for the sorts of exceptions that are available

83
00:03:56,650 --> 00:03:59,060
for you to check in your code.

84
00:03:59,060 --> 00:04:03,150
Now, as I scroll through, one interesting one,

85
00:04:03,150 --> 00:04:07,640
as we scroll through here, is this RecursionError.

86
00:04:07,640 --> 00:04:11,570
Now, back in section 11, we looked at recursive functions,

87
00:04:11,570 --> 00:04:15,050
and wrote a recursive function to generate factorials.

88
00:04:15,050 --> 00:04:17,390
Now, if you tried to run that with large numbers,

89
00:04:17,390 --> 00:04:20,870
above 1,000 would've done it, then the stack overflows,

90
00:04:20,870 --> 00:04:23,250
and you end up with a RecursionError.

91
00:04:23,250 --> 00:04:25,590
Let's try and do that again.

92
00:04:28,370 --> 00:04:29,610
Now, it's only a few lines of code,

93
00:04:29,610 --> 00:04:31,170
so I'm just going to type it in again,

94
00:04:31,170 --> 00:04:33,410
but if you've got the code from section 11

95
00:04:33,410 --> 00:04:36,710
in the video Name Spaces: More On Scope and Recursion,

96
00:04:36,710 --> 00:04:39,610
you can grab it from there if you prefer not to type it in.

97
00:04:39,610 --> 00:04:43,780
I'm gonna type it in, def factorial(n):,

98
00:04:45,670 --> 00:04:47,700
and then we wanna do just a reminder

99
00:04:47,700 --> 00:04:51,030
that the factorial n can also be defined

100
00:04:53,090 --> 00:04:55,010
as n times n, take one,

101
00:05:01,520 --> 00:05:03,930
and calculates n recursively.

102
00:05:06,760 --> 00:05:08,030
This is essentially what we're doing here.

103
00:05:08,030 --> 00:05:09,890
All right, so in terms of the code,

104
00:05:09,890 --> 00:05:14,050
it's if n is less than or equal to one, return one,

105
00:05:15,370 --> 00:05:17,870
else return n times factorial,

106
00:05:22,900 --> 00:05:23,820
n take one.

107
00:05:25,170 --> 00:05:26,020
Now, we can actually try this

108
00:05:26,020 --> 00:05:30,190
by doing a print factorial, and let's start with 50.

109
00:05:34,580 --> 00:05:36,390
That actually runs without any error,

110
00:05:36,390 --> 00:05:40,480
so let's change that to a larger number, say 900.

111
00:05:43,500 --> 00:05:45,030
We can see we've now got a huge number here,

112
00:05:45,030 --> 00:05:46,600
but it has still worked.

113
00:05:46,600 --> 00:05:49,090
Now, this may or may not work on your system.

114
00:05:49,090 --> 00:05:50,990
It really does depend on how much memory

115
00:05:50,990 --> 00:05:52,940
you've allocated for IntelliJ.

116
00:05:52,940 --> 00:05:56,050
If you get a RecursionError already, that's fine,

117
00:05:56,050 --> 00:05:59,120
but on my system, obviously, it's working with 900,

118
00:05:59,120 --> 00:06:01,010
and we obviously have this huge number printed.

119
00:06:01,010 --> 00:06:02,830
I'll come back to that in a moment.

120
00:06:02,830 --> 00:06:06,430
All right, so let's actually try a thousand now.

121
00:06:06,430 --> 00:06:08,570
Gonna run that again.

122
00:06:08,570 --> 00:06:09,950
We actually get this error now,

123
00:06:09,950 --> 00:06:13,250
RecursionError: maximum recursion depth

124
00:06:13,250 --> 00:06:15,790
exceeded in comparison.

125
00:06:15,790 --> 00:06:19,150
Now, in this case, there's not really a lot we can do

126
00:06:19,150 --> 00:06:21,430
to fix this problem, unless we rewrite

127
00:06:21,430 --> 00:06:23,230
our factorial function, of course,

128
00:06:23,230 --> 00:06:26,720
but what we can do is prevent the programme from crashing.

129
00:06:26,720 --> 00:06:29,230
The way we wanna do that is come down here,

130
00:06:29,230 --> 00:06:32,650
and on line nine, you type in try, colon,

131
00:06:33,570 --> 00:06:35,770
then we add our print on that line.

132
00:06:35,770 --> 00:06:40,110
I'm going to initially change that back to 900.

133
00:06:40,110 --> 00:06:43,830
Then I'll come down here and type except,

134
00:06:43,830 --> 00:06:45,500
then RecursionError.

135
00:06:47,380 --> 00:06:50,470
Print, "This programme cannot calculate

136
00:06:51,540 --> 00:06:53,540
"factorials that large."

137
00:06:57,920 --> 00:07:02,000
Then here I'll do a print, "Programme terminating."

138
00:07:03,960 --> 00:07:06,740
All right, so what I've done there is put the code

139
00:07:06,740 --> 00:07:10,730
that's likely to raise an exception into a try block.

140
00:07:10,730 --> 00:07:13,910
We did that by starting this new block with the try keyword.

141
00:07:13,910 --> 00:07:17,840
Now, the code that's in between the try and the except

142
00:07:17,840 --> 00:07:20,410
is executed, and runs as per normal.

143
00:07:20,410 --> 00:07:23,750
If everything works fine, then the code that appears

144
00:07:23,750 --> 00:07:27,410
after this except line is skipped,

145
00:07:27,410 --> 00:07:29,680
and the programme continues to run.

146
00:07:29,680 --> 00:07:32,980
However, if an exception is raised inside the try clause,

147
00:07:32,980 --> 00:07:36,400
execution will jump straight to this code that's immediately

148
00:07:36,400 --> 00:07:39,400
after the except line, or the except clause.

149
00:07:39,400 --> 00:07:40,930
Now, once the code in the except clause

150
00:07:40,930 --> 00:07:44,050
is finished executing, the programme will then continue

151
00:07:44,050 --> 00:07:46,070
with the code after the trial,

152
00:07:46,070 --> 00:07:49,040
so it should print, "Programme terminating," in this case.

153
00:07:49,040 --> 00:07:51,570
We'll just do a test of this to run it,

154
00:07:51,570 --> 00:07:53,550
to make sure it does do that,

155
00:07:53,550 --> 00:07:55,110
and you can see that we've got the normal output

156
00:07:55,110 --> 00:07:58,110
we had previously with the value of 900,

157
00:07:58,110 --> 00:08:00,140
and we've also got this extra message

158
00:08:00,140 --> 00:08:02,460
that the programme is terminating.

159
00:08:02,460 --> 00:08:04,470
Let's change this number back to a thousand,

160
00:08:04,470 --> 00:08:08,650
that we now know will actually generate an exception.

161
00:08:08,650 --> 00:08:10,230
If we run that now,

162
00:08:12,890 --> 00:08:15,090
you can see what's happened down here now.

163
00:08:15,090 --> 00:08:17,690
The programme still raises an exception,

164
00:08:17,690 --> 00:08:20,830
but because the code is now inside the try clause,

165
00:08:20,830 --> 00:08:23,150
the programme hasn't crashed this time.

166
00:08:23,150 --> 00:08:26,580
Instead, what's happened is it's executed the code

167
00:08:26,580 --> 00:08:28,920
in the except clause, and we get the message:

168
00:08:28,920 --> 00:08:32,659
"This programme cannot calculate factorials that large."

169
00:08:32,659 --> 00:08:34,280
Execution then continues on,

170
00:08:34,280 --> 00:08:36,530
and we see the programme terminating message,

171
00:08:36,530 --> 00:08:40,230
which we also got when the programme worked successfully.

172
00:08:40,230 --> 00:08:41,730
That really, that's basically all

173
00:08:41,730 --> 00:08:43,650
there is to exception handling.

174
00:08:43,650 --> 00:08:45,370
You wrap your code that's likely

175
00:08:45,370 --> 00:08:48,350
to raise an exception inside try and except.

176
00:08:48,350 --> 00:08:49,810
You then decide what action

177
00:08:49,810 --> 00:08:52,910
to take if an exception is raised.

178
00:08:52,910 --> 00:08:55,620
Now, in this particular case, we just printed a message,

179
00:08:55,620 --> 00:08:58,870
but if you're updating records in a database, for example,

180
00:08:58,870 --> 00:09:00,750
then you could roll back the transaction,

181
00:09:00,750 --> 00:09:04,060
and we're actually going to be doing that soon.

182
00:09:04,060 --> 00:09:07,280
Exception handling's a really very useful feature.

183
00:09:07,280 --> 00:09:09,250
At the very least, you can prevent your code

184
00:09:09,250 --> 00:09:12,720
from crashing when something unexpected happens.

185
00:09:12,720 --> 00:09:15,290
In many situations, you can allow the programme

186
00:09:15,290 --> 00:09:17,780
to recover from whatever caused the error,

187
00:09:17,780 --> 00:09:19,780
and maybe even retry the operation

188
00:09:19,780 --> 00:09:22,430
that failed, if that was appropriate.

189
00:09:22,430 --> 00:09:23,290
Okay, so let's have a look

190
00:09:23,290 --> 00:09:26,500
at that exception clause now in more detail.

191
00:09:26,500 --> 00:09:28,420
Now, in its simplest form,

192
00:09:28,420 --> 00:09:30,590
it can just be the keyword except,

193
00:09:30,590 --> 00:09:32,730
and we'll have a look at that in a minute.

194
00:09:32,730 --> 00:09:35,360
In our programme, we actually specified

195
00:09:35,360 --> 00:09:37,490
which exception we wanted to handle.

196
00:09:37,490 --> 00:09:41,790
A RecursionError, in this case, this is the code on line 11.

197
00:09:41,790 --> 00:09:44,390
We don't expect any other type of exception

198
00:09:44,390 --> 00:09:47,150
to be raised by our factorial function.

199
00:09:47,150 --> 00:09:49,080
It's good practise to be explicit

200
00:09:49,080 --> 00:09:51,730
about which exceptions you're handling,

201
00:09:51,730 --> 00:09:54,850
and you can have several except clauses if you want to.

202
00:09:54,850 --> 00:09:58,540
Let's add a division by zero into our factorial function,

203
00:09:58,540 --> 00:10:01,220
so we can see what happens when we get an exception

204
00:10:01,220 --> 00:10:03,980
that we haven't specified in the except clause.

205
00:10:03,980 --> 00:10:06,910
I'll come down here, and let's just add a line here

206
00:10:06,910 --> 00:10:09,780
that we know is gonna generate an exception.

207
00:10:09,780 --> 00:10:13,260
We'll do a print n divided by zero,

208
00:10:13,260 --> 00:10:14,880
which we know a divided by zero will give us

209
00:10:14,880 --> 00:10:18,880
that exception we saw at the start of the video.

210
00:10:21,060 --> 00:10:24,190
We just run this to see what happens.

211
00:10:24,190 --> 00:10:25,210
You'll notice here that we have got

212
00:10:25,210 --> 00:10:28,040
a ZeroDivisionError: division by zero.

213
00:10:28,040 --> 00:10:30,530
Now, you wouldn't normally do something like I've just done.

214
00:10:30,530 --> 00:10:33,290
I've only added the code on line seven

215
00:10:33,290 --> 00:10:35,060
purely to raise an exception,

216
00:10:35,060 --> 00:10:36,780
so that we can see what happens,

217
00:10:36,780 --> 00:10:38,740
and more on how to handle

218
00:10:38,740 --> 00:10:41,000
more than one exception in our code.

219
00:10:41,000 --> 00:10:44,700
When we run the programme, we got this ZeroDivisionError.

220
00:10:44,700 --> 00:10:47,500
That's because we've only handled RecursionError,

221
00:10:47,500 --> 00:10:50,740
at the moment, and as a result the programme crashes.

222
00:10:50,740 --> 00:10:53,630
When an exception is raised in a try block,

223
00:10:53,630 --> 00:10:55,990
Python checks the except clauses to see

224
00:10:55,990 --> 00:10:59,180
if there's one that handles that particular exception.

225
00:10:59,180 --> 00:11:00,920
Now, in our case, we didn't have one,

226
00:11:00,920 --> 00:11:05,070
so the exception wasn't handled and the programme crashed.

227
00:11:05,070 --> 00:11:06,190
Now, as I mentioned, we can add

228
00:11:06,190 --> 00:11:08,130
more than one except clause though.

229
00:11:08,130 --> 00:11:10,700
Let's go ahead and do that.

230
00:11:10,700 --> 00:11:13,920
Come down here after the output we want executed

231
00:11:13,920 --> 00:11:17,580
in the case of the RecursionError exception.

232
00:11:17,580 --> 00:11:20,580
Here, we'll type except on the next line,

233
00:11:20,580 --> 00:11:24,750
and this time it's going to be ZeroDivisionError, colon,

234
00:11:25,830 --> 00:11:28,180
and we'll just print out some output,

235
00:11:28,180 --> 00:11:32,340
which will be, "What are you doing dividing by zero?"

236
00:11:36,010 --> 00:11:39,510
All right, so now when we run the programme,

237
00:11:40,420 --> 00:11:43,320
this time it doesn't crash, and you can see that we've got,

238
00:11:43,320 --> 00:11:46,830
"What are you doing dividing by zero?" showing as output.

239
00:11:46,830 --> 00:11:49,250
We're now handling the ZeroDivisionError,

240
00:11:49,250 --> 00:11:51,890
as well as the RecursionError.

241
00:11:51,890 --> 00:11:53,510
Now, in this particular case,

242
00:11:53,510 --> 00:11:55,220
assuming that the factorial function

243
00:11:55,220 --> 00:11:57,440
really could raise a ZeroDivisionError,

244
00:11:57,440 --> 00:11:59,870
we've probably taken the right approach.

245
00:11:59,870 --> 00:12:02,270
By using two separate except clauses,

246
00:12:02,270 --> 00:12:04,620
we can display a message that's appropriate

247
00:12:04,620 --> 00:12:08,080
for the specific exception that was raised,

248
00:12:08,080 --> 00:12:10,260
but there is an alternate way of doing this.

249
00:12:10,260 --> 00:12:12,270
We can handle more than one exception

250
00:12:12,270 --> 00:12:15,170
in a single except clause.

251
00:12:15,170 --> 00:12:16,960
We can modify our code here,

252
00:12:16,960 --> 00:12:19,320
and we can actually come along here,

253
00:12:19,320 --> 00:12:22,710
and add parenthesis around our exception.

254
00:12:22,710 --> 00:12:26,420
Left parenthesis, then I'm gonna put a comma,

255
00:12:26,420 --> 00:12:29,890
then ZeroDivisionError, right parenthesis,

256
00:12:29,890 --> 00:12:33,260
and I'm gonna leave the message that currently shows,

257
00:12:33,260 --> 00:12:36,230
and I'm gonna delete the second exception line.

258
00:12:36,230 --> 00:12:38,780
Even though if our ZeroDivisionError occurs,

259
00:12:38,780 --> 00:12:40,660
the output probably isn't going to be appropriate,

260
00:12:40,660 --> 00:12:42,880
because it's talking still about factorials.

261
00:12:42,880 --> 00:12:44,030
It is proof that we can do it.

262
00:12:44,030 --> 00:12:47,610
Let's actually test this out, so we'll run.

263
00:12:48,810 --> 00:12:51,960
We get the message, "The programme calculates,"

264
00:12:51,960 --> 00:12:53,320
and that should be, "This programme

265
00:12:53,320 --> 00:12:56,950
"cannot calculate factorials that large."

266
00:12:56,950 --> 00:12:59,160
Let's just try running it again.

267
00:12:59,160 --> 00:13:00,980
All right, so we currently get that message,

268
00:13:00,980 --> 00:13:03,920
"This programme cannot calculate factorials that large,"

269
00:13:03,920 --> 00:13:07,440
even though, in effect, the ZeroDivisionError

270
00:13:07,440 --> 00:13:11,350
was the error that we caught in this particular occasion.

271
00:13:11,350 --> 00:13:13,330
You can see the exception handler

272
00:13:13,330 --> 00:13:16,130
isn't really appropriate for the exception we got.

273
00:13:16,130 --> 00:13:18,300
Now, even with a small number, we'd see the message,

274
00:13:18,300 --> 00:13:21,660
"This programme cannot calculate factorials that large,"

275
00:13:21,660 --> 00:13:25,550
when really the problem was the division by zero.

276
00:13:25,550 --> 00:13:29,960
It is useful to have one handler for multiple exceptions,

277
00:13:29,960 --> 00:13:32,140
but if you need to do something different

278
00:13:32,140 --> 00:13:35,770
for different exceptions, then use separate except clauses

279
00:13:35,770 --> 00:13:37,530
instead of what I've done here.

280
00:13:37,530 --> 00:13:39,880
Of course, we saw the separate except clauses

281
00:13:39,880 --> 00:13:42,140
a few minutes ago in the video.

282
00:13:42,140 --> 00:13:44,720
All right, so looking at our factorial function,

283
00:13:44,720 --> 00:13:46,890
what else could go wrong with it?

284
00:13:46,890 --> 00:13:48,390
Well, if you've got someone like me

285
00:13:48,390 --> 00:13:51,010
performing division by zero all over the place,

286
00:13:51,010 --> 00:13:53,380
then the answer's pretty much anything,

287
00:13:53,380 --> 00:13:56,500
but with sensible code, one thing that might happen

288
00:13:56,500 --> 00:13:58,250
is that the resulting number

289
00:13:58,250 --> 00:14:01,100
gets too large for Python to handle.

290
00:14:01,100 --> 00:14:03,420
Now, when that happens, that is when a number

291
00:14:03,420 --> 00:14:06,060
is too big to be represented by the computer,

292
00:14:06,060 --> 00:14:08,400
you get something called overflow.

293
00:14:08,400 --> 00:14:11,160
Now, if you're used to languages such as C or Java,

294
00:14:11,160 --> 00:14:12,980
you may have come across this.

295
00:14:12,980 --> 00:14:15,720
In Python, though, it's extremely difficult

296
00:14:15,720 --> 00:14:19,390
to overflow an integer, but there is an exception for it

297
00:14:19,390 --> 00:14:22,780
if we wanna be really sure that our code won't crash.

298
00:14:22,780 --> 00:14:24,630
Let's go back to that list of exceptions

299
00:14:24,630 --> 00:14:27,600
in the browser that we looked at earlier.

300
00:14:27,600 --> 00:14:30,530
We've got this RecursionError that we've looked at,

301
00:14:30,530 --> 00:14:33,050
but there's also this OverflowError.

302
00:14:33,050 --> 00:14:35,960
The OverflowError is raised when the result

303
00:14:35,960 --> 00:14:39,870
of an arithmetic operation is too large to be represented.

304
00:14:39,870 --> 00:14:42,290
As the documentation states there,

305
00:14:42,290 --> 00:14:44,080
this can't occur for integers.

306
00:14:44,080 --> 00:14:46,560
You'd run out of memory first.

307
00:14:46,560 --> 00:14:49,830
This might seem really strange to see for Java programmers,

308
00:14:49,830 --> 00:14:53,140
but Python can handle incredibly large numbers

309
00:14:53,140 --> 00:14:57,200
without having to use special classes to do so.

310
00:14:57,200 --> 00:15:01,860
I'm gonna go back to the code, and let's remove that row,

311
00:15:01,860 --> 00:15:06,310
division by zero line, the one on line seven.

312
00:15:06,310 --> 00:15:08,910
I'm gonna go back and change that factorial to 900,

313
00:15:08,910 --> 00:15:12,420
so that it doesn't, or it's not crashing anymore.

314
00:15:12,420 --> 00:15:15,260
Let's just run this again.

315
00:15:15,260 --> 00:15:16,090
You can see the number

316
00:15:16,090 --> 00:15:19,830
that's outputted there is absolutely huge.

317
00:15:19,830 --> 00:15:21,290
What I'm going to do, because you can't really see it

318
00:15:21,290 --> 00:15:22,810
in the output window too well,

319
00:15:22,810 --> 00:15:26,970
so I'm just gonna load up an editor, a text editor.

320
00:15:28,660 --> 00:15:31,160
I'm gonna paste it into there.

321
00:15:33,130 --> 00:15:34,550
Now, obviously this is quite a huge number.

322
00:15:34,550 --> 00:15:37,750
We can only sort of zoom it up so far.

323
00:15:37,750 --> 00:15:39,550
Now, I want to put this huge number

324
00:15:39,550 --> 00:15:42,160
that Python can do within to context,

325
00:15:42,160 --> 00:15:44,250
and that's why I've pasted it into this editor.

326
00:15:44,250 --> 00:15:45,640
Now, you will struggle a little bit

327
00:15:45,640 --> 00:15:47,430
if you use Notepad on Windows,

328
00:15:47,430 --> 00:15:50,680
because the number's too big to fit on one line in Notepad,

329
00:15:50,680 --> 00:15:51,900
but you'll still see the effect

330
00:15:51,900 --> 00:15:54,140
if you're doing this on your computer.

331
00:15:54,140 --> 00:15:57,720
On the line below, I'm going to paste in another number.

332
00:15:57,720 --> 00:16:01,480
This is the number of atoms in the known universe.

333
00:16:01,480 --> 00:16:04,310
The upper bound for the number of atoms in the universe

334
00:16:04,310 --> 00:16:09,140
is estimated to be four times to the power of 82.

335
00:16:09,140 --> 00:16:11,140
I'll paste that in here.

336
00:16:12,940 --> 00:16:15,100
We'll just look at the results there.

337
00:16:15,100 --> 00:16:19,200
Python's calculated a result significantly larger than that.

338
00:16:19,200 --> 00:16:21,440
If I just scroll over, look how far

339
00:16:21,440 --> 00:16:23,640
I can actually scroll this number over,

340
00:16:23,640 --> 00:16:26,140
the number is absolutely huge.

341
00:16:27,830 --> 00:16:30,230
Absolutely huge number.

342
00:16:30,230 --> 00:16:33,090
The point here is that there's really no point checking

343
00:16:33,090 --> 00:16:35,660
for an overflow operation in our code.

344
00:16:35,660 --> 00:16:37,960
It's really just not going to happen,

345
00:16:37,960 --> 00:16:41,630
but if it were possible, then that would be a good case

346
00:16:41,630 --> 00:16:44,140
for using the same exception handler.

347
00:16:44,140 --> 00:16:46,330
If overflow was possible, it would be caused

348
00:16:46,330 --> 00:16:48,800
by too large a number, which is the same thing

349
00:16:48,800 --> 00:16:51,550
that results in our RecursionError.

350
00:16:51,550 --> 00:16:53,790
In other words, coming back to the code,

351
00:16:53,790 --> 00:16:55,620
we might end up doing something like

352
00:16:55,620 --> 00:16:58,500
putting an OverflowError in there,

353
00:16:58,500 --> 00:17:01,400
and combining those exceptions.

354
00:17:01,400 --> 00:17:03,440
In other words, here it would make sense

355
00:17:03,440 --> 00:17:06,760
to use the same handler for both exceptions.

356
00:17:06,760 --> 00:17:09,300
This also emphasises that is really is worth reading

357
00:17:09,300 --> 00:17:11,660
the documentation for the exceptions

358
00:17:11,660 --> 00:17:13,510
that you plan to handle.

359
00:17:13,510 --> 00:17:14,920
Now, if we really were concerned

360
00:17:14,920 --> 00:17:16,530
about the result getting too big

361
00:17:16,530 --> 00:17:18,970
before a RecursionError was raised,

362
00:17:18,970 --> 00:17:21,089
we might be better off handling MemoryError,

363
00:17:21,089 --> 00:17:23,740
as the documentation suggested on the other page,

364
00:17:23,740 --> 00:17:25,800
rather than the OverflowError.

365
00:17:25,800 --> 00:17:27,910
All right, that's the basics of exception handling,

366
00:17:27,910 --> 00:17:30,660
and there isn't really much more to it than that.

367
00:17:30,660 --> 00:17:33,550
There's some fine details that we should know about

368
00:17:33,550 --> 00:17:34,720
to give us a bit more control

369
00:17:34,720 --> 00:17:37,600
in how we actually handle exceptions,

370
00:17:37,600 --> 00:17:39,720
and we'll be looking at those next,

371
00:17:39,720 --> 00:17:41,610
but before all that in the next video,

372
00:17:41,610 --> 00:17:43,320
let's start off with a challenge.

373
00:17:43,320 --> 00:17:45,360
I'll see you in the next video.

