(self)
| 2586 | self.assertEqual(q2, statistics.median(data)) |
| 2587 | |
| 2588 | def test_specific_cases_inclusive(self): |
| 2589 | # Match results computed by hand and cross-checked |
| 2590 | # against the PERCENTILE.INC function in MS Excel |
| 2591 | # and against the quantile() function in SciPy. |
| 2592 | quantiles = statistics.quantiles |
| 2593 | data = [100, 200, 400, 800] |
| 2594 | random.shuffle(data) |
| 2595 | for n, expected in [ |
| 2596 | (1, []), |
| 2597 | (2, [300.0]), |
| 2598 | (3, [200.0, 400.0]), |
| 2599 | (4, [175.0, 300.0, 500.0]), |
| 2600 | (5, [160.0, 240.0, 360.0, 560.0]), |
| 2601 | (6, [150.0, 200.0, 300.0, 400.0, 600.0]), |
| 2602 | (8, [137.5, 175, 225.0, 300.0, 375.0, 500.0,650.0]), |
| 2603 | (10, [130.0, 160.0, 190.0, 240.0, 300.0, 360.0, 440.0, 560.0, 680.0]), |
| 2604 | (12, [125.0, 150.0, 175.0, 200.0, 250.0, 300.0, 350.0, 400.0, |
| 2605 | 500.0, 600.0, 700.0]), |
| 2606 | (15, [120.0, 140.0, 160.0, 180.0, 200.0, 240.0, 280.0, 320.0, 360.0, |
| 2607 | 400.0, 480.0, 560.0, 640.0, 720.0]), |
| 2608 | ]: |
| 2609 | self.assertEqual(expected, quantiles(data, n=n, method="inclusive")) |
| 2610 | self.assertEqual(len(quantiles(data, n=n, method="inclusive")), n - 1) |
| 2611 | # Preserve datatype when possible |
| 2612 | for datatype in (float, Decimal, Fraction): |
| 2613 | result = quantiles(map(datatype, data), n=n, method="inclusive") |
| 2614 | self.assertTrue(all(type(x) == datatype) for x in result) |
| 2615 | self.assertEqual(result, list(map(datatype, expected))) |
| 2616 | # Invariant under translation and scaling |
| 2617 | def f(x): |
| 2618 | return 3.5 * x - 1234.675 |
| 2619 | exp = list(map(f, expected)) |
| 2620 | act = quantiles(map(f, data), n=n, method="inclusive") |
| 2621 | self.assertTrue(all(math.isclose(e, a) for e, a in zip(exp, act))) |
| 2622 | # Natural deciles |
| 2623 | self.assertEqual(quantiles([0, 100], n=10, method='inclusive'), |
| 2624 | [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0]) |
| 2625 | self.assertEqual(quantiles(range(0, 101), n=10, method='inclusive'), |
| 2626 | [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0]) |
| 2627 | # Whenever n is smaller than the number of data points, running |
| 2628 | # method='inclusive' should give the same result as method='exclusive' |
| 2629 | # after the two included extreme points are removed. |
| 2630 | data = [random.randrange(10_000) for i in range(501)] |
| 2631 | actual = quantiles(data, n=32, method='inclusive') |
| 2632 | data.remove(min(data)) |
| 2633 | data.remove(max(data)) |
| 2634 | expected = quantiles(data, n=32) |
| 2635 | self.assertEqual(expected, actual) |
| 2636 | # Q2 agrees with median() |
| 2637 | for k in range(2, 60): |
| 2638 | data = random.choices(range(100), k=k) |
| 2639 | q1, q2, q3 = quantiles(data, method='inclusive') |
| 2640 | self.assertEqual(q2, statistics.median(data)) |
| 2641 | # Base case with a single data point: When estimating quantiles from |
| 2642 | # a sample, we want to be able to add one sample point at a time, |
| 2643 | # getting increasingly better estimates. |
| 2644 | self.assertEqual(quantiles([10], n=4), [10.0, 10.0, 10.0]) |
| 2645 | self.assertEqual(quantiles([10], n=4, method='exclusive'), [10.0, 10.0, 10.0]) |
nothing calls this directly
no test coverage detected