• Facing Errors In Python - Part 5

    Handling more specific to less specific exceptions

    One strategy for handling exceptions is to provide specific except clauses for all known exceptions and generic except clauses to handle unknown exceptions. You can see the exception hierarchy that Python uses at https://docs.python.org/3.3/library/exceptions. html#exception-hierarchy. When viewing this chart, BaseException is the uppermost exception. Most exceptions are derived from Exception. When working through math errors, you can use the generic
    ArithmeticError or a more specific ZeroDivisionError exception.

    Python evaluates except clauses in the order in which they appear in the source code file. The first clause is examined first, the second clause is exam-ined second, and so on. The following steps help you examine an example that demonstrates the importance of using the correct exception order. In this case, you perform tasks that result in math errors.

     Open a Python File window.

    You see an editor in which you can type the example code.

     Type the following code into the window — pressing Enter after each line:

    try:

    Value1 = int(input("Type the first number: ")) Value2 = int(input("Type the second number: ")) Output = Value1 / Value2
    except ValueError:
    print("You must type a whole number!") except KeyboardInterrupt:
    print("You pressed Ctrl+C!") except ArithmeticError:

    print("An undefined math error occurred.") except ZeroDivisionError:
    print("Attempted to divide by zero!") else:
    print(Output)

    The code begins by obtaining two inputs: Value1 and Value2. The first two except clauses handle unexpected input. The second two except clauses handle math exceptions, such as dividing by zero. If everything goes well with the application, the else clause executes, which prints the result of the operation.

     Choose RunRun Module.

    You see a Python Shell window open. The application asks you to type the first number.

     Type Hello and press Enter.

    As expected, Python displays the ValueError exception message. However, it always pays to check for potential problems.

     Choose RunRun Module again.

    You see a Python Shell window open. The application asks you to type the first number.

     Type 8 and press Enter.

    The application asks you to enter the second number.


     Type 0 and press Enter.

    You see the error message for the ArithmeticError exception. What you should actually see is the ZeroDivisionError exception because it’s more specific than the ArithmeticError exception.

    8. Reverse the order of the two exceptions so that they look like this:

    except ZeroDivisionError: print("Attempted to divide by zero!")
    except ArithmeticError:
    print("An undefined math error occurred.")

     Perform Steps 5 through 7 again.

    This time, you see the ZeroDivisionError exception message because the exceptions appear in the correct order.

     Perform Steps 5 through 7 again, but type 2 for the second number instead of 0.

    This time, the application finally reports an output value of 4.0. Division results in a floating-point value unless you specify that you want an integer output by using the floor division operator (//).


    Nested exception handling

    Sometimes you need to place one exception-handling routine within another in a process called nesting. When you nest exception-handling routines, Python tries to find an exception handler in the nested level first and then moves to the outer layers. You can nest exception-handling routines as deeply as needed to make your code safe.


    One of the more common reasons to use a dual layer of exception-handling code is when you want to obtain input from a user and need to place the input code in a loop to ensure that you actually get the required information. The following steps demonstrate how this sort of code might work.

    Open a Python File window.

    You see an editor in which you can type the example code.


     Type the following code into the window — pressing Enter after each line:

    TryAgain = True

    while TryAgain:

    try:

    Value = int(input("Type a whole number. ")) except ValueError:
    print("You must type a whole number!")

    try:

    DoOver = input("Try again (y/n)? ") except:
    print("OK, see you next time!") TryAgain = False
    else:
    if (str.upper(DoOver) == "N"): TryAgain = False

    except KeyboardInterrupt: print("You pressed Ctrl+C!") print("See you next time!") TryAgain = False
    else:

    print(Value) TryAgain = False

    The code begins by creating an input loop. Using loops for this type of purpose is actually quite common in applications because you don’t want the application to end every time an input error is made. This is a simpli-fied loop, and normally you create a separate function to hold the code.

    When the loop starts, the application asks the user to type a whole number. It can be any integer value. If the user types any non-integer value or presses Ctrl+C, Cmd+C, or another interrupt key combination, the exception-handling code takes over. Otherwise, the application prints the value that the user supplied and sets TryAgain to False, which causes the loop to end.

    A ValueError exception can occur when the user makes a mistake. Because you don’t know why the user input the wrong value, you have to ask if the user wants to try again. Of course, getting more input from the user could generate another exception. The inner try . . . except code block handles this secondary input.

    Notice the use of the str.upper() function when getting character input from the user. This function makes it possible to receive y or Y as input and accept them both. Whenever you ask the user for character input, it’s a good idea to convert lowercase characters to uppercase so that you can perform a single comparison (reducing the potential for error).

    The KeyboardInterrupt exception displays two messages and then exits automatically by setting TryAgain to False. The KeyboardInterrupt occurs only when the user presses a specific key combination designed to end the application. The user is unlikely to want to continue using the application at this point.

     Choose RunRun Module.

    You see a Python Shell window open. The application asks the user to input a whole number.

     Type Hello and press Enter.

    The application displays an error message and asks whether you want to try again.

     Type Y and press Enter.

    The application asks you to input a whole number again.

     Type 5.5 and press Enter.

    The application again displays the error message and asks whether you want to try again.

     Press Ctrl+C, Cmd+C, or another key combination to interrupt the application.

    The application ends. Notice that the message is the one from the inner exception. The application never gets to the outer exception because the inner exception handler provides generic exception handling.

     Choose RunRun Module.

    You see a Python Shell window open. The application asks the user to input a whole number.


     Press Ctrl+C, Cmd+C, or another key combination to interrupt the application.

    The application ends. Notice that the message is the one from the outer exception. In Steps 7 and 9, the user ends the application by pressing an interrupt key. However, the application uses two different exception handlers to address the problem.

    Raising Exceptions

    So far, the examples in this Post have reacted to exceptions. Something happens and the application provides error-handling support for that event. However, situations arise for which you may not know how to handle an error event during the application design process. Perhaps you can’t even handle the error at a particular level and need to pass it up to some other level to handle. In short, in some situations, your application must generate an excep-tion. This act is called raising (or sometimes throwing) the exception. The fol-lowing sections describe common scenarios in which you raise exceptions in specific ways.



    Raising exceptions during exceptional conditions

    The example in this section demonstrates how you raise a simple exception­ — that it doesn’t require anything special. The following steps simply create the exception and then handle it immediately.

    Open a Python File window.

    You see an editor in which you can type the example code.

     Type the following code into the window — pressing Enter after each line:

    try:
    raise ValueError except ValueError:
    print("ValueError Exception!")

    You wouldn’t ever actually create code that looks like this, but it shows you how raising an exception works at its most basic level. In this case, the raise call appears within a try . . . except block. A basic raise call simply provides the name of the exception to raise (or throw). You can also provide arguments as part of the output to provide additional information.

    Notice that this try . . . except block lacks an else clause because there is nothing to do after the call. Although you rarely use a try . . . except block in this manner, you can. You may encounter situations like this one sometimes and need to remember that adding the else clause is purely optional. On the other hand, you must add at least one except clause.

     Choose RunRun Module.

    You see a Python Shell window open. The application displays the expected exception text.



  • 0 comments:

    Post a Comment

    Powered by Blogger.

    Tags

    Popular Posts