Practical Troubleshooting
Real-World Debugging Scenarios
graph TD
A[Practical Troubleshooting] --> B[Performance Issues]
A --> C[Memory Leaks]
A --> D[Unexpected Behavior]
A --> E[Complex Data Processing]
Identifying Bottlenecks
import time
import cProfile
def slow_function(data):
start_time = time.time()
result = []
for item in data:
## Simulate complex processing
processed_item = complex_processing(item)
result.append(processed_item)
end_time = time.time()
print(f"Execution time: {end_time - start_time} seconds")
return result
def complex_processing(item):
## Simulate computational complexity
return sum([x * item for x in range(1000)])
## Profile the function
cProfile.run('slow_function([1, 2, 3, 4, 5])')
Memory Management Debugging
Memory Leak Detection
import sys
import gc
def check_memory_usage():
## Track object references
objects_before = len(gc.get_objects())
## Simulate memory-intensive operation
large_list = [list(range(10000)) for _ in range(1000)]
## Check memory growth
objects_after = len(gc.get_objects())
memory_diff = objects_after - objects_before
print(f"Objects created: {memory_diff}")
## Force garbage collection
gc.collect()
Error Handling Strategies
Error Type |
Handling Approach |
Example |
Value Error |
Input Validation |
Check numeric ranges |
Type Error |
Type Checking |
Ensure correct data types |
Runtime Error |
Exception Handling |
Use try-except blocks |
Advanced Troubleshooting Techniques
Decorators for Debugging
def debug_decorator(func):
def wrapper(*args, **kwargs):
try:
print(f"Calling {func.__name__}")
print(f"Arguments: {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"Result: {result}")
return result
except Exception as e:
print(f"Error in {func.__name__}: {e}")
raise
return wrapper
@debug_decorator
def risky_calculation(x, y):
return x / y
Logging and Monitoring
import logging
import traceback
## Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s: %(message)s',
filename='/var/log/python_debug.log'
)
def robust_function(data):
try:
## Complex processing logic
processed_data = process_complex_data(data)
logging.info(f"Successfully processed {len(processed_data)} items")
return processed_data
except Exception as e:
logging.error(f"Error processing data: {e}")
logging.error(traceback.format_exc())
raise
Debugging Checklist
- Reproduce the issue consistently
- Isolate the problem
- Use logging and profiling
- Check memory usage
- Implement robust error handling
- Use LabEx debugging tools
Common Troubleshooting Patterns
- Break complex problems into smaller parts
- Use incremental testing
- Document debugging steps
- Learn from error patterns
By mastering these practical troubleshooting techniques, developers can effectively diagnose and resolve complex Python programming challenges.