Practical Validation Examples
Real-World Validation Scenarios
1. Financial Transaction Validation
class BankAccount:
def __init__(self, balance=0):
self.validate_balance(balance)
self._balance = balance
def validate_balance(self, amount):
if not isinstance(amount, (int, float)):
raise TypeError("Balance must be a number")
if amount < 0:
raise ValueError("Initial balance cannot be negative")
def deposit(self, amount):
if amount <= 0:
raise ValueError("Deposit amount must be positive")
self._balance += amount
def withdraw(self, amount):
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
if amount > self._balance:
raise ValueError("Insufficient funds")
self._balance -= amount
Validation Complexity Levels
Complexity Level |
Characteristics |
Example |
Basic |
Simple type checking |
Integer validation |
Intermediate |
Range and format validation |
Email format |
Advanced |
Complex business logic |
Financial transactions |
2. User Registration Validation
class UserRegistration:
def __init__(self, username, email, age):
self.validate_username(username)
self.validate_email(email)
self.validate_age(age)
self.username = username
self.email = email
self.age = age
def validate_username(self, username):
if not isinstance(username, str):
raise TypeError("Username must be a string")
if len(username) < 3 or len(username) > 20:
raise ValueError("Username must be between 3 and 20 characters")
def validate_email(self, email):
import re
email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if not re.match(email_regex, email):
raise ValueError("Invalid email format")
def validate_age(self, age):
if not isinstance(age, int):
raise TypeError("Age must be an integer")
if age < 18 or age > 120:
raise ValueError("Age must be between 18 and 120")
Validation Flow Diagram
flowchart TD
A[Input Data] --> B{Validate Username}
B -->|Valid| C{Validate Email}
B -->|Invalid| D[Reject Registration]
C -->|Valid| E{Validate Age}
C -->|Invalid| D
E -->|Valid| F[Complete Registration]
E -->|Invalid| D
3. Configuration Validation
class AppConfiguration:
def __init__(self, config_dict):
self.validate_config(config_dict)
self.config = config_dict
def validate_config(self, config):
required_keys = ['database_url', 'max_connections', 'timeout']
## Check for required keys
for key in required_keys:
if key not in config:
raise KeyError(f"Missing required configuration: {key}")
## Validate database URL
if not config['database_url'].startswith(('postgresql://', 'mysql://')):
raise ValueError("Invalid database URL format")
## Validate max connections
if not isinstance(config['max_connections'], int) or config['max_connections'] < 1:
raise ValueError("Max connections must be a positive integer")
## Validate timeout
if not isinstance(config['timeout'], (int, float)) or config['timeout'] <= 0:
raise ValueError("Timeout must be a positive number")
Validation Best Practices
- Implement comprehensive input validation
- Use type checking and range validation
- Provide clear and specific error messages
- Validate data at the point of entry
- Consider using decorators or descriptors for complex validations
import functools
def validate_input(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
## Perform validation before executing the function
return func(*args, **kwargs)
return wrapper
By applying these practical validation techniques, developers can create robust and reliable Python applications with LabEx best practices in data validation and error handling.