Exception Handling is a mechanism to handle runtime errors such as ClassNotFoundException, IOException, SQLException, RemoteException, etc.

There are 2 stages where errors may happen in a program

  • During compilation -> Syntax Error
  • During execution -> Exceptions

Syntax Error

  • Something in the program is not written according to the program grammar.
  • Error is raised by the interpreter/compiler
  • You can solve it by rectifying the program

Syntax Errors

# Examples of syntax error
print 'hello world'

Explanation:

  • Demonstrates syntax errors, such as missing parentheses in the print statement and misspelling of keywords.
  • Syntax errors are caught by the Python interpreter during code compilation.

Other examples of syntax error

  • Leaving symbols like colon, brackets
  • Misspelling a keyword
  • Incorrect indentation
  • empty if/else/loops/class/functions

Runtime Exceptions

# IndexError
L = [1, 2, 3]
L[100]

# ModuleNotFoundError
import mathi
math.floor(5.3)

# KeyError
d = {'name': 'nabin'}
d['age']

# TypeError
1 + 'a'

# ValueError
int('a')

# NameError
print(k)

# AttributeError
L = [1, 2, 3]
L.upper()
...

Explanation:

  • Illustrates common runtime exceptions like IndexError, ModuleNotFoundError, KeyError, TypeError, ValueError, NameError, and AttributeError.
  • These exceptions occur during program execution and can be caught and handled.

Handling Exceptions

# Why is it important to handle exceptions
# how to handle exceptions
# -> Try except block
...

Explanation:

  • Explains the importance of handling exceptions during runtime.
  • Introduces the try and except blocks for handling exceptions.

Try-Except Block

# let's create a file
with open('sample.txt', 'w') as f:
    f.write('hello world')

# try catch demo
try:
    with open('sample1.txt', 'r') as f:
        print(f.read())
except:
    print('sorry file not found')
...

Explanation:

  • Demonstrates the use of try and except blocks to handle file-related exceptions.
  • Provides a simple example of catching a generic exception.

Specific Exception Handling

# catching specific exception
try:
    ...
except FileNotFoundError:
    print('file not found')
except NameError:
    print('variable not defined')
except ZeroDivisionError:
    print("can't divide by 0")
except Exception as e:
    print(e)
...

Explanation:

  • Shows how to catch specific exceptions using multiple except blocks.
  • The Exception as e block catches any remaining exceptions.

else and finally Blocks

# else
try:
    ...
except FileNotFoundError:
    print('file not found')
except Exception:
    print('something went wrong')
else:
    print(f.read())

# finally
try:
    ...
except FileNotFoundError:
    print('file not found')
except Exception:
    print('something went wrong')
else:
    print(f.read())
finally:
    print('this will be printed regardless')
...

Explanation:

  • Introduces the else block, which is executed if no exceptions occur.
  • Introduces the finally block, which is executed regardless of whether an exception occurred.

raise Statement

# raise Exception
raise ZeroDivisionError('trying this out')
...

Explanation:

  • Shows how to manually raise exceptions using the raise statement.
  • Provides an example of raising a ZeroDivisionError with a custom message.

Custom Exceptions

# creating custom exceptions
...
class MyException(Exception):
    def __init__(self, message):
        print(message)

class Bank:
    def __init__(self, balance):
        self.balance = balance

    def withdraw(self, amount):
        if amount < 0:
            raise MyException('amount cannot be negative')
        if self.balance < amount:
            raise MyException('insufficient funds')
        self.balance = self.balance - amount

obj = Bank(10000)
try:
    obj.withdraw(5000)
except MyException as e:
    pass
else:
    print(obj.balance)
...

Explanation:

  • Demonstrates creating custom exceptions by inheriting from the Exception class.
  • Uses a custom MyException class in the context of a simple banking example.

Custom Exception Hierarchy

# creating custom exceptions
...
class SecurityError(Exception):
    def __init__(self, message):
        print(message)

    def logout(self):
        print('logout')

class Google:
    def __init__(self, name, email, password, device):
        self.name = name
        self.email = email
        self.password = password
        self.device = device

    def login(self, email, password, device):
        if device != self.device:
            raise SecurityError('device mismatch')
        if email == self.email and password == self.password:
            print('welcome')
        else:
            print('login error')

obj = Google('nabin', 'nabin@gmail.com', '1234', 'android')

try:
    obj.login('nabin@gmail.com', '1234', 'windows')
except SecurityError as e:
    e.logout()
else:
    print(obj.name)
finally:
    print('database connection closed')
...

Explanation:

  • Demonstrates creating a hierarchy of custom exceptions with SecurityError and using it in a more complex scenario involving login.

Advanced Topics: GridSearchCV with Pipelines

# using GridSearchCV with Pipelines
...
df = pd.read_csv('train.csv')

numerical_features = ['Age', 'Fare']
numerical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())
])

categorical_features = ['Embarked', 'Sex']
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('ohe', OneHotEncoder(handle_unknown='ignore'))
])

preprocessor = ColumnTransformer(
    transformers=[
        ('num', numerical_transformer, numerical_features),
        ('cat', categorical_transformer, categorical_features)
    ]
)

clf = Pipeline([
    ('preprocessor', preprocessor),
    ('classifier', LogisticRegression())
])

param_grid = {
    'preprocessor__num__imputer__strategy': ['mean', 'median'],
    'preprocessor__cat__imputer__strategy': ['most_frequent', 'constant'],
    'classifier__C': [0.1, 1.0, 10, 100]
}

grid_search =

 GridSearchCV(clf, param_grid, cv=10)
grid_search.fit(X_train, y_train)

print(f'Best params:')
print(grid_search.best_params_)
print(f'Internal CV score: {grid_search.best_score_:.3f}')

cv_results = pd.DataFrame(grid_search.cv_results_)
cv_results = cv_results.sort_values("mean_test_score", ascending=False)
print(cv_results[['param_classifier__C', 'param_preprocessor__cat__imputer__strategy', 'param_preprocessor__num__imputer__strategy', 'mean_test_score']])
...

Explanation:

  • Introduces advanced concepts like using GridSearchCV with Pipelines for hyperparameter tuning.

This code provides a comprehensive overview of exception handling in Python, ranging from basic concepts to more advanced scenarios. It covers syntax errors, runtime exceptions, handling techniques, custom exceptions, and advanced topics like grid search with pipelines. It’s a great resource for beginners to understand how to handle errors and exceptions in Python.

6 Replies to “Exception Handling in python”

  1. Declan Rice https://declan-rice.prostoprosport-fr.com Footballeur anglais, milieu defensif du club d’Arsenal et de l’equipe nationale equipe d’Angleterre. Originaire de Kingston upon Thames, Declan Rice s’est entraine a l’academie de football de Chelsea des l’age de sept ans. En 2014, il devient joueur de l’academie de football de West Ham United.

Leave a Reply

Your email address will not be published. Required fields are marked *