| 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
values
():
size (tallies):
y, n = tallies[size][], tallies[size][]
ratio = ( n == (((y)/n)))
()
():
(known([word])
known(edits1(word))
known(edits2(word))
[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