On Dec 28, 2019, at 23:29, Steve Barnes <gadgetst...@live.co.uk> wrote:
> 
> 
> From: Andrew Barnert <abarn...@yahoo.com> 
> Sent: 28 December 2019 20:21
> To: Steve Barnes <gadgetst...@live.co.uk>
> Cc: Christopher Barker <python...@gmail.com>; gu...@python.org; python-ideas 
> <python-ideas@python.org>
> Subject: Re: [Python-ideas] Re: Testing for NANs [was Re: Fix 
> statistics.median()?]
>  
> On Dec 28, 2019, at 00:03, Steve Barnes <gadgetst...@live.co.uk> wrote:
>  
> 
> Personally I still like the fundamental:
>  
> def is_nan(num):
>     “”” Test for NaN “””
>     return num != num
>  
> So simple!
>  
> This is only fundamental for types where all and only NaN values are not 
> self-equal. Is that guaranteed to be true for all number-like types? Would a 
> type that had numbers that weren’t self-equal, or non-numbers that were 
> self-equal, be so different that you wouldn’t want to count it as a 
> number-like type? What about values where the self-equal test raises (as it 
> does for Decimal with sNaN—and I don’t think you want a function named is_nan 
> to raise when passed a NaN value)? Or where it returns something that isn’t a 
> Boolean (as with arrays—for that matter, is a != a guaranteed to be the same 
> array as np.isnan(a)?)?
>  
> So this isn’t really a general test, it’s a test for int, float, and Decimal 
> but only if you ignore sNaN, and probably some number-like types, and 
> probably not some other number-like types. If you need a general nan test 
> that works for any type, I think you have to do something like the opt-in 
> method call idea.
>  
> Also, what’s the goal here? If we’re trying to detect all incomparable pairs 
> of values by checking if either one is NaN, that only works for float and 
> Decimal in the first place. It’s not even true for complex, much less all 
> possible number-like types. Of course lots of statistics makes no sense with 
> complex, but if the only reason we want a general is_nan is for statistics, 
> then it only has to be as general as the rest of the module, which explicitly 
> says it doesn’t support arbitrary number types, only a small set of them. So 
> we just need an isnan for that set of types, not a fully general one.
>  
> How about something along the lines of:
> def isnan(num):
>      """ Attempt at generic NaN check """
>      if hasattr(num, "is_nan"):  # Does it have its own method?
>          return num.is_nan()
>      else:
>          return num != num
> Then decimal would work nicely as would any potential types that are not 
> self-equal would just need to define their own method albeit with a 
> prescribed name. Of course it will return false for non-numeric types such as 
> strings.

No it won’t, unless you assume here that no possible non-numeric types could 
ever have non-self-equal values. Which isn’t true. (Unless you’re suggesting 
that every non-numeric type that might have any non-self-equal values has to 
add an is_nan that always returns False, even if the type has nothing to do 
with numbers, just to get around this rule?)

And what does this buy us? You fixed the problem with Decimal, but you’ve left 
in the part that does the right thing with some unspecified set of types that 
we may or may not ever need at the cost of doing the wrong thing with some 
other unspecified set of types that we may or may not ever need (as well as 
being less obvious/readable), so it still has the same root problem: it’s not 
“generic” in any useful sense.

How is this more useful than just falling back to math/cmath, or adding an 
is_nan method to float and complex? What types are you expecting to get a 
better result from this way, and what types do you think don’t matter even if 
they get a worse result?

Also, why should a function called is_nan return false for a string in the 
first place? If a string is not not a number, it’s a number, which isn’t right. 
Raising seems to make a lot more sense. Although, since I still don’t know why 
we need a fully generic isnan in the first place and where it’s going to be 
used, I can’t be sure it makes more sense in whatever context you’re imagining 
it being used in.


_______________________________________________
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/WVBMXMRXIXLEVMFUJOUM53LKUWPR4P4E/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to