| name | handle-edge-cases |
| description | For boundary conditions: empty collections, zero values, recursive base cases, null checks, prevent crashes at edges. |
handle-edge-cases
When to Use
- Loop boundaries
- Empty collections
- Recursive base cases
- Division or modulo operations
- Array/string indexing
When NOT to Use
- Already validated at boundary
- Edge case can't happen
- Over-defensive code
The Pattern
Explicitly check boundary conditions before operations.
def process(items):
if not items:
return default_value
if len(items) == 1:
return items[0]
return combine(items[0], process(items[1:]))
def divide(a, b):
if b == 0:
return None
return a / b
Example (from pytudes)
def eliminate(values, s, d):
"""Eliminate d from values[s]; propagate."""
if d not in values[s]:
return values
values[s] = values[s].replace(d, '')
if len(values[s]) == 0:
return False
if len(values[s]) == 1:
d2 = values[s]
if not all(eliminate(values, s2, d2) for s2 in peers[s]):
return False
for u in units[s]:
dplaces = [s for s in u if d in values[s]]
if len(dplaces) == 0:
return False
if len(dplaces) == 1:
if not assign(values, dplaces[0], d):
return False
return values
def show(tallies, label):
for size in sorted(tallies):
y, n = tallies[size][True], tallies[size][False]
ratio = ('inft' if n == 0 else int(round(float(y)/n)))
print(f'{size:4d} |{y:7,d} |{n:7,d} | {ratio:4}:1')
def candidates(word):
"""Generate possible spelling corrections for word."""
return (known([word]) or
known(edits1(word)) or
known(edits2(word)) or
[word])
Key Principles
- Check before access: Empty list before
list[0]
- Return early: Handle edge cases first, then main logic
- Zero checks: Before division, modulo
- Fallback values:
or default pattern
- Explicit is clear:
if not items: shows intent