For built-in types, there are relational operators (
==, etc.) that compare values and determine when one is greater than, less than, or equal to another. For user-defined types, we can override the behavior of the built-in operators by providing a method named
__cmp__ takes two parameters,
other, and returns a positive number if the first object is greater, a negative number if the second object is greater, and 0 if they are equal to each other.
The correct ordering for cards is not obvious. For example, which is better, the 3 of Clubs or the 2 of Diamonds? One has a higher rank, but the other has a higher suit. In order to compare cards, you have to decide whether rank or suit is more important.
The answer might depend on what game you are playing, but to keep things simple, we’ll make the arbitrary choice that suit is more important, so all of the Spades outrank all of the Diamonds, and so on.
With that decided, we can write
# inside class Card: def __cmp__(self, other): # check the suits if self.suit > other.suit: return 1 if self.suit < other.suit: return -1 # suits are the same... check ranks if self.rank > other.rank: return 1 if self.rank < other.rank: return -1 # ranks are the same... it's a tie return 0
You can write this more concisely using tuple comparison:
# inside class Card: def __cmp__(self, other): t1 = self.suit, self.rank t2 = other.suit, other.rank return cmp(t1, t2)
The built-in function
cmp has the same interface as the method
__cmp__: it takes two values and returns a positive number if the first is larger, a negative number if the second is larger, and 0 if they are equal.
In Python 3,
cmp no longer exists, and the
__cmp__ method is not supported. Instead you should provide
__lt__, which returns
self is less than
other. You can implement
__lt__ using tuples and the
__cmp__ method for Time objects. Hint: you can use tuple comparison, but you also might consider using integer subtraction.