<jupyter_start><jupyter_text>Lab 3: Exceptions Handling in Python  Exceptions  ReadingSkim over [Python's documentation on built-in exceptions](https://docs.python.org/3/library/exceptions.html).  `try`/`except`/`else`/`finally`Python provides `try` and `except` blocks , similar to other languages' `try` and `catch` blocks, for basic exceptional control flow.  Age Checker Exercise  `get_age`Write a function `get_age` that asks a user for their age, which must be a positive integer between 0 and 123 inclusive (the oldest human recorded, <NAME>, died at the age of 122). If the user enters something that's not an integer, you should reprompt them. However, if they enter an integer and it's out of range, you should raise an exception. That is, you should keep reprompting them until they enter something that can be converted into an integer, and then return that number if it's in range, and raise an exception otherwise. Two sample runs are shown below:``` (Call 1)How old are you? ABCInvalid integer input.How old are you? -4.5Invalid integer input.How old are you? 31 returns 36 (Call 2)How old are you? XYZInvalid integer input.How old are you? 128 raises some exceptionTraceback (most recent call last):  File "", line 1, in ValueError: Age 128 out of range```<jupyter_code>def get_age(min_age=0, max_age=123):
    is_int = False
    while not is_int:
        try:
            age = int(input("How old are you? ")) # => the output of the inner function becomes the input for the outer function
            is_int = True # be sure to change the argument of the while loop
        except Exception:
            print("Invalid integer input.")
    
    if age < min_age or age > max_age: # alternatively if age in range(min_age, max_age+1)
        raise ValueError(f'Age {age} out of range') # f'' allows to format the string inserting a variable name
    
    return age
# (Call 1)
get_age()
# (Call 2)
get_age()<jupyter_output><empty_output><jupyter_text>Custom ExceptionsWrite a custom exception class called `OutOfRangeError` that inherits from `ValueError` which indicates that a given value is outside of an acceptable range. What does this class definition look like? What is the body of the class?Rewrite your code in `get_age` to use this custom exception.<jupyter_code>class OutOfRangeError(ValueError):
    
    def __init__(self, given_value, acceptable_range):
        super().__init__(f'The value {given_value} is out of range ({acceptable_range.start}, {acceptable_range.stop})')
        
def get_age(min_age=0, max_age=123):
    is_int = False
    while not is_int:
        try:
            age = int(input("How old are you? ")) # => the output of the inner function becomes the input for the outer function
            is_int = True # be sure to change the argument of the while loop
        except Exception:
            print("Invalid integer input.") # => age is defined, otherwise it loops over and over
    
    if age < min_age or age > max_age: # alternatively if age in range(min_age, max_age+1)
        raise OutOfRangeError(age, range(min_age,max_age+1)) # f'' allows to format the string inserting a variable name
    
    return age
get_age()<jupyter_output><empty_output><jupyter_text>Using `else` and `finally` (maybe)Rewrite your `get_age` function to use the `else` block, and optionally the `finally` block. As is consistent with general style guidelines, try to keep the `try` block as short as possible, containing just the code that might raise the exception you're trying to catch.<jupyter_code>class OutOfRangeError(ValueError):
    
    def __init__(self, given_value, acceptable_range):
        super().__init__(f'The value {given_value} is out of range ({acceptable_range.start}, {acceptable_range.stop})')
        
def get_age(min_age=0, max_age=123):
    while True:
        answer = input("How old are you? ")
        try:
            age = int(answer)
        except ValueError:
            print("Invalid integer input.")
        else:
            if age < min_age or age > max_age:
                raise OutOfRangeError(age, range(min_age,max_age+1))
            else:
                return age
get_age()<jupyter_output><empty_output><jupyter_text>ReraisingConsider the following code:```Pythontry:    print("in try")     (A)except Exception as exc:    print("in except")     (B)else:    print("in else")     (C)finally:    print("in finally")     (D)```We're going to add some errors to this code block, which currently prints out```in tryin elsein finally```For each of the labelled locations `(A), (B), (C), (D)`, which statements print out if we `raise Exception()` at that position? Run the code to test your hypotheses.<jupyter_code># Case (A)
try:
    print("Try")
    raise Exception('An on-purpose exception.')
except Exception as exc:
    print("Except")
else:
    print("Else")
finally:
    print("Finally")
# Case (B)
try:
    print("Try")
except Exception as exc:
    print("Except")
    raise Exception('An on-purpose exception.')
else:
    print("Else")
finally:
    print("Finally")
# Case (C)
try:
    print("Try")
except Exception as exc:
    print("Except")
else:
    print("Else")
    raise Exception('An on-purpose exception.')
finally:
    print("Finally")
# Case (D)
try:
    print("Try")
except Exception as exc:
    print("Except")
else:
    print("Else")
finally:
    print("Finally")
    raise Exception('An on-purpose exception.')
# Case (AB)
try:
    print("Try")
    raise Exception('An on-purpose exception.')
except Exception as exc:
    print("Except")
    raise Exception('Another on-purpose exception.')
else:
    print("Else")
finally:
    print("Finally")
# Case (AC)
try:
    print("Try")
    raise Exception('An on-purpose exception.')
except Exception as exc:
    print("Except")
else:
    print("Else")
    raise Exception('Another on-purpose exception.')
finally:
    print("Finally")
# Case (AD)
try:
    print("Try")
    raise Exception('An on-purpose exception.')
except Exception as exc:
    print("Except")
else:
    print("Else")
finally:
    print("Finally")
    raise Exception('Another on-purpose exception.')<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup