WEBVTT 1 00:00:02.355 --> 00:00:04.539 In this video, we're going to take a break 2 00:00:04.539 --> 00:00:07.409 from databases, and we're gonna look at exceptions 3 00:00:07.409 --> 00:00:10.325 and exception handling in Python. 4 00:00:10.325 --> 00:00:13.600 Let's start by creating a new project. 5 00:00:13.600 --> 00:00:15.976 You should always select Python, as always. 6 00:00:15.976 --> 00:00:20.143 Next, and we're gonna call this project ExceptionHandling. 7 00:00:27.683 --> 00:00:30.433 Okay, and let's create a new file 8 00:00:31.409 --> 00:00:33.907 in the project, and we'll call that Examples. 9 00:00:33.907 --> 00:00:36.074 New Python file, Examples. 10 00:00:38.867 --> 00:00:41.015 Okay, let's go to full screen. 11 00:00:41.015 --> 00:00:43.525 All right, so let's experiment with some code. 12 00:00:43.525 --> 00:00:46.130 Now, there's two types of errors we can get. 13 00:00:46.130 --> 00:00:49.680 There's syntax errors and exceptions. 14 00:00:49.680 --> 00:00:51.705 Now, syntax errors, I'm sure you've seen before, 15 00:00:51.705 --> 00:00:54.316 are where we make a mistake in the code. 16 00:00:54.316 --> 00:00:55.757 As an example, if I type something like 17 00:00:55.757 --> 00:00:57.424 x equals 8 equals 5, 18 00:00:59.570 --> 00:01:02.078 instead of x equals 8 minus 5, 19 00:01:02.078 --> 00:01:03.650 we actually get a syntax error. 20 00:01:03.650 --> 00:01:06.233 If I actually try and run this, 21 00:01:07.211 --> 00:01:08.194 we get this error over here, 22 00:01:08.194 --> 00:01:11.277 which I'll just change to the bottom. 23 00:01:12.752 --> 00:01:16.180 We can see we got the error: can't assign to literal. 24 00:01:16.180 --> 00:01:18.671 Now, we can fix these types of errors, obviously, 25 00:01:18.671 --> 00:01:22.285 by fixing our code so that it's valid part in code, 26 00:01:22.285 --> 00:01:26.035 and then of course, the programme is gonna run. 27 00:01:28.285 --> 00:01:30.233 Okay, no surprises there, 28 00:01:30.233 --> 00:01:32.356 but when our programmes are running, though, 29 00:01:32.356 --> 00:01:34.817 we may actually get other errors as a result 30 00:01:34.817 --> 00:01:36.994 of flaws in the code's logic, 31 00:01:36.994 --> 00:01:39.609 or conditions that we couldn't predict. 32 00:01:39.609 --> 00:01:42.811 For example, we might attempt to create a new database, 33 00:01:42.811 --> 00:01:46.838 but there isn't enough space on the drive that we specify. 34 00:01:46.838 --> 00:01:49.451 These types of errors are exceptions. 35 00:01:49.451 --> 00:01:50.599 In the next few videos, we're going 36 00:01:50.599 --> 00:01:53.562 to look at dealing with them when they happen. 37 00:01:53.562 --> 00:01:55.550 Now, the thing to remember is if you don't handle 38 00:01:55.550 --> 00:01:58.444 an exception in your code when it occurs, 39 00:01:58.444 --> 00:02:00.161 then the programme actually crashes, 40 00:02:00.161 --> 00:02:02.163 and that's almost always not a good thing 41 00:02:02.163 --> 00:02:03.984 from a user's perspective. 42 00:02:03.984 --> 00:02:05.663 Now, it turns out that it is very easy 43 00:02:05.663 --> 00:02:08.229 to generate an exception. 44 00:02:08.229 --> 00:02:10.095 We can come up here, and on the second line, 45 00:02:10.095 --> 00:02:14.758 I can put something like y equals x divided by 0, 46 00:02:14.758 --> 00:02:17.005 and if I run that, we should see an error, 47 00:02:17.005 --> 00:02:19.750 an exception, rather, a ZeroDivisionError. 48 00:02:19.750 --> 00:02:21.562 You can see we've got just that on line two, 49 00:02:21.562 --> 00:02:24.531 ZeroDivisionError: division by zero. 50 00:02:24.531 --> 00:02:26.917 If we don't handle an exception, 51 00:02:26.917 --> 00:02:29.213 it is called an unhandled exception, 52 00:02:29.213 --> 00:02:31.728 and execution of the programme stops, 53 00:02:31.728 --> 00:02:34.021 as you can see has happened in this case. 54 00:02:34.021 --> 00:02:36.914 Python then prints out the details of the exception 55 00:02:36.914 --> 00:02:40.158 and a stack trace showing where the exception occurred. 56 00:02:40.158 --> 00:02:42.852 In our case, as you can see, it was on line two, 57 00:02:42.852 --> 00:02:45.239 and the exception details are, again, 58 00:02:45.239 --> 00:02:48.522 ZeroDivisionError: division by zero. 59 00:02:48.522 --> 00:02:51.330 This first part over here before the colon 60 00:02:51.330 --> 00:02:55.109 is the type of the exception, its name, if you like, 61 00:02:55.109 --> 00:02:59.290 but the details after the colon are the extra information 62 00:02:59.290 --> 00:03:02.430 added to the exception when it occurs. 63 00:03:02.430 --> 00:03:05.394 In this particular case, it's quite a simple description, 64 00:03:05.394 --> 00:03:07.326 but you can add the values of variables 65 00:03:07.326 --> 00:03:09.003 to the exception, if you want. 66 00:03:09.003 --> 00:03:10.119 We'll be seeing how to do that 67 00:03:10.119 --> 00:03:14.043 when we raise our own exceptions a little bit later. 68 00:03:14.043 --> 00:03:16.012 You can get a list of all the built-in exceptions 69 00:03:16.012 --> 00:03:17.845 by going to this link. 70 00:03:23.454 --> 00:03:25.563 There's quite a few exceptions as you can see here, 71 00:03:25.563 --> 00:03:26.920 so I'm scrolling down. 72 00:03:26.920 --> 00:03:27.842 I'm certainly not going to attempt 73 00:03:27.842 --> 00:03:31.533 to go through them all now, but this page is useful 74 00:03:31.533 --> 00:03:32.930 because it goes into the mechanics 75 00:03:32.930 --> 00:03:35.325 of exception handling in great detail, 76 00:03:35.325 --> 00:03:38.014 but I recommend you don't read through it just yet, 77 00:03:38.014 --> 00:03:41.898 because much of it will be quite confusing at first. 78 00:03:41.898 --> 00:03:43.937 It is interesting to skip through or skim through 79 00:03:43.937 --> 00:03:47.104 the list of exceptions in section 5.2. 80 00:03:48.179 --> 00:03:49.429 Down here. 81 00:03:49.429 --> 00:03:50.892 Really just to, more or less, get a feel 82 00:03:50.892 --> 00:03:53.601 for the sorts of exceptions that are available 83 00:03:53.601 --> 00:03:56.017 for you to check in your code. 84 00:03:56.017 --> 00:04:00.103 Now, as I scroll through, one interesting one, 85 00:04:00.103 --> 00:04:04.594 as we scroll through here, is this RecursionError. 86 00:04:04.594 --> 00:04:08.521 Now, back in section 11, we looked at recursive functions, 87 00:04:08.521 --> 00:04:12.003 and wrote a recursive function to generate factorials. 88 00:04:12.003 --> 00:04:14.345 Now, if you tried to run that with large numbers, 89 00:04:14.345 --> 00:04:17.823 above 1,000 would've done it, then the stack overflows, 90 00:04:17.823 --> 00:04:20.208 and you end up with a RecursionError. 91 00:04:20.208 --> 00:04:22.541 Let's try and do that again. 92 00:04:25.322 --> 00:04:26.569 Now, it's only a few lines of code, 93 00:04:26.569 --> 00:04:28.124 so I'm just going to type it in again, 94 00:04:28.124 --> 00:04:30.368 but if you've got the code from section 11 95 00:04:30.368 --> 00:04:33.668 in the video Name Spaces: More On Scope and Recursion, 96 00:04:33.668 --> 00:04:36.567 you can grab it from there if you prefer not to type it in. 97 00:04:36.567 --> 00:04:40.734 I'm gonna type it in, def factorial(n):, 98 00:04:42.629 --> 00:04:44.650 and then we wanna do just a reminder 99 00:04:44.650 --> 00:04:47.983 that the factorial n can also be defined 100 00:04:50.048 --> 00:04:51.965 as n times n, take one, 101 00:04:58.472 --> 00:05:00.889 and calculates n recursively. 102 00:05:03.716 --> 00:05:04.989 This is essentially what we're doing here. 103 00:05:04.989 --> 00:05:06.841 All right, so in terms of the code, 104 00:05:06.841 --> 00:05:11.008 it's if n is less than or equal to one, return one, 105 00:05:12.326 --> 00:05:14.826 else return n times factorial, 106 00:05:19.855 --> 00:05:20.772 n take one. 107 00:05:22.121 --> 00:05:22.978 Now, we can actually try this 108 00:05:22.978 --> 00:05:27.145 by doing a print factorial, and let's start with 50. 109 00:05:31.530 --> 00:05:33.349 That actually runs without any error, 110 00:05:33.349 --> 00:05:37.432 so let's change that to a larger number, say 900. 111 00:05:40.455 --> 00:05:41.983 We can see we've now got a huge number here, 112 00:05:41.983 --> 00:05:43.556 but it has still worked. 113 00:05:43.556 --> 00:05:46.044 Now, this may or may not work on your system. 114 00:05:46.044 --> 00:05:47.944 It really does depend on how much memory 115 00:05:47.944 --> 00:05:49.896 you've allocated for IntelliJ. 116 00:05:49.896 --> 00:05:53.005 If you get a RecursionError already, that's fine, 117 00:05:53.005 --> 00:05:56.072 but on my system, obviously, it's working with 900, 118 00:05:56.072 --> 00:05:57.966 and we obviously have this huge number printed. 119 00:05:57.966 --> 00:05:59.787 I'll come back to that in a moment. 120 00:05:59.787 --> 00:06:03.382 All right, so let's actually try a thousand now. 121 00:06:03.382 --> 00:06:05.522 Gonna run that again. 122 00:06:05.522 --> 00:06:06.905 We actually get this error now, 123 00:06:06.905 --> 00:06:10.205 RecursionError: maximum recursion depth 124 00:06:10.205 --> 00:06:12.746 exceeded in comparison. 125 00:06:12.746 --> 00:06:16.104 Now, in this case, there's not really a lot we can do 126 00:06:16.104 --> 00:06:18.381 to fix this problem, unless we rewrite 127 00:06:18.381 --> 00:06:20.189 our factorial function, of course, 128 00:06:20.189 --> 00:06:23.673 but what we can do is prevent the programme from crashing. 129 00:06:23.673 --> 00:06:26.189 The way we wanna do that is come down here, 130 00:06:26.189 --> 00:06:29.606 and on line nine, you type in try, colon, 131 00:06:30.527 --> 00:06:32.720 then we add our print on that line. 132 00:06:32.720 --> 00:06:37.061 I'm going to initially change that back to 900. 133 00:06:37.061 --> 00:06:40.784 Then I'll come down here and type except, 134 00:06:40.784 --> 00:06:42.451 then RecursionError. 135 00:06:44.337 --> 00:06:47.420 Print, "This programme cannot calculate 136 00:06:48.491 --> 00:06:50.491 "factorials that large." 137 00:06:54.872 --> 00:06:58.955 Then here I'll do a print, "Programme terminating." 138 00:07:00.917 --> 00:07:03.694 All right, so what I've done there is put the code 139 00:07:03.694 --> 00:07:07.680 that's likely to raise an exception into a try block. 140 00:07:07.680 --> 00:07:10.868 We did that by starting this new block with the try keyword. 141 00:07:10.868 --> 00:07:14.795 Now, the code that's in between the try and the except 142 00:07:14.795 --> 00:07:17.364 is executed, and runs as per normal. 143 00:07:17.364 --> 00:07:20.700 If everything works fine, then the code that appears 144 00:07:20.700 --> 00:07:24.364 after this except line is skipped, 145 00:07:24.364 --> 00:07:26.631 and the programme continues to run. 146 00:07:26.631 --> 00:07:29.939 However, if an exception is raised inside the try clause, 147 00:07:29.939 --> 00:07:33.355 execution will jump straight to this code that's immediately 148 00:07:33.355 --> 00:07:36.351 after the except line, or the except clause. 149 00:07:36.351 --> 00:07:37.881 Now, once the code in the except clause 150 00:07:37.881 --> 00:07:41.006 is finished executing, the programme will then continue 151 00:07:41.006 --> 00:07:43.026 with the code after the trial, 152 00:07:43.026 --> 00:07:45.995 so it should print, "Programme terminating," in this case. 153 00:07:45.995 --> 00:07:48.521 We'll just do a test of this to run it, 154 00:07:48.521 --> 00:07:50.505 to make sure it does do that, 155 00:07:50.505 --> 00:07:52.066 and you can see that we've got the normal output 156 00:07:52.066 --> 00:07:55.064 we had previously with the value of 900, 157 00:07:55.064 --> 00:07:57.099 and we've also got this extra message 158 00:07:57.099 --> 00:07:59.412 that the programme is terminating. 159 00:07:59.412 --> 00:08:01.424 Let's change this number back to a thousand, 160 00:08:01.424 --> 00:08:05.600 that we now know will actually generate an exception. 161 00:08:05.600 --> 00:08:07.183 If we run that now, 162 00:08:09.847 --> 00:08:12.041 you can see what's happened down here now. 163 00:08:12.041 --> 00:08:14.649 The programme still raises an exception, 164 00:08:14.649 --> 00:08:17.784 but because the code is now inside the try clause, 165 00:08:17.784 --> 00:08:20.102 the programme hasn't crashed this time. 166 00:08:20.102 --> 00:08:23.533 Instead, what's happened is it's executed the code 167 00:08:23.533 --> 00:08:25.875 in the except clause, and we get the message: 168 00:08:25.875 --> 00:08:29.616 "This programme cannot calculate factorials that large." 169 00:08:29.616 --> 00:08:31.236 Execution then continues on, 170 00:08:31.236 --> 00:08:33.488 and we see the programme terminating message, 171 00:08:33.488 --> 00:08:37.181 which we also got when the programme worked successfully. 172 00:08:37.181 --> 00:08:38.682 That really, that's basically all 173 00:08:38.682 --> 00:08:40.606 there is to exception handling. 174 00:08:40.606 --> 00:08:42.323 You wrap your code that's likely 175 00:08:42.323 --> 00:08:45.303 to raise an exception inside try and except. 176 00:08:45.303 --> 00:08:46.768 You then decide what action 177 00:08:46.768 --> 00:08:49.866 to take if an exception is raised. 178 00:08:49.866 --> 00:08:52.577 Now, in this particular case, we just printed a message, 179 00:08:52.577 --> 00:08:55.824 but if you're updating records in a database, for example, 180 00:08:55.824 --> 00:08:57.700 then you could roll back the transaction, 181 00:08:57.700 --> 00:09:01.018 and we're actually going to be doing that soon. 182 00:09:01.018 --> 00:09:04.232 Exception handling's a really very useful feature. 183 00:09:04.232 --> 00:09:06.202 At the very least, you can prevent your code 184 00:09:06.202 --> 00:09:09.675 from crashing when something unexpected happens. 185 00:09:09.675 --> 00:09:12.241 In many situations, you can allow the programme 186 00:09:12.241 --> 00:09:14.732 to recover from whatever caused the error, 187 00:09:14.732 --> 00:09:16.734 and maybe even retry the operation 188 00:09:16.734 --> 00:09:19.383 that failed, if that was appropriate. 189 00:09:19.383 --> 00:09:20.243 Okay, so let's have a look 190 00:09:20.243 --> 00:09:23.459 at that exception clause now in more detail. 191 00:09:23.459 --> 00:09:25.376 Now, in its simplest form, 192 00:09:25.376 --> 00:09:27.543 it can just be the keyword except, 193 00:09:27.543 --> 00:09:29.681 and we'll have a look at that in a minute. 194 00:09:29.681 --> 00:09:32.313 In our programme, we actually specified 195 00:09:32.313 --> 00:09:34.443 which exception we wanted to handle. 196 00:09:34.443 --> 00:09:38.740 A RecursionError, in this case, this is the code on line 11. 197 00:09:38.740 --> 00:09:41.347 We don't expect any other type of exception 198 00:09:41.347 --> 00:09:44.102 to be raised by our factorial function. 199 00:09:44.102 --> 00:09:46.039 It's good practise to be explicit 200 00:09:46.039 --> 00:09:48.682 about which exceptions you're handling, 201 00:09:48.682 --> 00:09:51.801 and you can have several except clauses if you want to. 202 00:09:51.801 --> 00:09:55.490 Let's add a division by zero into our factorial function, 203 00:09:55.490 --> 00:09:58.173 so we can see what happens when we get an exception 204 00:09:58.173 --> 00:10:00.932 that we haven't specified in the except clause. 205 00:10:00.932 --> 00:10:03.868 I'll come down here, and let's just add a line here 206 00:10:03.868 --> 00:10:06.731 that we know is gonna generate an exception. 207 00:10:06.731 --> 00:10:10.217 We'll do a print n divided by zero, 208 00:10:10.217 --> 00:10:11.838 which we know a divided by zero will give us 209 00:10:11.838 --> 00:10:15.838 that exception we saw at the start of the video. 210 00:10:18.016 --> 00:10:21.143 We just run this to see what happens. 211 00:10:21.143 --> 00:10:22.162 You'll notice here that we have got 212 00:10:22.162 --> 00:10:24.999 a ZeroDivisionError: division by zero. 213 00:10:24.999 --> 00:10:27.481 Now, you wouldn't normally do something like I've just done. 214 00:10:27.481 --> 00:10:30.247 I've only added the code on line seven 215 00:10:30.247 --> 00:10:32.018 purely to raise an exception, 216 00:10:32.018 --> 00:10:33.738 so that we can see what happens, 217 00:10:33.738 --> 00:10:35.694 and more on how to handle 218 00:10:35.694 --> 00:10:37.951 more than one exception in our code. 219 00:10:37.951 --> 00:10:41.651 When we run the programme, we got this ZeroDivisionError. 220 00:10:41.651 --> 00:10:44.451 That's because we've only handled RecursionError, 221 00:10:44.451 --> 00:10:47.694 at the moment, and as a result the programme crashes. 222 00:10:47.694 --> 00:10:50.586 When an exception is raised in a try block, 223 00:10:50.586 --> 00:10:52.944 Python checks the except clauses to see 224 00:10:52.944 --> 00:10:56.134 if there's one that handles that particular exception. 225 00:10:56.134 --> 00:10:57.871 Now, in our case, we didn't have one, 226 00:10:57.871 --> 00:11:02.025 so the exception wasn't handled and the programme crashed. 227 00:11:02.025 --> 00:11:03.146 Now, as I mentioned, we can add 228 00:11:03.146 --> 00:11:05.088 more than one except clause though. 229 00:11:05.088 --> 00:11:07.659 Let's go ahead and do that. 230 00:11:07.659 --> 00:11:10.875 Come down here after the output we want executed 231 00:11:10.875 --> 00:11:14.530 in the case of the RecursionError exception. 232 00:11:14.530 --> 00:11:17.537 Here, we'll type except on the next line, 233 00:11:17.537 --> 00:11:21.704 and this time it's going to be ZeroDivisionError, colon, 234 00:11:22.780 --> 00:11:25.130 and we'll just print out some output, 235 00:11:25.130 --> 00:11:29.297 which will be, "What are you doing dividing by zero?" 236 00:11:32.967 --> 00:11:36.467 All right, so now when we run the programme, 237 00:11:37.374 --> 00:11:40.272 this time it doesn't crash, and you can see that we've got, 238 00:11:40.272 --> 00:11:43.784 "What are you doing dividing by zero?" showing as output. 239 00:11:43.784 --> 00:11:46.209 We're now handling the ZeroDivisionError, 240 00:11:46.209 --> 00:11:48.845 as well as the RecursionError. 241 00:11:48.845 --> 00:11:50.461 Now, in this particular case, 242 00:11:50.461 --> 00:11:52.178 assuming that the factorial function 243 00:11:52.178 --> 00:11:54.396 really could raise a ZeroDivisionError, 244 00:11:54.396 --> 00:11:56.828 we've probably taken the right approach. 245 00:11:56.828 --> 00:11:59.220 By using two separate except clauses, 246 00:11:59.220 --> 00:12:01.573 we can display a message that's appropriate 247 00:12:01.573 --> 00:12:05.033 for the specific exception that was raised, 248 00:12:05.033 --> 00:12:07.213 but there is an alternate way of doing this. 249 00:12:07.213 --> 00:12:09.228 We can handle more than one exception 250 00:12:09.228 --> 00:12:12.126 in a single except clause. 251 00:12:12.126 --> 00:12:13.917 We can modify our code here, 252 00:12:13.917 --> 00:12:16.279 and we can actually come along here, 253 00:12:16.279 --> 00:12:19.663 and add parenthesis around our exception. 254 00:12:19.663 --> 00:12:23.375 Left parenthesis, then I'm gonna put a comma, 255 00:12:23.375 --> 00:12:26.847 then ZeroDivisionError, right parenthesis, 256 00:12:26.847 --> 00:12:30.217 and I'm gonna leave the message that currently shows, 257 00:12:30.217 --> 00:12:33.188 and I'm gonna delete the second exception line. 258 00:12:33.188 --> 00:12:35.739 Even though if our ZeroDivisionError occurs, 259 00:12:35.739 --> 00:12:37.612 the output probably isn't going to be appropriate, 260 00:12:37.612 --> 00:12:39.839 because it's talking still about factorials. 261 00:12:39.839 --> 00:12:40.986 It is proof that we can do it. 262 00:12:40.986 --> 00:12:44.569 Let's actually test this out, so we'll run. 263 00:12:45.769 --> 00:12:48.911 We get the message, "The programme calculates," 264 00:12:48.911 --> 00:12:50.277 and that should be, "This programme 265 00:12:50.277 --> 00:12:53.901 "cannot calculate factorials that large." 266 00:12:53.901 --> 00:12:56.110 Let's just try running it again. 267 00:12:56.110 --> 00:12:57.935 All right, so we currently get that message, 268 00:12:57.935 --> 00:13:00.875 "This programme cannot calculate factorials that large," 269 00:13:00.875 --> 00:13:04.392 even though, in effect, the ZeroDivisionError 270 00:13:04.392 --> 00:13:08.303 was the error that we caught in this particular occasion. 271 00:13:08.303 --> 00:13:10.285 You can see the exception handler 272 00:13:10.285 --> 00:13:13.084 isn't really appropriate for the exception we got. 273 00:13:13.084 --> 00:13:15.254 Now, even with a small number, we'd see the message, 274 00:13:15.254 --> 00:13:18.617 "This programme cannot calculate factorials that large," 275 00:13:18.617 --> 00:13:22.503 when really the problem was the division by zero. 276 00:13:22.503 --> 00:13:26.910 It is useful to have one handler for multiple exceptions, 277 00:13:26.910 --> 00:13:29.099 but if you need to do something different 278 00:13:29.099 --> 00:13:32.727 for different exceptions, then use separate except clauses 279 00:13:32.727 --> 00:13:34.489 instead of what I've done here. 280 00:13:34.489 --> 00:13:36.833 Of course, we saw the separate except clauses 281 00:13:36.833 --> 00:13:39.099 a few minutes ago in the video. 282 00:13:39.099 --> 00:13:41.673 All right, so looking at our factorial function, 283 00:13:41.673 --> 00:13:43.842 what else could go wrong with it? 284 00:13:43.842 --> 00:13:45.347 Well, if you've got someone like me 285 00:13:45.347 --> 00:13:47.965 performing division by zero all over the place, 286 00:13:47.965 --> 00:13:50.339 then the answer's pretty much anything, 287 00:13:50.339 --> 00:13:53.450 but with sensible code, one thing that might happen 288 00:13:53.450 --> 00:13:55.207 is that the resulting number 289 00:13:55.207 --> 00:13:58.059 gets too large for Python to handle. 290 00:13:58.059 --> 00:14:00.374 Now, when that happens, that is when a number 291 00:14:00.374 --> 00:14:03.017 is too big to be represented by the computer, 292 00:14:03.017 --> 00:14:05.357 you get something called overflow. 293 00:14:05.357 --> 00:14:08.115 Now, if you're used to languages such as C or Java, 294 00:14:08.115 --> 00:14:09.930 you may have come across this. 295 00:14:09.930 --> 00:14:12.676 In Python, though, it's extremely difficult 296 00:14:12.676 --> 00:14:16.348 to overflow an integer, but there is an exception for it 297 00:14:16.348 --> 00:14:19.733 if we wanna be really sure that our code won't crash. 298 00:14:19.733 --> 00:14:21.587 Let's go back to that list of exceptions 299 00:14:21.587 --> 00:14:24.552 in the browser that we looked at earlier. 300 00:14:24.552 --> 00:14:27.484 We've got this RecursionError that we've looked at, 301 00:14:27.484 --> 00:14:30.005 but there's also this OverflowError. 302 00:14:30.005 --> 00:14:32.919 The OverflowError is raised when the result 303 00:14:32.919 --> 00:14:36.820 of an arithmetic operation is too large to be represented. 304 00:14:36.820 --> 00:14:39.249 As the documentation states there, 305 00:14:39.249 --> 00:14:41.037 this can't occur for integers. 306 00:14:41.037 --> 00:14:43.519 You'd run out of memory first. 307 00:14:43.519 --> 00:14:46.786 This might seem really strange to see for Java programmers, 308 00:14:46.786 --> 00:14:50.093 but Python can handle incredibly large numbers 309 00:14:50.093 --> 00:14:54.152 without having to use special classes to do so. 310 00:14:54.152 --> 00:14:58.811 I'm gonna go back to the code, and let's remove that row, 311 00:14:58.811 --> 00:15:03.265 division by zero line, the one on line seven. 312 00:15:03.265 --> 00:15:05.869 I'm gonna go back and change that factorial to 900, 313 00:15:05.869 --> 00:15:09.378 so that it doesn't, or it's not crashing anymore. 314 00:15:09.378 --> 00:15:12.211 Let's just run this again. 315 00:15:12.211 --> 00:15:13.044 You can see the number 316 00:15:13.044 --> 00:15:16.780 that's outputted there is absolutely huge. 317 00:15:16.780 --> 00:15:18.243 What I'm going to do, because you can't really see it 318 00:15:18.243 --> 00:15:19.762 in the output window too well, 319 00:15:19.762 --> 00:15:23.929 so I'm just gonna load up an editor, a text editor. 320 00:15:25.611 --> 00:15:28.111 I'm gonna paste it into there. 321 00:15:30.080 --> 00:15:31.503 Now, obviously this is quite a huge number. 322 00:15:31.503 --> 00:15:34.707 We can only sort of zoom it up so far. 323 00:15:34.707 --> 00:15:36.507 Now, I want to put this huge number 324 00:15:36.507 --> 00:15:39.115 that Python can do within to context, 325 00:15:39.115 --> 00:15:41.205 and that's why I've pasted it into this editor. 326 00:15:41.205 --> 00:15:42.595 Now, you will struggle a little bit 327 00:15:42.595 --> 00:15:44.385 if you use Notepad on Windows, 328 00:15:44.385 --> 00:15:47.636 because the number's too big to fit on one line in Notepad, 329 00:15:47.636 --> 00:15:48.851 but you'll still see the effect 330 00:15:48.851 --> 00:15:51.091 if you're doing this on your computer. 331 00:15:51.091 --> 00:15:54.673 On the line below, I'm going to paste in another number. 332 00:15:54.673 --> 00:15:58.434 This is the number of atoms in the known universe. 333 00:15:58.434 --> 00:16:01.263 The upper bound for the number of atoms in the universe 334 00:16:01.263 --> 00:16:06.091 is estimated to be four times to the power of 82. 335 00:16:06.091 --> 00:16:08.091 I'll paste that in here. 336 00:16:09.899 --> 00:16:12.058 We'll just look at the results there. 337 00:16:12.058 --> 00:16:16.154 Python's calculated a result significantly larger than that. 338 00:16:16.154 --> 00:16:18.399 If I just scroll over, look how far 339 00:16:18.399 --> 00:16:20.591 I can actually scroll this number over, 340 00:16:20.591 --> 00:16:23.091 the number is absolutely huge. 341 00:16:24.782 --> 00:16:27.187 Absolutely huge number. 342 00:16:27.187 --> 00:16:30.047 The point here is that there's really no point checking 343 00:16:30.047 --> 00:16:32.610 for an overflow operation in our code. 344 00:16:32.610 --> 00:16:34.914 It's really just not going to happen, 345 00:16:34.914 --> 00:16:38.581 but if it were possible, then that would be a good case 346 00:16:38.581 --> 00:16:41.098 for using the same exception handler. 347 00:16:41.098 --> 00:16:43.288 If overflow was possible, it would be caused 348 00:16:43.288 --> 00:16:45.755 by too large a number, which is the same thing 349 00:16:45.755 --> 00:16:48.504 that results in our RecursionError. 350 00:16:48.504 --> 00:16:50.746 In other words, coming back to the code, 351 00:16:50.746 --> 00:16:52.570 we might end up doing something like 352 00:16:52.570 --> 00:16:55.452 putting an OverflowError in there, 353 00:16:55.452 --> 00:16:58.352 and combining those exceptions. 354 00:16:58.352 --> 00:17:00.397 In other words, here it would make sense 355 00:17:00.397 --> 00:17:03.712 to use the same handler for both exceptions. 356 00:17:03.712 --> 00:17:06.251 This also emphasises that is really is worth reading 357 00:17:06.251 --> 00:17:08.619 the documentation for the exceptions 358 00:17:08.619 --> 00:17:10.467 that you plan to handle. 359 00:17:10.467 --> 00:17:11.878 Now, if we really were concerned 360 00:17:11.878 --> 00:17:13.488 about the result getting too big 361 00:17:13.488 --> 00:17:15.920 before a RecursionError was raised, 362 00:17:15.920 --> 00:17:18.044 we might be better off handling MemoryError, 363 00:17:18.044 --> 00:17:20.691 as the documentation suggested on the other page, 364 00:17:20.691 --> 00:17:22.750 rather than the OverflowError. 365 00:17:22.750 --> 00:17:24.868 All right, that's the basics of exception handling, 366 00:17:24.868 --> 00:17:27.618 and there isn't really much more to it than that. 367 00:17:27.618 --> 00:17:30.502 There's some fine details that we should know about 368 00:17:30.502 --> 00:17:31.674 to give us a bit more control 369 00:17:31.674 --> 00:17:34.557 in how we actually handle exceptions, 370 00:17:34.557 --> 00:17:36.675 and we'll be looking at those next, 371 00:17:36.675 --> 00:17:38.561 but before all that in the next video, 372 00:17:38.561 --> 00:17:40.274 let's start off with a challenge. 373 00:17:40.274 --> 00:17:42.318 I'll see you in the next video.