Comparisons and sorting of a numeric class....

Andrew Robinson andrew3 at r3dsolutions.com
Tue Jan 6 05:27:22 EST 2015


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.

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'."

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?

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."

And I am seriously stumped....



















More information about the Python-list mailing list