1 00:00:01,040 --> 00:00:02,210 - [Instructor] Now let's take a look 2 00:00:02,210 --> 00:00:07,210 at how to handle actual exceptions as they occur at runtime, 3 00:00:07,800 --> 00:00:08,780 so for this purpose, 4 00:00:08,780 --> 00:00:10,320 we're going to be looking at a script 5 00:00:10,320 --> 00:00:13,520 called dividebyzero.py, 6 00:00:13,520 --> 00:00:15,100 let me go ahead and execute that 7 00:00:15,100 --> 00:00:16,900 so you can see it in action. 8 00:00:16,900 --> 00:00:18,610 This script is going to prompt the user 9 00:00:18,610 --> 00:00:20,830 to enter two numbers, 10 00:00:20,830 --> 00:00:24,580 a numerator and a denominator specifically for this script, 11 00:00:24,580 --> 00:00:26,510 they must be integers, 12 00:00:26,510 --> 00:00:29,200 so let's say I go ahead and enter 100, 13 00:00:29,200 --> 00:00:32,120 now for the numerator, now for the denominator, 14 00:00:32,120 --> 00:00:33,270 in the preceeding video, 15 00:00:33,270 --> 00:00:35,410 we saw that if we divide by zero, 16 00:00:35,410 --> 00:00:37,730 a zero division error occurs. 17 00:00:37,730 --> 00:00:40,410 So, let's see what happens if we try to divide by zero 18 00:00:40,410 --> 00:00:41,590 in this script. 19 00:00:41,590 --> 00:00:42,930 We get an error message, 20 00:00:42,930 --> 00:00:44,800 attempted to divide by zero 21 00:00:44,800 --> 00:00:46,520 but the script doesn't terminate, 22 00:00:46,520 --> 00:00:48,050 it simply prompts the user 23 00:00:48,050 --> 00:00:50,750 to enter the numerator once again. 24 00:00:50,750 --> 00:00:52,240 Now in the preceding video, 25 00:00:52,240 --> 00:00:54,200 we also demonstrated what happened 26 00:00:54,200 --> 00:00:56,270 if an integer was expected 27 00:00:56,270 --> 00:00:59,100 and the user typed a non-integer value. 28 00:00:59,100 --> 00:01:01,090 In that case, we got a valuer 29 00:01:01,090 --> 00:01:03,840 but in this script, we simply get a message 30 00:01:03,840 --> 00:01:05,380 you must enter two integers 31 00:01:05,380 --> 00:01:09,430 and the prompt to enter the numerator appears once again. 32 00:01:09,430 --> 00:01:12,440 So, finally if I do go and enter two integers, 33 00:01:12,440 --> 00:01:13,900 then we can see the result 34 00:01:13,900 --> 00:01:15,630 of dividing those two values 35 00:01:15,630 --> 00:01:17,450 and the script terminates. 36 00:01:17,450 --> 00:01:20,690 So, there's actually three flows of control going on 37 00:01:20,690 --> 00:01:21,970 in this script. 38 00:01:21,970 --> 00:01:24,400 There's the flow of control that occurs 39 00:01:24,400 --> 00:01:26,950 when we attempt to divide by zero 40 00:01:26,950 --> 00:01:29,140 and we display a message indicating that 41 00:01:29,140 --> 00:01:31,750 and then simply continue by prompting the user 42 00:01:31,750 --> 00:01:33,340 for input once again. 43 00:01:33,340 --> 00:01:34,640 There is the flow of control 44 00:01:34,640 --> 00:01:37,640 that occurs if the user types non-integer value 45 00:01:37,640 --> 00:01:39,970 like hello, in which case again, 46 00:01:39,970 --> 00:01:42,910 we get an error message and then we prompt the user 47 00:01:42,910 --> 00:01:44,990 for the numerator once again 48 00:01:44,990 --> 00:01:46,700 and then there's the flow of control 49 00:01:46,700 --> 00:01:48,770 for a successful division 50 00:01:48,770 --> 00:01:52,090 which does in fact lead us to terminating the script 51 00:01:52,090 --> 00:01:54,420 after the division is performed. 52 00:01:54,420 --> 00:01:56,850 So, let's take a look at the code for this 53 00:01:56,850 --> 00:01:59,630 and those three flows of control. 54 00:01:59,630 --> 00:02:02,330 So, for the code, we have this script 55 00:02:02,330 --> 00:02:04,220 and we haven't looked at a script for a while, 56 00:02:04,220 --> 00:02:05,770 so just as a reminder, 57 00:02:05,770 --> 00:02:08,170 we always include a comment at the beginning 58 00:02:08,170 --> 00:02:09,340 of the script file 59 00:02:09,340 --> 00:02:11,670 that specifies the name of the file 60 00:02:11,670 --> 00:02:13,960 so you can find it on disk 61 00:02:13,960 --> 00:02:16,460 and we have a doc string that is used 62 00:02:16,460 --> 00:02:19,660 to describe the purpose of the string. 63 00:02:19,660 --> 00:02:23,130 Now in this script we have an infinite while loop 64 00:02:23,130 --> 00:02:26,600 and the while loop is going to execute the statement 65 00:02:26,600 --> 00:02:29,240 in its suite which is a try statement 66 00:02:29,240 --> 00:02:31,610 in this example and as you can see, 67 00:02:31,610 --> 00:02:34,280 the try statement has code in it, 68 00:02:34,280 --> 00:02:37,230 in its suite and then it has a couple 69 00:02:37,230 --> 00:02:40,360 of except clauses and an else clause, 70 00:02:40,360 --> 00:02:42,810 so we'll talk about all the different pieces here. 71 00:02:42,810 --> 00:02:46,730 Now, in Python, typically you're going to put 72 00:02:46,730 --> 00:02:49,350 in the try suite any statements 73 00:02:49,350 --> 00:02:52,130 that might cause an exception. 74 00:02:52,130 --> 00:02:53,550 The else suite 75 00:02:53,550 --> 00:02:56,800 is where you put code that you want to execute 76 00:02:56,800 --> 00:02:59,350 if no exceptions occur 77 00:02:59,350 --> 00:03:02,670 in the try suite, so in a lot of other programming languages 78 00:03:02,670 --> 00:03:04,130 that have exception handling, 79 00:03:04,130 --> 00:03:06,050 you put in the block of code 80 00:03:06,050 --> 00:03:08,880 for the try, not only the statements 81 00:03:08,880 --> 00:03:10,750 that might cause an exception, 82 00:03:10,750 --> 00:03:12,650 but also any statements 83 00:03:12,650 --> 00:03:16,590 that you don't want to execute if an exception occurs. 84 00:03:16,590 --> 00:03:19,790 In Python that second category, 85 00:03:19,790 --> 00:03:22,430 the statements that you don't want to execute 86 00:03:22,430 --> 00:03:24,030 if an exception occurs, 87 00:03:24,030 --> 00:03:25,850 those get placed in the else block 88 00:03:25,850 --> 00:03:28,170 and they are in the else suite I should say 89 00:03:28,170 --> 00:03:31,770 and those only execute if no exceptions occur 90 00:03:31,770 --> 00:03:33,100 in the try block, 91 00:03:33,100 --> 00:03:34,870 so back up here in the try statement, 92 00:03:34,870 --> 00:03:37,940 we're going to prompt the user for some input, 93 00:03:37,940 --> 00:03:41,090 the input function will obtain the value the user types, 94 00:03:41,090 --> 00:03:44,180 give it back to our program as a string, 95 00:03:44,180 --> 00:03:46,340 we will convert that string to an integer 96 00:03:46,340 --> 00:03:48,140 and assign it to number one, 97 00:03:48,140 --> 00:03:49,820 then we'll do the same thing again 98 00:03:49,820 --> 00:03:53,620 for a second value that will represent the denominator. 99 00:03:53,620 --> 00:03:55,990 If both of those successfully execute, 100 00:03:55,990 --> 00:03:58,050 we will attempt the division. 101 00:03:58,050 --> 00:04:00,460 If that successfully executes, 102 00:04:00,460 --> 00:04:03,140 we will print the result of the division 103 00:04:03,140 --> 00:04:05,050 by executing the else clause 104 00:04:05,050 --> 00:04:08,120 which will also terminate the loop. 105 00:04:08,120 --> 00:04:10,580 On the other hand, going back up above here, 106 00:04:10,580 --> 00:04:14,110 if either of these first two statements in the try suite 107 00:04:14,110 --> 00:04:15,880 causes a value error 108 00:04:15,880 --> 00:04:20,010 because the user did not enter an integer value, 109 00:04:20,010 --> 00:04:23,470 in that case the try suite terminates immediately 110 00:04:23,470 --> 00:04:27,060 and control jumps down to the first 111 00:04:27,060 --> 00:04:28,900 of the except handlers. 112 00:04:28,900 --> 00:04:32,290 Now if I did not enter an integer, 113 00:04:32,290 --> 00:04:34,010 the type of exception I'll get 114 00:04:34,010 --> 00:04:36,300 from these first two statements in the try suite 115 00:04:36,300 --> 00:04:37,640 is a value error, 116 00:04:37,640 --> 00:04:41,810 so that would be the matching exception handler 117 00:04:41,810 --> 00:04:45,680 for the particular type of exception that occurred. 118 00:04:45,680 --> 00:04:49,720 In that case, we will print You must enter two integers. 119 00:04:49,720 --> 00:04:53,840 Now once you reach the end of an except clause's suite, 120 00:04:53,840 --> 00:04:57,350 that exception is considered to be handled. 121 00:04:57,350 --> 00:05:00,830 All additional except clauses are skipped 122 00:05:00,830 --> 00:05:04,320 as is the else clause, so once we print 123 00:05:04,320 --> 00:05:06,250 you must enter two integers, 124 00:05:06,250 --> 00:05:10,390 the rest of the try statement will be skipped 125 00:05:10,390 --> 00:05:13,210 and control will continue with the first statement 126 00:05:13,210 --> 00:05:14,930 after the try statement 127 00:05:14,930 --> 00:05:17,160 but in this case, that's the end of our loop, 128 00:05:17,160 --> 00:05:18,960 so we'll go back to the top of the loop 129 00:05:18,960 --> 00:05:21,723 and we will try everything once again. 130 00:05:22,900 --> 00:05:26,090 If we successfully read in the first two values, 131 00:05:26,090 --> 00:05:27,950 the numerator and the denominator, 132 00:05:27,950 --> 00:05:31,230 then we'll try to perform the division. 133 00:05:31,230 --> 00:05:33,950 If the numerator is zero, 134 00:05:33,950 --> 00:05:36,520 in that case, again the try statement 135 00:05:36,520 --> 00:05:39,140 or the try suite terminates immediately. 136 00:05:39,140 --> 00:05:41,040 If we had additional statements 137 00:05:41,040 --> 00:05:43,270 before this first except clause, 138 00:05:43,270 --> 00:05:45,730 they would not execute. 139 00:05:45,730 --> 00:05:48,800 Control flow jumps to the except clauses 140 00:05:48,800 --> 00:05:50,470 and this first except clause 141 00:05:50,470 --> 00:05:53,590 is not for zero division errors, 142 00:05:53,590 --> 00:05:57,100 so again we're talking about the case of dividing by zero, 143 00:05:57,100 --> 00:05:59,230 in that case, we skip that except clause 144 00:05:59,230 --> 00:06:00,470 and go to the next one. 145 00:06:00,470 --> 00:06:05,470 That except clause does in fact match a ZeroDivisionError, 146 00:06:05,600 --> 00:06:08,030 so this one will execute, 147 00:06:08,030 --> 00:06:10,860 we will print Attempted to divide by zero. 148 00:06:10,860 --> 00:06:13,270 If there were any further except clauses, 149 00:06:13,270 --> 00:06:14,470 they would be skipped, 150 00:06:14,470 --> 00:06:16,020 the else clause will be skipped 151 00:06:16,020 --> 00:06:18,520 because we're in the exception handling flow 152 00:06:18,520 --> 00:06:20,670 of control and we will proceed 153 00:06:20,670 --> 00:06:24,090 with the first statement after the enter try statement 154 00:06:24,090 --> 00:06:26,280 which in this case means go back to the top 155 00:06:26,280 --> 00:06:28,980 of the loop and try it all again. 156 00:06:28,980 --> 00:06:31,800 Now if we successfully read the two integers 157 00:06:31,800 --> 00:06:34,400 and successfully perform the division, 158 00:06:34,400 --> 00:06:36,720 all the except clauses will be skipped 159 00:06:36,720 --> 00:06:39,030 and the else clause will execute. 160 00:06:39,030 --> 00:06:42,010 That will print out the results of the division 161 00:06:42,010 --> 00:06:43,620 and we will terminate the loop 162 00:06:43,620 --> 00:06:46,180 at that point and because we have nothing more 163 00:06:46,180 --> 00:06:47,860 in our script to execute, 164 00:06:47,860 --> 00:06:51,163 the script will terminate in that case as well.