diff -r 8d0206f97439 Lib/statistics.py --- a/Lib/statistics.py Sun Nov 24 22:41:35 2013 -0800 +++ b/Lib/statistics.py Mon Nov 25 08:16:04 2013 +0100 @@ -91,6 +91,8 @@ A single exception is defined: StatisticsError is a subclass of ValueError. """ +# Please keep this module mostly compatible with Python 2.6. +from __future__ import division __all__ = [ 'StatisticsError', 'pstdev', 'pvariance', 'stdev', 'variance', @@ -99,8 +101,9 @@ ] -import collections -import math +from collections import Counter +from math import sqrt +from math import isfinite from fractions import Fraction from decimal import Decimal @@ -159,7 +162,7 @@ partials[d] = partials_get(d, 0) + n if None in partials: assert issubclass(T, (float, Decimal)) - assert not math.isfinite(partials[None]) + assert not isfinite(partials[None]) return T(partials[None]) total = Fraction() for d, n in sorted(partials.items()): @@ -202,7 +205,7 @@ if isinstance(x, Decimal): assert not x.is_finite() else: - assert not math.isfinite(x) + assert not isfinite(x) return (x, None) @@ -231,8 +234,8 @@ def _coerce_types(T1, T2): """Coerce types T1 and T2 to a common type. - >>> _coerce_types(int, float) - + >>> _coerce_types(int, float) is float + True Coercion is performed according to this table, where "N/A" means that a TypeError exception is raised. @@ -270,7 +273,7 @@ # Generate a table of sorted (value, frequency) pairs. if data is None: raise TypeError('None is not iterable') - table = collections.Counter(data).most_common() + table = Counter(data).most_common() if not table: return table # Extract the values with the highest frequency. @@ -287,8 +290,8 @@ def mean(data): """Return the sample arithmetic mean of data. - >>> mean([1, 2, 3, 4, 4]) - 2.8 + >>> mean([1, 2, 3, 4, 4]) == 2.8 + True >>> from fractions import Fraction as F >>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)]) @@ -377,8 +380,8 @@ def median_grouped(data, interval=1): """"Return the 50th percentile (median) of grouped continuous data. - >>> median_grouped([1, 2, 2, 3, 4, 4, 4, 4, 4, 5]) - 3.7 + >>> median_grouped([1, 2, 2, 3, 4, 4, 4, 4, 4, 5]) == 3.7 + True >>> median_grouped([52, 52, 53, 54]) 52.5 @@ -591,7 +594,7 @@ try: return var.sqrt() except AttributeError: - return math.sqrt(var) + return sqrt(var) def pstdev(data, mu=None): @@ -599,12 +602,12 @@ See ``pvariance`` for arguments and other details. - >>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) - 0.986893273527251 + >>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) == 0.986893273527251 + True """ var = pvariance(data, mu) try: return var.sqrt() except AttributeError: - return math.sqrt(var) + return sqrt(var) diff -r 8d0206f97439 Lib/test/test_statistics.py --- a/Lib/test/test_statistics.py Sun Nov 24 22:41:35 2013 -0800 +++ b/Lib/test/test_statistics.py Mon Nov 25 08:16:04 2013 +0100 @@ -2,6 +2,8 @@ approx_equal function. """ +# Please keep this module mostly compatible with Python 2.6. +from __future__ import division import collections import decimal @@ -271,9 +273,9 @@ # Test that approx_equal(a, b) == approx_equal(b, a) args = [-23, -2, 5, 107, 93568] delta = 2 - for x in args: + for a in args: for type_ in (int, float, Decimal, Fraction): - x = type_(x)*100 + x = type_(a)*100 y = x + delta r = abs(delta/max(x, y)) # There are five cases to check: @@ -400,7 +402,7 @@ # === Absolute error tests === def do_approx_equal_abs_test(self, x, delta): - template = "Test failure for x={!r}, y={!r}" + template = "Test failure for x={0!r}, y={1!r}" for y in (x + delta, x - delta): msg = template.format(x, y) self.assertTrue(approx_equal(x, y, tol=2*delta, rel=0), msg) @@ -441,7 +443,7 @@ # === Relative error tests === def do_approx_equal_rel_test(self, x, delta): - template = "Test failure for x={!r}, y={!r}" + template = "Test failure for x={0!r}, y={1!r}" for y in (x*(1+delta), x*(1-delta)): msg = template.format(x, y) self.assertTrue(approx_equal(x, y, tol=0, rel=2*delta), msg) @@ -773,9 +775,9 @@ # because it checks the numeric result by equality, but not by type. class MyFloat(float): def __truediv__(self, other): - return type(self)(super().__truediv__(other)) + return type(self)(super(MyFloat, self).__truediv__(other)) def __add__(self, other): - return type(self)(super().__add__(other)) + return type(self)(super(MyFloat, self).__add__(other)) __radd__ = __add__ raw = self.prepare_data() @@ -802,15 +804,15 @@ # result, not the value. class MyFloat(float): def __truediv__(self, other): - return type(self)(super().__truediv__(other)) + return type(self)(super(MyFloat, self).__truediv__(other)) def __sub__(self, other): - return type(self)(super().__sub__(other)) + return type(self)(super(MyFloat, self).__sub__(other)) def __rsub__(self, other): - return type(self)(super().__rsub__(other)) + return type(self)(super(MyFloat, self).__rsub__(other)) def __pow__(self, other): - return type(self)(super().__pow__(other)) + return type(self)(super(MyFloat, self).__pow__(other)) def __add__(self, other): - return type(self)(super().__add__(other)) + return type(self)(super(MyFloat, self).__add__(other)) __radd__ = __add__ data = self.prepare_data() @@ -1088,7 +1090,7 @@ def prepare_data(self): """Overload method from UnivariateCommonMixin.""" - data = super().prepare_data() + data = super(TestMedian, self).prepare_data() if len(data)%2 != 1: data.append(2) return data