Lesson 5 · Python for Banking and Finance
Effective Error Handling in Banking Systems Using Python for Secure Financial Software
In this lesson, we will learn how to handle errors when processing banking data in Python. Error handling is important in banking because even small…
- CoursePython for Banking and Finance
- Lesson5 of 24
- Video21 min
- FormatJupyter notebook · 19 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbError Handling in Banking Systems#
- In this lesson, we will learn how to handle errors when processing banking data in Python.
- Error handling is important in banking because even small mistakes in code or data can lead to financial losses and compliance issues.
- You will discover how to identify, handle, and debug different types of errors that commonly occur in banking applications.
- By the end, you will be confident writing safer banking code and debugging real-world financial data!
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
np.random.seed(42)
Overview of Data Used in Banking Error Handling#
- Banking data includes transactions like withdrawals, deposits, transfers, and more.
- Data is usually structured in tables, with columns for customer IDs, amounts, dates, and transaction types.
- Beginners often make mistakes like working with missing values, wrong column names, or mismatched data types.
# Create a synthetic banking transactions DataFrame
n_transactions = 1000
n_customers = 200
df = pd.DataFrame({
'transaction_id': range(1, n_transactions + 1),
'customer_id': np.random.choice([f'CUST_{i:04d}' for i in range(1, n_customers + 1)], n_transactions),
'amount': np.round(np.random.normal(150, 60, n_transactions), 2),
'transaction_type': np.random.choice(['Debit', 'Credit'], n_transactions),
'channel': np.random.choice(['ATM', 'Online', 'Branch', 'POS'], n_transactions),
'date': pd.date_range(start='2024-01-01', periods=n_transactions, freq='h')
})
print('Shape:', df.shape)
print(df.head(3))
# Example 1: Accessing a non-existent column (beginner error)
try:
print(df['balance'])
except KeyError as e:
print('Error:', e)
# Example 2: Division by zero in transaction calculations (beginner error)
try:
df['percentage'] = df['amount'] / 0
except ZeroDivisionError as e:
print('Error:', e)
# Example 3: Type conversion errors (beginner error)
df['error_amount'] = ['one hundred'] * len(df)
try:
df['error_amount'] = df['error_amount'].astype(float)
except ValueError as e:
print('Error:', e)
# Example 4: Handling missing data (intermediate error)
df_missing = df.copy()
df_missing.loc[0:10, 'amount'] = np.nan
try:
total = df_missing['amount'].sum()
print('Total amount:', total)
except Exception as e:
print('Error:', e)
# Example 5: Ensuring transaction amounts are positive (intermediate error)
negative_rows = df[df['amount'] < 0]
if not negative_rows.empty:
print('Found negative amounts! Fixing them now...')
df.loc[df['amount'] < 0, 'amount'] = 0
else:
print('All amounts are positive.')
# Example 6: Catching and logging exceptions to a file (intermediate)
import logging
logging.basicConfig(filename='banking_errors.log', level=logging.ERROR, format='%(asctime)s %(levelname)s: %(message)s')
try:
df['transaction_id'] = df['transaction_id'].astype(float)
# purposely create a conversion issue
df.at[0, 'transaction_id'] = 'error_id'
df['transaction_id'] = df['transaction_id'].astype(int)
except Exception as e:
print('Error logged to file.')
logging.error('Problem with transaction_id conversion: %s', e)
# Example 7: Using assertions to enforce business rules (intermediate)
assert df['amount'].min() >= 0, 'All transaction amounts must be non-negative!'
print('All transaction amounts are non-negative.')
# Example 8: Handling multiple exception types (intermediate)
try:
# Create a possible index error scenario
print(df.iloc[5000])
except IndexError as e:
print('IndexError:', e)
except Exception as e:
print('Other error:', e)
# Example 9: Custom exception for suspicious transactions (advanced)
class SuspiciousTransaction(Exception):
pass
def validate_transaction(amount):
if amount > 5000:
raise SuspiciousTransaction('Transaction above allowable threshold!')
try:
test_amount = 6000
validate_transaction(test_amount)
except SuspiciousTransaction as e:
print('Custom Exception:', e)
# Example 10: Handling errors in batch transaction processing (advanced)
def process_transactions(df):
errors = []
for idx, row in df.iterrows():
try:
if row['amount'] < 0:
raise ValueError('Negative transaction amount found!')
# Simulate occasional type error
if idx == 13:
x = 'oops' + 10
except Exception as e:
errors.append((idx, str(e)))
return errors
batch_errors = process_transactions(df)
print('Batch errors:', batch_errors[:3])
# Example 11: Using finally for important cleanup after error (advanced)
try:
risky = 10 / 0
except ZeroDivisionError:
print('Division by zero!')
finally:
print('This will always run, useful for cleanup.')
Debugging banking data: locating common errors#
- When your code fails, focus on the error message and the data used for that code.
- Print() and df.info() are your best tools for finding issues.
- In banking, errors can waste time or even stop trading or payment batches.
# Debugging: Checking data types and missingness
print(df.info())
print(df.isnull().sum())
Best practices for error handling in banking#
- Always catch exceptions when reading, writing, or transforming financial data.
- Validate inputs, outputs, and intermediate values.
- Use logging for serious problems, not just print().
- Assert business rules early and test boundary cases.
# Pattern: Context-specific error messages for users
try:
user_input = int('ten')
except ValueError as e:
print('Invalid entry: please enter a number amount, not text!')
# Pattern: Using context to provide more helpful error logs
for idx, row in df.iterrows():
try:
val = int(row['amount'])
except Exception as e:
print(f'Error at transaction {row.transaction_id}: {e}')
break
# All-in-one practice: Validate uploaded transactions and write to file with error handling
def validate_and_save(df):
errors = []
valid = []
for idx, row in df.iterrows():
try:
amount = float(row['amount'])
assert amount >= 0
valid.append(row)
except Exception as e:
errors.append({'id': row['transaction_id'], 'error': str(e)})
pd.DataFrame(valid).to_csv('valid_transactions.csv', index=False)
pd.DataFrame(errors).to_csv('transaction_errors.csv', index=False)
validate_and_save(df)
print('Done validating and writing files.')
# BONUS: Preview valid transactions file
preview = pd.read_csv('valid_transactions.csv')
print('Preview:', preview.head(3))
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



