๐ŸŽ“ A1Learner
๐Ÿ”

DSA Edge Cases and Testing

An edge case is an input at the boundary of what a problem allows. Edge cases break solutions that pass every ordinary input.

Empty and single inputs

An average divides by the length of its list. The empty list makes that division explode, while one score works fine.

def average(nums):
    return sum(nums) / len(nums)

try:
    print(average([]))
except ZeroDivisionError:
    print("empty list -> ZeroDivisionError")
print("one score ->", average([4]))

Duplicates fool a removal trick

The fragile helper removes the maximum once and trusts what remains. On three equal scores it reports 5, and it silently shrinks the caller's list.

def second_fragile(nums):
    top = max(nums)
    nums.remove(top)
    return max(nums)

scores = [5, 5, 5]
print("fragile second largest:", second_fragile(scores))
print("the caller's list is now:", scores)

Negatives beat a zero start

This best-sum helper starts its best total at zero. On two losing days it reports 0, a total no single day or pair ever reaches.

def best_sum_fragile(nums):
    best = 0
    current = 0
    for x in nums:
        current = max(x, current + x)
        best = max(best, current)
    return best

print("fragile best sum for [-3, -1]:", best_sum_fragile([-3, -1]))
print("the true best sum is -1, the least bad single day")

Example

def fragile(nums):
    biggest = max(nums)
    nums.remove(biggest)
    return max(nums)

def fixed(nums):
    distinct = sorted(set(nums))
    if len(distinct) < 2:
        return None
    return distinct[-2]

cases = [
    ("empty", [], None),
    ("single", [7], None),
    ("all equal", [5, 5, 5], None),
    ("duplicated top", [3, 9, 9, 4], 4),
    ("negatives", [-7, -3, -3], -7),
    ("already sorted", [1, 2, 3, 4], 3),
    ("huge", [10**30, 10**30 - 1, 5], 10**30 - 1),
]
for name, data, expected in cases:
    try:
        f = fragile(list(data))
        f_text = str(f)
        f_ok = f == expected
    except ValueError:
        f_text = "ValueError"
        f_ok = False
    g = fixed(data)
    print(name, "| fragile:", f_text, "| fixed:", g, "| expected:", expected,
          "| fragile", "PASS" if f_ok else "FAIL",
          "| fixed", "PASS" if g == expected else "FAIL")

Key points

  • An edge case is an input at the boundary of what a problem allows.
  • An empty input breaks code that reads a first element or divides by a length.
  • A single element breaks code that assumes a pair exists.
  • All equal values break code that expects a strict winner.
  • Duplicates break code that removes one copy and trusts the rest.
  • Negative values break code that starts its best answer at zero.
  • Already sorted input hides order bugs that shuffled data would expose.
  • Python integers never overflow, so huge values stay exact.

In this example, a gauntlet of trap inputs runs against one fragile solution and its fix. The fragile helper removes the largest value once and returns the new maximum. It crashes on the empty and single cases. It fails on all equal values, on a duplicated top value, and on negatives with a duplicated top. It passes only the already sorted case and the huge case. The fixed helper collects the distinct values and returns the second largest distinct value. It returns None when no second distinct value exists. Every fixed verdict in the table is a pass. The huge case uses values near 10^30, and Python keeps them exact because its integers never overflow.

Note

Run the whole checklist before calling a solution finished.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท Python Playground

Exercise

A best-sum solution returns 0 for the input [-3, -1]. What went wrong?