The happy path is not the test
Generated code is fitted to the example you gave it, so the example proves nothing. Learn the boundary catalogue and write a probe that separates correct candidates from plausible ones.
Why the example always passes
When you ask for a function and give an example, you have handed over the test. Whatever produced the code, human or model, optimized for that example. So the example passing tells you almost nothing, and the confident tone of the response tells you less.
Here is the shape you will see constantly. The task: "return the second largest distinct value in a list, or None if there is not one." The example: [3, 1, 4] should give 3.
def second_largest(nums):
ordered = sorted(set(nums))
return ordered[1] if len(ordered) >= 2 else None
Run the example. sorted(set([3, 1, 4])) is [1, 3, 4], and index 1 is 3. Correct. It even handles the empty list and the single-value list, which looks like careful work.
It is wrong. ordered[1] is the second smallest. With three distinct values the second smallest and the second largest are the same element, so the example cannot tell them apart. Feed it [1, 2, 3, 4] and it returns 2 where the answer is 3.
The boundary catalogue
Reviewing well is mostly recall. Keep a short list and walk it against the contract every time.
| Boundary | The input to try | What it catches |
|---|---|---|
| Empty | [], "", {} | indexing, division by length, max on nothing |
| One | [x] | anything that compares neighbours or takes a pair |
| Two versus many | [a, b] versus [a, b, c, d] | index confusion that a short example hides |
| Duplicates | [5, 5] | uniqueness assumptions, tie-breaking |
| All equal | [3, 3, 3] | ranges, spreads, second-place logic |
| Zero | 0 in the data | division, truthiness, seeded accumulators |
| Negative | -4 | accumulators seeded at 0, absolute values, clamps |
| Missing | None in the data | arithmetic and comparison against None |
| Order | already sorted, reverse sorted | code that assumes it can stop early |
Nothing on that list is clever. It is a checklist, and a checklist is what makes the review repeatable when you are tired.
You are reviewing a function that returns the largest gap between consecutive elements of a sorted list of prices. Sort each input by whether it is the happy path or a real boundary for this contract.
Turning the catalogue into a probe
Reading a boundary list is one thing. The skill that gets you hired is turning it into code that answers a yes or no question about someone else's function.
A probe is a function that takes a candidate implementation and returns whether it is correct, by calling it on inputs you chose. It is a test, written from the outside, with no view of the body.
def is_correct(fn):
cases = [
([3, 1, 4], 3), # the happy path, so a broken probe is obvious
([1, 2, 3, 4], 3), # four distinct values: catches the index confusion
([7, 7], None), # duplicates collapse to one distinct value
([], None), # empty
([9], None), # single
]
for nums, expected in cases:
if fn(list(nums)) != expected:
return False
return True
Three details in there are worth stealing.
First, fn(list(nums)) passes a copy. If the candidate sorts its argument in place, the original case data is corrupted for every later assertion and your probe starts lying.
Second, every case is a pair of input and expected value, so the probe reads as a specification rather than a pile of calls.
Third, the happy path is still in the list. It is not there to catch anything. It is there so that a probe which is itself broken fails loudly on the easy case instead of silently rejecting everything.
The probe has to be able to fail
The last rule is the one people skip. Before you trust a probe, run it against an implementation you know is broken and confirm it says no. A probe that returns True for everything is worse than no probe, because it converts an unknown into a false reassurance.
That is exactly how the exercises below are graded: your probe is run against correct candidates and against broken ones, so a probe that always agrees fails immediately.
Interview nuance: "how would you test this?" is now a more common interview question than "how would you write this?", and the answer that lands is not a list of frameworks. It is naming two concrete inputs that distinguish a correct implementation from a plausible one, and saying what each is for. That is a thirty second answer and almost nobody gives it.
def second_largest(nums):
ordered = sorted(set(nums))
return ordered[1] if len(ordered) >= 2 else None
# The example from the ticket, and the input that separates the readings.
print(second_largest([3, 1, 4])) # 3, looks right
print(second_largest([1, 2, 3, 4])) # 2, and the answer is 3Apply
Your turn
The task this lesson builds to.
Write a function check(name) that returns True only when the candidate implementation
stored under name is a correct second_largest, and False otherwise.
The contract: second_largest(nums) returns the second largest distinct value in nums, or
None when nums has fewer than two distinct values.
The starter holds four candidates in the CANDIDATES dictionary. Look up the function with
CANDIDATES[name], call it on inputs you choose, and decide. Two of the four are correct. Your
answer is graded by running it against correct candidates and broken ones, so return True fails.
Keep check as the last function in the file.
3 hints and 4 automated checks are waiting in the workspace.
Practice
Make it stick
A second problem on the same idea, so it survives past today.
A marketplace shows a rating summary under every listing. An assistant produced the
summarize_ratings function in the starter, it matched the screenshot in the ticket, and it
shipped. Overnight, every listing with no reviews yet started returning a 500.
Repair summarize_ratings so it satisfies its contract on the inputs the happy-path example
never covered.
The contract: scores is a list where a customer who left a review has an integer rating and a
customer who did not is recorded as None. Return a dictionary with "count" (how many real
ratings there are), "average" (their mean, rounded to one decimal place), and "top" (the
highest real rating). When there is no real rating at all, return
{"count": 0, "average": 0.0, "top": None}.
3 hints and 4 automated checks are waiting in the workspace.