Operator Overload - Columbia College

Download Report

Transcript Operator Overload - Columbia College

Mathematical operators overload
• Fractions, also known as rational numbers, are values
that can be expressed as a ratio of whole numbers, such
as 5/6. The top number is called the numerator and the
bottom number is called the denominator.
• We define a Fraction class with an initialization method
that provides the numerator and denominator as
integers
• class Fraction:
def __init__(self, numerator, denominator=1):
self.numerator = numerator
self.denominator = denominator
• The denominator is optional. A Fraction with just one just
one parameter represents a whole number. If the numerator
is n, we build the Fraction n=1
__str__
• the print command invokes the __str__ method
implicitly
• write a __str__ method that displays fractions in a way
that makes sense.
def __str__(self):
return "%d/%d" % (self.numerator, self.denominator)
• To test what we have so far, we put it in a file named
Fraction.py and importit into the Python interpreter.
Then we create a fraction object and print it.
• >>> from Fraction import Fraction
• >>> spam = Fraction(5,6)
• >>> print "The fraction is", spam
__mul__ & __rmul__
• __mul__ is the name Python uses for a
method that overloads the * operator
(multiplication)
• class Fraction:
...
def __mul__(self, object):
return Fraction(self.numerator*object.numerator,
self.denominator*object.denominator)
• >>> print Fraction(5,6) * Fraction(3,4)
__mul__ & __rmul__
• We can extend the method to handle multiplication by an integer. We use the type function
to test if other is an integer and convert it to a
fraction if it is.
def __mul__(self, object):
if type(object)==type(5):
object =Fraction(object)
return Fraction(self.numerator*object.numerator, self.denominator*object.denominator)
>>> print Fraction(5,6)*4
20/6
>>> print 4*Fraction(5,6)
Error
__mul__ & __rmul__
• To evaluate a binary operator like multiplication, Python
checks the left operand first to see if it provides a __mul__
that supports the type of the second operand. In this case,
the built-in integer operator doesn't support fractions.
• Next, Python checks the right operand to see if it provides
an __rmul__ method that supports the first type. In this
case, we haven't provided __rmul__ , so it fails.
• On the other hand, there is a simple way to provide rmul :
• class Fraction:
• ...
• __rmul__ = __mul__
• This assignment says that the rmul is the same as mul .
• >>> print 5 * Fraction(3,4)
15/4
__add__ & __radd__
• The sum of a/b and c/d is the fraction
(a*d+c*b)/b*d
def __add__(self, other):
if type(other) == type(5):
other = Fraction(other)
return Fraction(self.numerator * other.denominator +
self.denominator * other.numerator,
self.denominator * other.denominator)
__radd__ = __add__
__cmp__
• By convention, the __cmp__ method returns a
negative number if self is less than other, zero if
they are the same, and a positive number if self is
greater than other.
• The simplest way to compare fractions is to crossmultiply. If a/b > c/d, then ad > bc. With that in
mind, here is the code for cmp :
def __cmp__(self, other):
diff = (self.numerator * other.denominator - other.numerator *
self.denominator)
return diff
__cmp__ in your assignment
in order to check whether two cards are match so that we can
remove the match, we change the __cmp__ method:
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
__cmp__ in your assignment
originalCards =self.cards[:]
for eachcard in originalCards:
match = Card(3-eachcard.suit, eachcard.rank)
if match in self.cards:
self.cards.remove(eachcard)
self.cards.remove(match)
__sub __ & __div__
• One way to handle those operations is to
implement negation by overriding __neg__
and inversion by overriding __invert__ . Then
we can subtract by negating the second
operand and adding, and we can divide by
inverting the second operand and multiplying.