On 01/06/2015 05:27 AM, Andrew Robinson wrote:
Hi,
I'm building a custom numeric class that works with values that have
uncertainty and am wanting to make it as compatible with floating point
objects as possible -- so as to be usable in legacy code with minimal
rewites; but but I am having trouble understanding how to handle
magnitude comparison return values for __lt__ __gt__ etc.

The problem with magnitude comparisons in my class is that the
comparison may fail to be True for various reasons, and in various ways,
but it's important for programming to retain the general reason a
comparison wasn't strictly 'True'.

For example, to 1 significant figure, I can write two values
a=mynum(0.1) and b=mynum(0.01) ; as written both of them have an
uncertainty of 1 least significant figure, so it is possible both values
are really a 0.   But, there is a bias/mean/average which suggests that
more often than not -- 0.1 will be bigger than 0.01. So, what is the
proper response of a>b ?,  the answer is that a>b depends on the context
of how the values were obtained and what is being done with them,
although strictly speaking 'a' is not greater than 'b' in this case,
although 'a' has a much better chance of being greater than 'b' on
average which may be important for the user to know.

Where I'm getting stuck is how to encode the return values of the
comparison operators to be compatible with python floating point object
return values (and python's sort algorithms for lists of floats) but
still give extra functionality that is needed for uncertainty ... and as
I'm writing in python 2.xx but with an eye toward python 3 in the
future, I've become concerned that __cmp__ has been discontinued so that
I need to write this using only __gt__() and friends.  I don't know how
to do it.

What I would like is for operators like '>' to return a boolean True or
False equivalent, which also encodes the reason for failure in one of
five ways:

True:          Sufficient information and confidence exists that the
comparison is thoroughly True.
PartTrue:    The comparison is uncertain for any single sample, but True
is at least minimally more probable.
Unbiased:  The comparison is uncertain for any single sample.
PartFalse:   The comparison is uncertain for any single sample, but
False is at least minimally more probable.
False:         Sufficient information and confidence exists that the
comparison is thoroughly False.


Just a few comments, not a thorough examination. And I don't have time to actually try it today.

1) to subclass built-in types, you frequently have to implement your own constructor. You probably tried it by only implementing the initializer. The constructor has the name __new__

and you probably should read:
    http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

2) to be sortable, your comparison mechanism needs to be stable. (I think that's the word). Anyway, if a < b and b < c, then a must be < c. It's not clear that you can accomplish that with the approach you're describing. But if you modify your definition for values near zero, it may be possible.

3) Your user will have to be aware that she's not using regular float values. Sooner or later some functions will have to be used differently. But you should still be able to mostly preserve the illusion.

4) When you convert to Python version 3.x, you'll have to re-study all these issues. It may be to your advantage to do both versions at once, or to just support version 3.x


By default, only True would evaluate in conditional statement as a
logical True.  All other values would be equivalent to False, but
hopefully, a programmer could find out which 'False' was returned by
some kind of object inspection or operator, like:

if (a>b) is PartTrue:     print "I don't really know if 'a' really is
greater than 'b'. but it might be"
if (a>b) > Unbiased:   print "a sorts after b because it's at least more
probable that a>b than not."
if (a>b):  print "this message will not print if the value 'b' might
occasionally be less than or equal to 'a'."


Those should all be possible.

For sorting, it would be ideal if the sorting algorithms min(), max(),
etc. could automatically recognize that:
False < PartFalse < Unknown < PartTrue < True.

But, even if that can't be done -- if there were a way, or method I
could add to my classes, which would intercept sort functions and
replace an absolute certain compare function with a merely Unbiased
detecting one; sort functions would all operate properly.

However, I'm not sure how to create these return values nor do I know
how to get the sort() functions to use them.

I've tried subclassing float() to see if I could actually make a
subclass that inherited all that float has, and be able to add extra
methods for my own use -- but Python doesn't seem to allow subclassing
float.  I either am not doing it right, or it can't be done.

So, I'm not sure I can subclass boolean either because that too is a
built in class ...  but I'm not sure how else to make an object that
acts as boolean False, but can be differentiated from false by the 'is'
operator.  It's frustrating -- what good is subclassing, if one cant
subclass all the base classes the language has?

As I said above, make sure you have a constructor. If you still get an error, post a message that shows exactly what you did, and what exception you saw.


What other approaches can I take?

'False' is a singleton, so I was pretty sure this wouldn't work -- but I
tried it...
PartTrue = False
if (1>2) is PartTrue: print "This is an obvious failure...  False is not
the object PartTrue."

You misunderstand the term singleton in this context.  When you execute
   PartTrue = False

you are just rebinding PartTrue to the object called False. There's still only one object.



--
DaveA
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to