Complex code isn’t just hard to read—it’s statistically more likely to contain bugs.Research shows that functions with complexity above 10 have significantly higher defect rates. At 20+, the function is nearly impossible to test exhaustively.
Complexity 1-10
Low riskEasy to understand, test, and maintain
Complexity 11-20
Moderate riskConsider refactoring when touching this code
def process_order(order): if not order.valid: return None if order.priority == 'high': if order.value > 1000: apply_discount(order) notify_manager(order) elif order.priority == 'medium': queue_order(order) for item in order.items: if item.backordered: handle_backorder(item) elif item.fragile: mark_fragile(item) return order
# Before: Complexity 8def process_order(order): if not order.valid: return None # ... 50 more lines of nested logic# After: Complexity 3 eachdef process_order(order): if not order.valid: return None handle_priority(order) process_items(order) return orderdef handle_priority(order): # Isolated complexity passdef process_items(order): # Isolated complexity pass
Copy
# Before: Nested conditionalsdef validate(data): if data: if data.user: if data.user.active: return process(data) return None# After: Guard clausesdef validate(data): if not data: return None if not data.user: return None if not data.user.active: return None return process(data)
Deep nesting forces readers to hold multiple conditions in working memory simultaneously.
Copy
# Depth 5 - Very hard to followdef bad_example(): ## first if condition1: ## second for item in items: ## third if condition2: ## forth try: ## fifth (RIP) if condition3: process(item) except: pass
# Before: Depth 4def process_users(users): for user in users: if user.active: if user.verified: if user.has_permission: do_something(user)# After: Depth 1 (using continue)def process_users(users): for user in users: if not user.active: continue if not user.verified: continue if not user.has_permission: continue do_something(user)
# Bug: list is shared across all callsdef append_to(item, target=[]): target.append(item) return target>>> append_to(1)[1]>>> append_to(2)[1, 2] # Unexpected! Same list.
Copy
# Fixeddef append_to(item, target=None): if target is None: target = [] target.append(item) return target