Reputation: 177048
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
Upvotes: 3
Views: 695
Reputation: 22483
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.
Upvotes: 1
Reputation: 1733
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
Upvotes: 6