New submission from Wolfgang Maier: Can this still be fixed in 3.4 ??
I came across this bug in the statistics module today: >>> import statistics >>> data = [Decimal('1e4')] >>> statistics.mean(data) Traceback (most recent call last): File "<pyshell#465>", line 1, in <module> statistics.mean(data) File "C:/Python33\statistics.py", line 316, in mean return _sum(data)/n File "C:/Python33\statistics.py", line 167, in _sum total += Fraction(n, d) File "C:\Python33\lib\fractions.py", line 163, in __new__ raise TypeError("both arguments should be " TypeError: both arguments should be Rational instances The reason for this is that the statistics module converts Decimals to exact ratios internally like this: def _decimal_to_ratio(d): """Convert Decimal d to exact integer ratio (numerator, denominator). >>> from decimal import Decimal >>> _decimal_to_ratio(Decimal("2.6")) (26, 10) """ sign, digits, exp = d.as_tuple() if exp in ('F', 'n', 'N'): # INF, NAN, sNAN assert not d.is_finite() raise ValueError num = 0 for digit in digits: num = num*10 + digit if sign: num = -num den = 10**-exp #if type(den) != int: # print (d, sign, digits, exp, num, den) return (num, den) The important part here is the line: den = 10**-exp which makes den an int if - and **only** if - exp is negative. However, the exponent in the namedtuple returned by Decimal.as_tuple() is not guaranteed to be negative and in fact: >>>Decimal('1e4').as_tuple() DecimalTuple(sign=0, digits=(1,), exponent=4) With this den in the above function becomes a float, which raises an error subsequently in _sum, when it essentially tries to do: Fraction(num, den) IMPORTANT: I have been running this example on my laptop with Python3.3.0 and the statistics module imported from sys.path. Thus, I cannot exclude that the decimal module has changed since 3.3.0 and is now always returning a negative exponent with .as_tuple(). I'm abroad and cannot verify this against the Python3.4dev build. Could somebody confirm this for 3.4 and reject this issue immediately if the error doesn't occur ? If this is not version dependent though, then there is a very simple bug-fix for it, which I suggest should still be incorporated into 3.4: if exp >= 0: return int(x), 1 inserted right after the raise ValueError line is doing the job. I cannot generate the diff for this myself, so could somebody do this. Thanks a lot for your efforts! ---------- messages: 210613 nosy: oscarbenjamin, python-dev, skrah, stevenjd, wolma priority: normal severity: normal status: open title: Decimal handling error in statistics module type: behavior versions: Python 3.4 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue20561> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com