Core Python: Part 2

Exception Handling

Core Python: Part 2

Check out the previous part: Core Python: Part 1

try... except...:

In the previous part, we learned about the exceptions. In this part, we continue learning about how to handle them. Using ...try and ...except block. You might think of an exception that might occur given some condition but you don't want it to stop your program workflow. Then we put that 'might cause exception' line in the try block and the way to handle it in the except block.

try:
    number = int(input("Enter a number: "))
    result = 10 / number
    print("Result:", result)
except ZeroDivisionError:
    print("Error: Cannot divide by zero.")
except ValueError:
    print("Error: Invalid input. Please enter a valid number.")
except Exception as e:
    print("An error occurred:", e)

print('I will run anyhow')

Here, we think of possible exceptions that might occur such as ZeroDivisionError and ValueError. We handle particular cases and any other kind of error is handled by Exception as e. Once the exception is handled, program workflow continues and the line 'I will run anyhow' will be printed without exiting from the program. If there is any exception found, then line 3 in the try block that prints the result will be executed and the result is printed and none of the except blocks will be executed.

Warning: The bad practice of handling exceptions should be avoided. That is...

try:
    number = int(input("Enter a number: "))
    result = 10 / number
except:
    print('Error')

This way of handling every exception using except block makes the code hard to debug and hence should be avoided.

Raising Exceptions:

Sometimes we intentionally want to end the program workflow if the intended input is not provided and in that case, we can raise the exception explicitly. The program stops if b is equal to 0.

def divide(a, b):
    if b == 0:
        raise ZeroDivisionError("Division by zero is not allowed")
    return a / b

# Output:
# raise ZeroDivisionError("Division by zero is not allowed")
# ZeroDivisionError: Division by zero is not allowed
class MyCustomError(Exception):
    def __init__(self, message, additional_info=None):
        super().__init__(message)
        self.additional_info = additional_info

def raise_custom_error(value):
    if value < 0:
        error_message = "Value cannot be negative"
        raise MyCustomError(error_message, additional_info=value)

try:
    raise_custom_error(-5)
except MyCustomError as e:
    print("Caught custom exception:", e)
    print("Additional info:", e.additional_info)

# Output:
# Caught custom exception: Value cannot be negative
# Additional info: -5

AssertionError:

assert is a keyword in Python that evaluates a conditional expression and raises AssertionError if the expression is not True. You can pass an optional error message. assert statement will stop the program if the condition evaluates to false. Hence they are only useful during development and testing and are not meant to be used for error handling in production code. We use exception handling and other mechanisms in the production code. assert statements are typically disabled in optimized and production code using the -o (optimize) command-line switch or the PYTHONOPTIMIZE environment variable.

def divide(a, b):
    assert b != 0, "Division by zero is not allowed"
    return a / b

result = divide(10, 0)  # This will raise an AssertionError with the specified error message
print('Always pass a valid value')

# Output:
# assert b != 0, "Division by zero is not allowed"
# AssertionError: Division by zero is not allowed

try-except-else-finally

else and finally blocks are the two optional that come after the except block. else block will be executed only if except is not executed that is when there is no error but finally block will be executed in either case.

try:
    value = int(input("Enter a number: "))
    result = 10 / value
except ZeroDivisionError:
    print("Error: Cannot divide by zero.")
except ValueError:
    print("Error: Invalid input. Please enter a valid number.")
else:
    print("Result:", result)
finally:
    print("Execution complete.")

# Output:
# Enter a number: 0
# Error: Cannot divide by zero.
# Execution complete.

=============================== RESTART =======================================

# Enter a number: 10
# Result: 1.0
# Execution complete.

Check out the next part: Core Python: Part 3