Problem 596385 · medium · Level 05 Advanced Algorithms & Graphs

A Test That Catches Every Broken Median

py-testing · assert · edge cases · randomised testing · median

A statistics library accepts contributions, and each new median function must pass your test before it is merged. Write a test function test_median(median) that receives an implementation and checks it against this specification:

  • median(values) takes a list of numbers (ints or floats) and returns its median: the middle value of the sorted list for an odd length, and the mean of the two middle values (an ordinary / division) for an even length;
  • an empty list raises ValueError;
  • the caller's list is not changed.

Your function must return normally (the value does not matter) for a correct implementation, and raise an exception (normally an AssertionError from a failed assert) for an incorrect one.

The judge mutation_report(test_median, names) runs your test against the implementations named in names and returns, for each, whether your test flagged it (raised). Two are correct: "correct" and "correct_float" (which returns floats). All others are broken in one way each: "no_sort", "upper_middle", "lower_middle", "floor_mean", "sorts_input", "empty_none", "dedupe", "abs_order", "rounds", "pair_first" and "partial_sort". The names hint at the bug; finding a case that exposes it is your job. A perfect test gives False for the correct ones and True for every other.

Examples

Input:  mutation_report(test_median, ["correct", "no_sort", "upper_middle"])
Output: {"correct": False, "no_sort": True, "upper_middle": True}

Constraints

  • The judge builds new implementation objects for every report, so compare results, not identities.
  • Keep the test quick: at most a few thousand calls of median. Randomness must be seeded (for example random.Random(0)).

Goals

  • Write a test function with `assert` that a correct implementation passes
  • Choose edge cases that expose each typical mistake
  • Check side effects (the input list must not change) as well as results
Starting Python…