"""Tests for binary operators on subtypes of built-in types."""
from test
import test_support
"""Greatest common divisor using Euclid's algorithm."""
"""Test whether an object is an instance of int or long."""
return isinstance(x
, int) or isinstance(x
, long)
"""Test whether an object is an instance of a built-in numeric type."""
for T
in int, long, float, complex:
"""Test wheter an object is an instance of the Rat class."""
return isinstance(x
, Rat
)
"""Rational number implemented as a normalized pair of longs."""
__slots__
= ['_Rat__num', '_Rat__den']
def __init__(self
, num
=0L, den
=1L):
"""Constructor: Rat([num[, den]]).
The arguments must be ints or longs, and default to (0, 1)."""
raise TypeError, "Rat numerator must be int or long (%r)" % num
raise TypeError, "Rat denominator must be int or long (%r)" % den
# But the zero is always on
raise ZeroDivisionError, "zero denominator"
self
.__num
= long(num
//g
)
self
.__den
= long(den
//g
)
"""Accessor function for read-only 'num' attribute of Rat."""
num
= property(_get_num
, None)
"""Accessor function for read-only 'den' attribute of Rat."""
den
= property(_get_den
, None)
"""Convert a Rat to an string resembling a Rat constructor call."""
return "Rat(%d, %d)" % (self
.__num
, self
.__den
)
"""Convert a Rat to a string resembling a decimal numeric value."""
"""Convert a Rat to a float."""
return self
.__num
*1.0/self
.__den
"""Convert a Rat to an int; self.den must be 1."""
raise OverflowError, ("%s too large to convert to int" %
raise ValueError, "can't convert %s to int" % repr(self
)
"""Convert a Rat to an long; self.den must be 1."""
raise ValueError, "can't convert %s to long" % repr(self
)
def __add__(self
, other
):
"""Add two Rats, or a Rat and a number."""
return Rat(self
.__num
*other
.__den
+ other
.__num
*self
.__den
,
return float(self
) + other
def __sub__(self
, other
):
"""Subtract two Rats, or a Rat and a number."""
return Rat(self
.__num
*other
.__den
- other
.__num
*self
.__den
,
return float(self
) - other
def __rsub__(self
, other
):
"""Subtract two Rats, or a Rat and a number (reversed args)."""
return Rat(other
.__num
*self
.__den
- self
.__num
*other
.__den
,
return other
- float(self
)
def __mul__(self
, other
):
"""Multiply two Rats, or a Rat and a number."""
return Rat(self
.__num
*other
.__num
, self
.__den
*other
.__den
)
return Rat(self
.__num
*other
, self
.__den
)
def __truediv__(self
, other
):
"""Divide two Rats, or a Rat and a number."""
return Rat(self
.__num
*other
.__den
, self
.__den
*other
.__num
)
return Rat(self
.__num
, self
.__den
*other
)
return float(self
) / other
def __rtruediv__(self
, other
):
"""Divide two Rats, or a Rat and a number (reversed args)."""
return Rat(other
.__num
*self
.__den
, other
.__den
*self
.__num
)
return Rat(other
*self
.__den
, self
.__num
)
return other
/ float(self
)
def __floordiv__(self
, other
):
"""Divide two Rats, returning the floored result."""
return x
.__num
// x
.__den
def __rfloordiv__(self
, other
):
"""Divide two Rats, returning the floored result (reversed args)."""
return x
.__num
// x
.__den
def __divmod__(self
, other
):
"""Divide two Rats, returning quotient and remainder."""
return (x
, self
- other
* x
)
def __rdivmod__(self
, other
):
"""Divide two Rats, returning quotient and remainder (reversed args)."""
return divmod(other
, self
)
def __mod__(self
, other
):
"""Take one Rat modulo another."""
return divmod(self
, other
)[1]
def __rmod__(self
, other
):
"""Take one Rat modulo another (reversed args)."""
return divmod(other
, self
)[1]
"""Compare two Rats for equality."""
return self
.__den
== 1 and self
.__num
== other
return self
.__num
== other
.__num
and self
.__den
== other
.__den
return float(self
) == other
"""Compare two Rats for inequality."""
class RatTestCase(unittest
.TestCase
):
"""Unit tests for Rat class and its support utilities."""
self
.assertEqual(gcd(10, 12), 2)
self
.assertEqual(gcd(10, 15), 5)
self
.assertEqual(gcd(10, 11), 1)
self
.assertEqual(gcd(100, 15), 5)
self
.assertEqual(gcd(-10, 2), -2)
self
.assertEqual(gcd(10, -2), 2)
self
.assertEqual(gcd(-10, -2), -2)
self
.assert_(gcd(i
, j
) > 0)
self
.assert_(gcd(-i
, j
) < 0)
self
.assert_(gcd(i
, -j
) > 0)
self
.assert_(gcd(-i
, -j
) < 0)
def test_constructor(self
):
self
.assertEqual(a
.num
, 2)
self
.assertEqual(a
.den
, 3)
self
.assertEqual(a
.num
, 2)
self
.assertEqual(a
.den
, 3)
self
.assertEqual(a
.num
, -2)
self
.assertEqual(a
.den
, 3)
self
.assertEqual(a
.num
, -2)
self
.assertEqual(a
.den
, 3)
self
.assertEqual(a
.num
, 2)
self
.assertEqual(a
.den
, 3)
self
.assertEqual(a
.num
, 7)
self
.assertEqual(a
.den
, 1)
except ZeroDivisionError:
self
.fail("Rat(1, 0) didn't raise ZeroDivisionError")
for bad
in "0", 0.0, 0j
, (), [], {}, None, Rat
, unittest
:
self
.fail("Rat(%r) didn't raise TypeError" % bad
)
self
.fail("Rat(1, %r) didn't raise TypeError" % bad
)
self
.assertEqual(Rat(2, 3) + Rat(1, 3), 1)
self
.assertEqual(Rat(2, 3) + 1, Rat(5, 3))
self
.assertEqual(1 + Rat(2, 3), Rat(5, 3))
self
.assertEqual(1.0 + Rat(1, 2), 1.5)
self
.assertEqual(Rat(1, 2) + 1.0, 1.5)
self
.assertEqual(Rat(7, 2) - Rat(7, 5), Rat(21, 10))
self
.assertEqual(Rat(7, 5) - 1, Rat(2, 5))
self
.assertEqual(1 - Rat(3, 5), Rat(2, 5))
self
.assertEqual(Rat(3, 2) - 1.0, 0.5)
self
.assertEqual(1.0 - Rat(1, 2), 0.5)
self
.assertEqual(Rat(2, 3) * Rat(5, 7), Rat(10, 21))
self
.assertEqual(Rat(10, 3) * 3, 10)
self
.assertEqual(3 * Rat(10, 3), 10)
self
.assertEqual(Rat(10, 5) * 0.5, 1.0)
self
.assertEqual(0.5 * Rat(10, 5), 1.0)
self
.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))
self
.assertEqual(Rat(10, 3) / 3, Rat(10, 9))
self
.assertEqual(2 / Rat(5), Rat(2, 5))
self
.assertEqual(3.0 * Rat(1, 2), 1.5)
self
.assertEqual(Rat(1, 2) * 3.0, 1.5)
self
.assertEqual(Rat(10) // Rat(4), 2)
self
.assertEqual(Rat(10, 3) // Rat(4, 3), 2)
self
.assertEqual(Rat(10) // 4, 2)
self
.assertEqual(10 // Rat(4), 2)
self
.assertEqual(Rat(10), Rat(20, 2))
self
.assertEqual(Rat(10), 10)
self
.assertEqual(10, Rat(10))
self
.assertEqual(Rat(10), 10.0)
self
.assertEqual(10.0, Rat(10))
def test_future_div(self
):
# XXX Ran out of steam; TO DO: divmod, div, future division
from __future__ import division
self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))
self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))
self.assertEqual(2 / Rat(5), Rat(2, 5))
self.assertEqual(3.0 * Rat(1, 2), 1.5)
self.assertEqual(Rat(1, 2) * 3.0, 1.5)
self.assertEqual(eval('1/2'), 0.5)
test_support
.run_unittest(RatTestCase
)
if __name__
== "__main__":