fractions.py revision d058cd2cc8e2a3f61609b92a8fc821ea8ec524ca
1d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin# Originally contributed by Sjoerd Mullender.
2d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
4d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin"""Rational, infinite-precision, real numbers."""
5d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
6d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinfrom __future__ import division
7d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinimport math
8d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinimport numbers
9d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinimport operator
1045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskinimport re
11d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
12d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson__all__ = ["Fraction"]
13d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
14d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark DickinsonRational = numbers.Rational
15d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
16d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
173e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskindef gcd(a, b):
183e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin    """Calculate the Greatest Common Divisor of a and b.
19d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
20d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    Unless b==0, the result will have the same sign as b (so that when
21d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    b is divided by it, the result comes out positive).
22d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    """
23d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    while b:
24d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        a, b = b, a%b
25d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    return a
26d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
27d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
281dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson_RATIONAL_FORMAT = re.compile(r"""
291dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    \A\s*                      # optional whitespace at the start, then
301dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    (?P<sign>[-+]?)            # an optional sign, then
311dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    (?=\d|\.\d)                # lookahead for digit or .digit
321dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    (?P<num>\d*)               # numerator (possibly empty)
331dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    (?:                        # followed by an optional
341dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson       /(?P<denom>\d+)         # / and denominator
351dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    |                          # or
361dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson       \.(?P<decimal>\d*)      # decimal point and fractional part
371dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    )?
381dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson    \s*\Z                      # and optional whitespace to finish
391dabdb25f83d55737c2154b63bc463240fd7bc03Mark Dickinson""", re.VERBOSE)
4045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
4145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
42d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinsonclass Fraction(Rational):
43d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    """This class implements rational numbers.
44d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
45d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson    Fraction(8, 6) will produce a rational number equivalent to
46d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    4/3. Both arguments must be Integral. The numerator defaults to 0
47d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson    and the denominator defaults to 1 so that Fraction(3) == 3 and
48d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson    Fraction() == 0.
49d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
50d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson    Fractions can also be constructed from strings of the form
513e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin    '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces.
5245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
53d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    """
54d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
55dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    __slots__ = ('_numerator', '_denominator')
56d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
5745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    # We're immutable, so use __new__ not __init__
5845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    def __new__(cls, numerator=0, denominator=1):
59d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        """Constructs a Fraction.
6045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
61d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        Takes a string like '3/2' or '1.5', another Fraction, or a
623e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin        numerator/denominator pair.
6345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
6445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """
65d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        self = super(Fraction, cls).__new__(cls)
6645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
6745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if denominator == 1:
6845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            if isinstance(numerator, basestring):
6945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                # Handle construction from strings.
7045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                input = numerator
7145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                m = _RATIONAL_FORMAT.match(input)
7245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                if m is None:
73d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                    raise ValueError('Invalid literal for Fraction: ' + input)
743e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                numerator = m.group('num')
753e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                decimal = m.group('decimal')
763e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                if decimal:
773e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    # The literal is a decimal number.
783e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    numerator = int(numerator + decimal)
793e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    denominator = 10**len(decimal)
803e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                else:
813e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    # The literal is an integer or fraction.
823e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    numerator = int(numerator)
833e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    # Default denominator to 1.
843e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    denominator = int(m.group('denom') or 1)
853e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin
8645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                if m.group('sign') == '-':
8745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                    numerator = -numerator
8845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
8945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            elif (not isinstance(numerator, numbers.Integral) and
90d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                  isinstance(numerator, Rational)):
9145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                # Handle copies from other rationals.
9245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                other_rational = numerator
9345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                numerator = other_rational.numerator
9445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                denominator = other_rational.denominator
95d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
96d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if (not isinstance(numerator, numbers.Integral) or
97d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            not isinstance(denominator, numbers.Integral)):
98d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            raise TypeError("Fraction(%(numerator)s, %(denominator)s):"
99d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                            " Both arguments must be integral." % locals())
100d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
101d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if denominator == 0:
102d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
103d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
1043e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin        g = gcd(numerator, denominator)
105dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        self._numerator = int(numerator // g)
106dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        self._denominator = int(denominator // g)
10745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        return self
108d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
10974d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson    @staticmethod
11074d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson    def from_float(f):
11145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """Converts a finite float to a rational number, exactly.
11245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
113d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        Beware that Fraction.from_float(0.3) != Fraction(3, 10).
11445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
11545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """
116d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if not isinstance(f, float):
117d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            raise TypeError("Fraction.from_float() only takes floats, "
11874d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson                            "not %r (%s)" % (f, type(f).__name__))
119d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if math.isnan(f) or math.isinf(f):
120d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            raise TypeError("Cannot convert %r to Fraction." % f)
121d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(*f.as_integer_ratio())
122d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
12374d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson    @staticmethod
12474d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson    def from_decimal(dec):
12545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """Converts a finite Decimal instance to a rational number, exactly."""
12645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        from decimal import Decimal
12745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if not isinstance(dec, Decimal):
12845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            raise TypeError(
129d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                "Fraction.from_decimal() only takes Decimals, not %r (%s)" %
13074d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson                (dec, type(dec).__name__))
13145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if not dec.is_finite():
13245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            # Catches infinities and nans.
133d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            raise TypeError("Cannot convert %s to Fraction." % dec)
13445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        sign, digits, exp = dec.as_tuple()
13545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        digits = int(''.join(map(str, digits)))
13645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if sign:
13745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            digits = -digits
13845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if exp >= 0:
139d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            return Fraction(digits * 10 ** exp)
14045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        else:
141d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            return Fraction(digits, 10 ** -exp)
14245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
14374d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson    @staticmethod
14474d09144136e6b6cc072765fa052dd85f69dcde9Mark Dickinson    def from_continued_fraction(seq):
145d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        'Build a Fraction from a continued fraction expessed as a sequence'
146cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        n, d = 1, 0
147cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        for e in reversed(seq):
148cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n, d = d, n
149cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n += e * d
150d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(n, d) if seq else Fraction(0)
151cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger
152cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger    def as_continued_fraction(self):
153cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        'Return continued fraction expressed as a list'
154cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        n = self.numerator
155cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        d = self.denominator
156cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        cf = []
157cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        while d:
158cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            e = int(n // d)
159cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            cf.append(e)
160cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n -= e * d
161cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n, d = d, n
162cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        return cf
163cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger
1649c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger    def approximate(self, max_denominator):
1659c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger        'Best rational approximation with a denominator <= max_denominator'
166cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        # XXX First cut at algorithm
167cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        # Still needs rounding rules as specified at
168cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        #       http://en.wikipedia.org/wiki/Continued_fraction
1699c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger        if self.denominator <= max_denominator:
1709c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger            return self
1719c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger        cf = self.as_continued_fraction()
172d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        result = Fraction(0)
173cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        for i in range(1, len(cf)):
1749c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger            new = self.from_continued_fraction(cf[:i])
175cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            if new.denominator > max_denominator:
176cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger                break
177cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            result = new
178cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        return result
179cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger
180dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    @property
181dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    def numerator(a):
182dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        return a._numerator
183dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin
184dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    @property
185dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    def denominator(a):
186dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        return a._denominator
187dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin
188d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __repr__(self):
189d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """repr(self)"""
190d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return ('Fraction(%r,%r)' % (self.numerator, self.denominator))
191d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
192d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __str__(self):
193d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """str(self)"""
194d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if self.denominator == 1:
195d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return str(self.numerator)
196d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
19745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            return '%s/%s' % (self.numerator, self.denominator)
198d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
199d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _operator_fallbacks(monomorphic_operator, fallback_operator):
200d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """Generates forward and reverse operators given a purely-rational
201d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        operator and a function from the operator module.
202d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
203d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        Use this like:
204d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
205d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
206b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        In general, we want to implement the arithmetic operations so
207b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        that mixed-mode operations either call an implementation whose
208b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        author knew about the types of both arguments, or convert both
209b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        to the nearest built in type and do the operation there. In
210d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        Fraction, that means that we define __add__ and __radd__ as:
211b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
212b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            def __add__(self, other):
2132df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # Both types have numerators/denominator attributes,
2142df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # so do the operation directly
215d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                if isinstance(other, (int, long, Fraction)):
216d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                    return Fraction(self.numerator * other.denominator +
217b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    other.numerator * self.denominator,
218b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    self.denominator * other.denominator)
2192df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # float and complex don't have those operations, but we
2202df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # know about those types, so special case them.
221b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, float):
222b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return float(self) + other
223b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, complex):
224b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return complex(self) + other
2252df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # Let the other type take over.
2262df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                return NotImplemented
227b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
228b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            def __radd__(self, other):
229b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                # radd handles more types than add because there's
230b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                # nothing left to fall back to.
231d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                if isinstance(other, Rational):
232d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                    return Fraction(self.numerator * other.denominator +
233b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    other.numerator * self.denominator,
234b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    self.denominator * other.denominator)
235b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, Real):
236b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return float(other) + float(self)
237b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, Complex):
238b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return complex(other) + complex(self)
2392df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                return NotImplemented
240b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
241b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
242b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        There are 5 different cases for a mixed-type addition on
243d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        Fraction. I'll refer to all of the above code that doesn't
244d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        refer to Fraction, float, or complex as "boilerplate". 'r'
245d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        will be an instance of Fraction, which is a subtype of
246d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        Rational (r : Fraction <: Rational), and b : B <:
247b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        Complex. The first three involve 'r + b':
248b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
249d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            1. If B <: Fraction, int, float, or complex, we handle
250b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               that specially, and all is well.
251d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            2. If Fraction falls back to the boilerplate code, and it
252b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               were to return a value from __add__, we'd miss the
253b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               possibility that B defines a more intelligent __radd__,
254b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               so the boilerplate should return NotImplemented from
255d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson               __add__. In particular, we don't handle Rational
256b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               here, even though we could get an exact answer, in case
257b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               the other type wants to do something special.
258d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            3. If B <: Fraction, Python tries B.__radd__ before
259d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson               Fraction.__add__. This is ok, because it was
260d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson               implemented with knowledge of Fraction, so it can
261b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               handle those instances before delegating to Real or
262b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               Complex.
263b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
264b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        The next two situations describe 'b + r'. We assume that b
265d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        didn't know about Fraction in its implementation, and that it
266b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        uses similar boilerplate code:
267b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
268d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            4. If B <: Rational, then __radd_ converts both to the
269b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               builtin rational type (hey look, that's us) and
270b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               proceeds.
271b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            5. Otherwise, __radd__ tries to find the nearest common
272b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               base ABC, and fall back to its builtin type. Since this
273b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               class doesn't subclass a concrete type, there's no
274b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               implementation to fall back to, so we need to try as
275b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               hard as possible to return an actual value, or the user
276b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               will get a TypeError.
277b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
278d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
279d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        def forward(a, b):
280d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            if isinstance(b, (int, long, Fraction)):
281d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return monomorphic_operator(a, b)
282d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(b, float):
283d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(float(a), b)
284d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(b, complex):
285d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(complex(a), b)
286d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            else:
287d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return NotImplemented
288d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        forward.__name__ = '__' + fallback_operator.__name__ + '__'
289d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        forward.__doc__ = monomorphic_operator.__doc__
290d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
291d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        def reverse(b, a):
292d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            if isinstance(a, Rational):
293d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                # Includes ints.
294d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return monomorphic_operator(a, b)
295d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(a, numbers.Real):
296d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(float(a), float(b))
297d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(a, numbers.Complex):
298d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(complex(a), complex(b))
299d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            else:
300d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return NotImplemented
301d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
302d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        reverse.__doc__ = monomorphic_operator.__doc__
303d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
304d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return forward, reverse
305d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
306d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _add(a, b):
307d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a + b"""
308d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(a.numerator * b.denominator +
309d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        b.numerator * a.denominator,
310d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        a.denominator * b.denominator)
311d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
312d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __add__, __radd__ = _operator_fallbacks(_add, operator.add)
313d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
314d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _sub(a, b):
315d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a - b"""
316d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(a.numerator * b.denominator -
317d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        b.numerator * a.denominator,
318d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        a.denominator * b.denominator)
319d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
320d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
321d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
322d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _mul(a, b):
323d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a * b"""
324d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
325d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
326d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
327d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
328d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _div(a, b):
329d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a / b"""
330d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(a.numerator * b.denominator,
331d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        a.denominator * b.numerator)
332d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
333d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
334d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __div__, __rdiv__ = _operator_fallbacks(_div, operator.div)
335d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
336909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger    def __floordiv__(a, b):
337909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        """a // b"""
338909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        # Will be math.floor(a / b) in 3.0.
339d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        div = a / b
340d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if isinstance(div, Rational):
341d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # trunc(math.floor(div)) doesn't work if the rational is
342d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # more precise than a float because the intermediate
343d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # rounding may cross an integer boundary.
344d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return div.numerator // div.denominator
345d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
346d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return math.floor(div)
347d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
348d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __rfloordiv__(b, a):
349d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a // b"""
350d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        # Will be math.floor(a / b) in 3.0.
351909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        div = a / b
352d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if isinstance(div, Rational):
353909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            # trunc(math.floor(div)) doesn't work if the rational is
354909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            # more precise than a float because the intermediate
355909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            # rounding may cross an integer boundary.
356909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            return div.numerator // div.denominator
357909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        else:
358909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            return math.floor(div)
359d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
360d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __mod__(a, b):
361d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a % b"""
362909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        div = a // b
363909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        return a - b * div
364d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
365d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __rmod__(b, a):
366d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a % b"""
367909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        div = a // b
368909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        return a - b * div
369d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
370d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __pow__(a, b):
371d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a ** b
372d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
373d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        If b is not an integer, the result will be a float or complex
374d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        since roots are generally irrational. If b is an integer, the
375d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        result will be rational.
376d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
377d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
378d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if isinstance(b, Rational):
379d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            if b.denominator == 1:
380d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                power = b.numerator
381d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                if power >= 0:
382d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                    return Fraction(a.numerator ** power,
383d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                                    a.denominator ** power)
384d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                else:
385d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson                    return Fraction(a.denominator ** -power,
386d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                                    a.numerator ** -power)
387d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            else:
388d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                # A fractional power will generally produce an
389d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                # irrational number.
390d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return float(a) ** float(b)
391d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
392d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return float(a) ** b
393d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
394d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __rpow__(b, a):
395d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a ** b"""
396d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if b.denominator == 1 and b.numerator >= 0:
397d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # If a is an int, keep it that way if possible.
398d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a ** b.numerator
399d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
400d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if isinstance(a, Rational):
401d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            return Fraction(a.numerator, a.denominator) ** b
402d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
403d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if b.denominator == 1:
404d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a ** b.numerator
405d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
406d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a ** float(b)
407d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
408d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __pos__(a):
409d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        """+a: Coerces a subclass instance to Fraction"""
410d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(a.numerator, a.denominator)
411d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
412d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __neg__(a):
413d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """-a"""
414d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(-a.numerator, a.denominator)
415d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
416d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __abs__(a):
417d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """abs(a)"""
418d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        return Fraction(abs(a.numerator), a.denominator)
419d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
420d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __trunc__(a):
421d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """trunc(a)"""
422d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if a.numerator < 0:
423d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return -(-a.numerator // a.denominator)
424d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
425d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a.numerator // a.denominator
426d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
427d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __hash__(self):
428d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """hash(self)
429d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
430d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        Tricky because values that are exactly representable as a
431d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        float must have the same hash as that float.
432d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
433d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
434921cb5d3a3e823c6c225681d8e99f7baa8920f3eRaymond Hettinger        # XXX since this method is expensive, consider caching the result
435d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if self.denominator == 1:
436d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # Get integers right.
437d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return hash(self.numerator)
438d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        # Expensive check, but definitely correct.
439d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if self == float(self):
440d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return hash(float(self))
441d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
442d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # Use tuple's hash to avoid a high collision rate on
443d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # simple fractions.
444d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return hash((self.numerator, self.denominator))
445d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
446d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __eq__(a, b):
447d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a == b"""
448d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if isinstance(b, Rational):
449d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return (a.numerator == b.numerator and
450d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                    a.denominator == b.denominator)
451d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, numbers.Complex) and b.imag == 0:
452d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            b = b.real
453d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, float):
454d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a == a.from_float(b)
455d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
456d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # XXX: If b.__eq__ is implemented like this method, it may
457d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # give the wrong answer after float(a) changes a's
458d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # value. Better ways of doing this are welcome.
459d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return float(a) == b
460d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
461d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _subtractAndCompareToZero(a, b, op):
462d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """Helper function for comparison operators.
463d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
464d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        Subtracts b from a, exactly if possible, and compares the
465d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        result with 0 using op, in such a way that the comparison
466d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        won't recurse. If the difference raises a TypeError, returns
467d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        NotImplemented instead.
468d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
469d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
470d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, numbers.Complex) and b.imag == 0:
471d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            b = b.real
472d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, float):
473d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            b = a.from_float(b)
474d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        try:
475d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson            # XXX: If b <: Real but not <: Rational, this is likely
476d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # to fall back to a float. If the actual values differ by
477d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # less than MIN_FLOAT, this could falsely call them equal,
478d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # which would make <= inconsistent with ==. Better ways of
479d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # doing this are welcome.
480d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            diff = a - b
481d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        except TypeError:
482d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return NotImplemented
483d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if isinstance(diff, Rational):
484d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return op(diff.numerator, 0)
485d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return op(diff, 0)
486d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
487d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __lt__(a, b):
488d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a < b"""
489d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.lt)
490d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
491d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __gt__(a, b):
492d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a > b"""
493d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.gt)
494d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
495d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __le__(a, b):
496d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a <= b"""
497d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.le)
498d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
499d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __ge__(a, b):
500d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a >= b"""
501d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.ge)
502d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
503d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __nonzero__(a):
504d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a != 0"""
505d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a.numerator != 0
506a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
507a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    # support for pickling, copy, and deepcopy
508a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
509a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    def __reduce__(self):
510a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        return (self.__class__, (str(self),))
511a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
512a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    def __copy__(self):
513d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if type(self) == Fraction:
514a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger            return self     # I'm immutable; therefore I am my own clone
515a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        return self.__class__(self.numerator, self.denominator)
516a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
517a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    def __deepcopy__(self, memo):
518d058cd2cc8e2a3f61609b92a8fc821ea8ec524caMark Dickinson        if type(self) == Fraction:
519a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger            return self     # My components are also immutable
520a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        return self.__class__(self.numerator, self.denominator)
521