EXCEPTIONS

In Python, exception handling allows you to gracefully manage errors and unexpected situations that may occur during the execution of your code. Here's an explanation of various elements related to exception handling:

Try-Except Block:

The try statement is used to wrap the code that may raise an exception. The except block is used to handle the exception that occurred within the try block.

try:
    # Code that may raise an exception
    result = 10 / 0
except ZeroDivisionError:
    # Handling the exception
    print("Error: Division by zero")

Else Block:

The else block is executed if no exceptions are raised within the try block. It is typically used to perform actions that should only occur if the code in the try block succeeds.

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Error: Division by zero")
else:
    print("Division successful. Result:", result)

Pass Statement:

The pass statement is a null operation that does nothing when executed. It is used as a placeholder where Python syntax requires a statement but no action needs to be taken.

try:
    result = 10 / 2
except ZeroDivisionError:
    # Do nothing
    pass

Raise Statement:

The raise statement is used to explicitly raise an exception. You can raise built-in exceptions or custom exceptions.

def validate_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative")
    elif age < 18:
        raise ValueError("You must be at least 18 years old")

try:
    validate_age(-5)
except ValueError as ve:
    print("Error:", ve)

Finally Block:

The finally block is used to execute cleanup code that should always be run, regardless of whether an exception occurred or not.

try:
    file = open("example.txt", "r")
    # Perform file operations
except FileNotFoundError:
    print("File not found")
finally:
    file.close()  # Always close the file, even if an exception occurs

These elements provide a robust mechanism for handling errors and ensuring that your code behaves predictably in various scenarios.