opps, forgot to include my test code -- could be handy:
On Fri, Dec 27, 2019 at 11:52 PM Christopher Barker <python...@gmail.com> wrote: > On Fri, Dec 27, 2019 at 5:39 PM Guido van Rossum <gu...@python.org> wrote: > >> Is duck typing float or Decimal worth the bother? Barring that it could >> be done with some isinstance() checks (in the user code, not in >> math.isnan()). >> > > well, for the topic at hand in another thread -- in the statistics module. > And I was coming to the same conclusion, but it dawned on me that another > option would be to add a .is_nan() method to floats. (same as Decimal). It > would be a lighter-weight option that a new dunder, but accomplish a > similar effect -- anyone implementing a new numeric type that support NaN > could add that method. > > BTW, could you simply do: > > def is_nan(num): > try: > return num.is_nan() > except AttributeError: > if isinstance(num, complex): > return cmath.isnan(num) > try: > return math.isnan(num) > except: > return False > > I don't like the bare except, but it may be OK to say that anything that > can't be coerced to a float is not a NaN. (na you could trap the exeptions > we expect anyway) > > And this doesn't require you to import the Decimal module, and you can > document that it will work with any type that either has an is_nan() > method, or can have its NaN values successfully coerced into a float. > > And we could remove the complex support -- does the rest of the statistics > module support it anyway? But it did make me think -- what if the complex > number __float__() would work for NaN, and Inf, and -inf -- then you could > have a single isnan() implementation in the math module, > > (in fact, that could be a standard part of the __float__ protocol) > > > By the way: > > ----> 1 float(Decimal('snan')) > ValueError: cannot convert signaling NaN to float > > Why can't it convert a signaling NaN to a float? Isn't a signaling NaN > part of the IEE 754 spec? > > -CHB > > -- > Christopher Barker, PhD > > Python Language Consulting > - Teaching > - Scientific Software Development > - Desktop GUI and Web Development > - wxPython, numpy, scipy, Cython > -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
""" some tests of an is_nan function """ import math import cmath from decimal import Decimal from fractions import Fraction import numpy as np import pytest def is_nan(num): try: return num.is_nan() except AttributeError: if isinstance(num, complex): return cmath.isnan(num) try: return math.isnan(num) except: return False nan_vals = [Decimal('nan'), Decimal('snan'), float('nan'), np.nan, np.array(np.nan, dtype=np.float128), complex(float('nan'), 1), complex(0, float('nan')), complex(float('nan'), float('nan')), ] non_nan_vals = [34, 10**1000, # an int too big for a float 3.4, np.array(1e200, dtype=np.float128) * 1e200, # a numpy float128 too big for a float Decimal('1e500'), Fraction(1,10), Fraction(1,1000000)**100, # fraction too small for a float Fraction(10,1) ** 500, # fraction too large for a float complex(1, 2), complex(-123, 154), ] @pytest.mark.parametrize("num", nan_vals) def test_nan(num): assert is_nan(num) @pytest.mark.parametrize("num", non_nan_vals) def test_not_nan(num): assert not is_nan(num)
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OVJI5F7DCBYTJF3334YKF7FRQXI7HVF6/ Code of Conduct: http://python.org/psf/codeofconduct/