I wanted to get a better understanding of OOP in Python and wrote a bit of code describing (infinite) ordinal arithmetic. I defined a class named Omega() with the usual comparison operators (==, <=, etc.), addition and multiplication.
I thought I'd check whether (as should be true) the first infinite ordinal added to itself was less-than-or-equal-to the first uncountable ordinal. Launching the interactive shell, here's what I found:
>>> a, b = Omega(), Omega(1)
>>> (a+a) <= b
False
>>> (a+a) <= b
True
>>> (a+a) <= b
False
The same expression produces different truth values.
I continued to test the expression and could not spot any pattern. If I re-interpret the code, I find that repeatedly testing the expression produces a different sequence of True/False values.
What could be causing this behaviour?
If it's relevant, I'm using CPython 2.7.5 on Windows 8.1.
Here's the Python code I ran: http://pastebin.com/XPqMphBw
I believe you overloaded the <= and >= operators incorrectly. Instead of:
def __leq__(self, other):
# ...
def __geq__(self, other):
use this instead:
def __le__(self, other):
# ...
def __ge__(self, other):
After making these changes and running this in Python 3.4.1, I get:
>>> a, b = Omega(), Omega(1)
>>> (a+a) <= b
True
>>> (a+a) <= b
True
>>> (a+a) <= b
True
Like @Padraic Cunningham, I also cannot replicate your problem (under Python 2.7.5 on Mac OS X). It gives me consistent answers.
You would do well to give your objects a comprehensible __repr__ method so that they are easily printed for debugging purposes. For example:
def __repr__(self):
innards = ", ".join(str(v) for v in [self.index, self.power, self.copies])
return "{0}({1})".format(self.__class__.__name__, innards)
Printing a would then show Omega(0, 1, 1). A slightly fancier version might be:
def __repr__(self):
innards = "index={index}, power={power}, copies={copies}".format(**self.__dict__)
return "{0}({1})".format(self.__class__.__name__, innards)
I also note that your code is probably not computing "less than or equal" the way you think it is. You have methods __leq__ and __geq__ defined, but those are not part of the Python data model. You want (and need) __le__ and __ge__ instead. If those are not defined, a combination of __eq__ and __lt__ are called instead. That combination generally has logical equivalency, if you're using a standard algebraic definition of <=, but in this case... It's at least a place to check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With