Utility Functions¶
The Utils module provides essential helper functions and utilities used throughout the project. These functions are designed to work seamlessly with the BaseExample class and are extensively used by the Calculator module.
Overview¶
This module contains standalone utility functions that provide common functionality like input validation, number formatting, and data processing. All functions are designed to be stateless and can be used independently or in combination with other modules.
Function Categories¶
Input Validation¶
Function | Purpose | Used By |
---|---|---|
validate_input(value) |
Validates and converts input data | Calculator, BaseExample |
check_type(value, expected_type) |
Type validation | All modules |
sanitize_string(text) |
String cleaning and validation | Input processing |
Data Formatting¶
Function | Purpose | Used By |
---|---|---|
format_number(number, precision=2) |
Number formatting with precision | Calculator output |
format_currency(amount) |
Currency formatting | Financial calculations |
format_percentage(ratio) |
Percentage display | Statistical operations |
Data Processing¶
Function | Purpose | Used By |
---|---|---|
process_list(items) |
List processing utilities | Batch operations |
merge_dicts(dict1, dict2) |
Dictionary merging | Configuration management |
deep_copy(obj) |
Safe object copying | Data manipulation |
Usage Examples¶
Basic Validation¶
from src.example.utils import validate_input, format_number
from src.example.calculator import Calculator
# Validate and format user input
user_input = "42.5"
validated_number = validate_input(user_input)
formatted_output = format_number(validated_number, precision=3)
# Use with Calculator
calc = Calculator()
result = calc.add(validated_number, 10)
print(format_number(result))
Advanced Processing¶
from src.example.utils import process_list, merge_dicts
from src.example.base import BaseExample
# Process multiple values
numbers = ["1", "2", "3.14", "42"]
validated_numbers = process_list(numbers, validator=validate_input)
# Merge configurations
base_config = BaseExample.default_config()
custom_config = {"precision": 4, "strict_mode": True}
final_config = merge_dicts(base_config, custom_config)
Configuration¶
The utils module supports configuration for default behaviors:
# Global configuration
UTILS_CONFIG = {
'default_precision': 2,
'strict_validation': True,
'error_on_invalid': False,
'locale_formatting': 'en_US'
}
Configuration Options¶
Option | Type | Default | Description |
---|---|---|---|
default_precision |
int |
2 |
Default decimal places for number formatting |
strict_validation |
bool |
True |
Enable strict input validation |
error_on_invalid |
bool |
False |
Raise errors on invalid input vs. returning None |
locale_formatting |
str |
'en_US' |
Locale for number/currency formatting |
Error Handling¶
The utils module implements consistent error handling patterns:
Exception Types¶
ValidationError
- Input validation failuresFormattingError
- Output formatting issuesProcessingError
- Data processing problems
Error Handling Patterns¶
from src.example.utils import validate_input, ValidationError
try:
result = validate_input(user_data)
except ValidationError as e:
logger.warning(f"Invalid input: {e}")
# Handle gracefully or use default
result = default_value
Integration Patterns¶
With BaseExample¶
class CustomExample(BaseExample):
def process(self, data):
# Use utils for validation
validated_data = validate_input(data)
# Process using base methods
result = super().process(validated_data)
# Format output using utils
return format_number(result)
With Calculator¶
calc = Calculator()
# All calculator operations use utils internally
def safe_calculate(operation, a, b):
"""Safe calculation with validation and formatting."""
# Validation happens inside calculator methods
result = getattr(calc, operation)(a, b)
# Format using utils
return format_number(result, precision=4)
Performance Considerations¶
- Caching: Validation functions use internal caching for repeated inputs
- Lazy Loading: Configuration loaded only when needed
- Memory Efficient: Functions designed to minimize memory usage
- Thread Safe: All utility functions are thread-safe
Testing Utilities¶
The utils module includes testing helpers:
from src.example.utils import UtilsTestCase
class TestMyUtilsUsage(UtilsTestCase):
def test_validation_pipeline(self):
"""Test complete validation and formatting pipeline."""
# Use inherited utilities
self.assert_valid_input("42")
self.assert_formatted_output(42.0, "42.00")
Migration and Compatibility¶
When upgrading utils functions:
- Backward Compatibility: All functions maintain backward compatibility
- Deprecation Warnings: Old patterns show deprecation warnings
- Migration Guides: Available in upgrade documentation
Best Practices¶
Function Usage¶
- Always Validate: Use
validate_input()
for all user input - Consistent Formatting: Use
format_number()
for all numeric output - Error Handling: Always handle
ValidationError
andFormattingError
- Type Checking: Use
check_type()
for runtime type validation
Performance Tips¶
- Batch Processing: Use
process_list()
for multiple items - Configuration Caching: Cache configuration objects when possible
- Avoid Repeated Validation: Cache validated inputs when reused
Examples and Tutorials¶
For detailed examples:
- Calculator Integration - Using utils with Calculator
- Base Class Patterns - Utils in base classes
- Code Samples - Practical usage examples
- Best Practices - Recommended patterns
Related Documentation¶
- API Overview - Complete API documentation
- Calculator Module - Primary consumer of utils
- Base Classes - Foundation classes using utils
- Configuration Guide - Setup and configuration
API Reference¶
Utility functions for the example package.
This module contains helper functions and decorators that can be used throughout the application.
Classes¶
DateFormatter
¶
Format dates in various formats.
This class provides methods to format datetime objects into different string representations.
Attributes:
Name | Type | Description |
---|---|---|
default_format |
Default format string for dates |
Example
Initialize formatter with default format.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
default_format
|
str
|
Default strftime format string |
'%Y-%m-%d %H:%M:%S'
|
Source code in src/example/utils.py
Functions¶
format
¶
Format a datetime object.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
date
|
datetime
|
The datetime to format |
required |
format_string
|
Optional[str]
|
Optional format string (uses default if None) |
None
|
Returns:
Type | Description |
---|---|
str
|
Formatted date string |
Example
formatter = DateFormatter() date = datetime(2024, 1, 15, 14, 30, 45) formatter.format(date) '2024-01-15 14:30:45'
Source code in src/example/utils.py
parse_iso
staticmethod
¶
Parse ISO format date string.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
date_string
|
str
|
ISO format date string |
required |
Returns:
Type | Description |
---|---|
datetime
|
Parsed datetime object |
Raises:
Type | Description |
---|---|
ValueError
|
If date string is invalid |
Example
DateFormatter.parse_iso("2024-01-15T14:30:45") datetime.datetime(2024, 1, 15, 14, 30, 45)
Source code in src/example/utils.py
relative_time
¶
Get relative time string (e.g., "2 hours ago").
Parameters:
Name | Type | Description | Default |
---|---|---|---|
date
|
datetime
|
The datetime to compare against now |
required |
Returns:
Type | Description |
---|---|
str
|
Human-readable relative time string |
Example
formatter = DateFormatter() past = datetime.now() - timedelta(hours=2) formatter.relative_time(past) '2 hours ago'
Source code in src/example/utils.py
Functions¶
format_number
¶
format_number(number: Union[int, float], decimals: int = 2, thousands_separator: bool = True) -> str
Format a number for display.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
number
|
Union[int, float]
|
The number to format |
required |
decimals
|
int
|
Number of decimal places (default: 2) |
2
|
thousands_separator
|
bool
|
Whether to use thousands separator (default: True) |
True
|
Returns:
Type | Description |
---|---|
str
|
Formatted number as string |
Example
format_number(1234567.89) '1,234,567.89' format_number(1234567.89, decimals=0) '1,234,568' format_number(1234.5, thousands_separator=False) '1234.50'
See Also
- :func:
validate_input
: Validate numeric input locale.format_string
: For locale-specific formatting
Source code in src/example/utils.py
timer
¶
Decorator to measure function execution time.
This decorator wraps a function and prints the time taken to execute it.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func
|
F
|
The function to time |
required |
Returns:
Type | Description |
---|---|
F
|
Wrapped function that prints execution time |
Example
Note
The timing includes all operations within the function, including any I/O operations.
Source code in src/example/utils.py
validate_input
¶
validate_input(value: Any, expected_type: type, min_value: Optional[Union[int, float]] = None, max_value: Optional[Union[int, float]] = None, allow_none: bool = False) -> bool
Validate input value against constraints.
This function checks if a value meets specified type and range constraints.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value
|
Any
|
The value to validate |
required |
expected_type
|
type
|
Expected type of the value |
required |
min_value
|
Optional[Union[int, float]]
|
Minimum allowed value (for numeric types) |
None
|
max_value
|
Optional[Union[int, float]]
|
Maximum allowed value (for numeric types) |
None
|
allow_none
|
bool
|
Whether None is a valid value |
False
|
Returns:
Type | Description |
---|---|
bool
|
True if value is valid, False otherwise |
Example
validate_input(42, int, min_value=0, max_value=100) True validate_input(-5, int, min_value=0) False validate_input(None, str, allow_none=True) True
Warning
This function only performs basic validation. For complex
validation logic, consider using a dedicated validation library
like pydantic
or cerberus
.