14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Tests for binary operators on subtypes of built-in types.""" 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef gcd(a, b): 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Greatest common divisor using Euclid's algorithm.""" 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while a: 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a, b = b%a, a 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return b 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef isint(x): 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test whether an object is an instance of int or long.""" 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return isinstance(x, int) or isinstance(x, long) 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef isnum(x): 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test whether an object is an instance of a built-in numeric type.""" 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for T in int, long, float, complex: 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(x, T): 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 1 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef isRat(x): 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test wheter an object is an instance of the Rat class.""" 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return isinstance(x, Rat) 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Rat(object): 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Rational number implemented as a normalized pair of longs.""" 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __slots__ = ['_Rat__num', '_Rat__den'] 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, num=0L, den=1L): 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Constructor: Rat([num[, den]]). 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The arguments must be ints or longs, and default to (0, 1).""" 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not isint(num): 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError, "Rat numerator must be int or long (%r)" % num 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not isint(den): 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError, "Rat denominator must be int or long (%r)" % den 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # But the zero is always on 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if den == 0: 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ZeroDivisionError, "zero denominator" 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm g = gcd(den, num) 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__num = long(num//g) 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__den = long(den//g) 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _get_num(self): 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Accessor function for read-only 'num' attribute of Rat.""" 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.__num 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm num = property(_get_num, None) 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _get_den(self): 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Accessor function for read-only 'den' attribute of Rat.""" 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.__den 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm den = property(_get_den, None) 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __repr__(self): 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Convert a Rat to an string resembling a Rat constructor call.""" 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "Rat(%d, %d)" % (self.__num, self.__den) 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __str__(self): 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Convert a Rat to a string resembling a decimal numeric value.""" 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return str(float(self)) 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __float__(self): 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Convert a Rat to a float.""" 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.__num*1.0/self.__den 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __int__(self): 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Convert a Rat to an int; self.den must be 1.""" 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.__den == 1: 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return int(self.__num) 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except OverflowError: 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise OverflowError, ("%s too large to convert to int" % 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm repr(self)) 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "can't convert %s to int" % repr(self) 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __long__(self): 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Convert a Rat to an long; self.den must be 1.""" 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.__den == 1: 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return long(self.__num) 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "can't convert %s to long" % repr(self) 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __add__(self, other): 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Add two Rats, or a Rat and a number.""" 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = Rat(other) 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(self.__num*other.__den + other.__num*self.__den, 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__den*other.__den) 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return float(self) + other 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __radd__ = __add__ 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __sub__(self, other): 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Subtract two Rats, or a Rat and a number.""" 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = Rat(other) 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(self.__num*other.__den - other.__num*self.__den, 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__den*other.__den) 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return float(self) - other 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rsub__(self, other): 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Subtract two Rats, or a Rat and a number (reversed args).""" 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = Rat(other) 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(other.__num*self.__den - self.__num*other.__den, 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__den*other.__den) 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return other - float(self) 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __mul__(self, other): 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Multiply two Rats, or a Rat and a number.""" 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(self.__num*other.__num, self.__den*other.__den) 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(self.__num*other, self.__den) 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return float(self)*other 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __rmul__ = __mul__ 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __truediv__(self, other): 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Divide two Rats, or a Rat and a number.""" 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(self.__num*other.__den, self.__den*other.__num) 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(self.__num, self.__den*other) 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return float(self) / other 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __div__ = __truediv__ 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rtruediv__(self, other): 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Divide two Rats, or a Rat and a number (reversed args).""" 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(other.__num*self.__den, other.__den*self.__num) 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Rat(other*self.__den, self.__num) 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return other / float(self) 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __rdiv__ = __rtruediv__ 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __floordiv__(self, other): 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Divide two Rats, returning the floored result.""" 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = Rat(other) 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif not isRat(other): 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = self/other 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x.__num // x.__den 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rfloordiv__(self, other): 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Divide two Rats, returning the floored result (reversed args).""" 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = other/self 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x.__num // x.__den 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __divmod__(self, other): 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Divide two Rats, returning quotient and remainder.""" 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = Rat(other) 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif not isRat(other): 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = self//other 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (x, self - other * x) 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rdivmod__(self, other): 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Divide two Rats, returning quotient and remainder (reversed args).""" 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = Rat(other) 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif not isRat(other): 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return divmod(other, self) 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __mod__(self, other): 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Take one Rat modulo another.""" 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return divmod(self, other)[1] 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rmod__(self, other): 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Take one Rat modulo another (reversed args).""" 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return divmod(other, self)[1] 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __eq__(self, other): 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Compare two Rats for equality.""" 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isint(other): 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.__den == 1 and self.__num == other 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isRat(other): 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.__num == other.__num and self.__den == other.__den 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isnum(other): 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return float(self) == other 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NotImplemented 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __ne__(self, other): 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Compare two Rats for inequality.""" 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return not self == other 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Silence Py3k warning 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __hash__ = None 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass RatTestCase(unittest.TestCase): 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Unit tests for Rat class and its support utilities.""" 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_gcd(self): 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(10, 12), 2) 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(10, 15), 5) 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(10, 11), 1) 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(100, 15), 5) 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(-10, 2), -2) 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(10, -2), 2) 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(gcd(-10, -2), -2) 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in range(1, 20): 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for j in range(1, 20): 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(gcd(i, j) > 0) 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(gcd(-i, j) < 0) 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(gcd(i, -j) > 0) 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(gcd(-i, -j) < 0) 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_constructor(self): 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(10, 15) 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.num, 2) 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.den, 3) 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(10L, 15L) 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.num, 2) 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.den, 3) 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(10, -15) 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.num, -2) 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.den, 3) 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(-10, 15) 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.num, -2) 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.den, 3) 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(-10, -15) 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.num, 2) 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.den, 3) 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(7) 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.num, 7) 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(a.den, 1) 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(1, 0) 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except ZeroDivisionError: 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fail("Rat(1, 0) didn't raise ZeroDivisionError") 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for bad in "0", 0.0, 0j, (), [], {}, None, Rat, unittest: 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(bad) 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError: 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fail("Rat(%r) didn't raise TypeError" % bad) 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a = Rat(1, bad) 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError: 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fail("Rat(1, %r) didn't raise TypeError" % bad) 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_add(self): 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(2, 3) + Rat(1, 3), 1) 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(2, 3) + 1, Rat(5, 3)) 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(1 + Rat(2, 3), Rat(5, 3)) 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(1.0 + Rat(1, 2), 1.5) 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(1, 2) + 1.0, 1.5) 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_sub(self): 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(7, 2) - Rat(7, 5), Rat(21, 10)) 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(7, 5) - 1, Rat(2, 5)) 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(1 - Rat(3, 5), Rat(2, 5)) 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(3, 2) - 1.0, 0.5) 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(1.0 - Rat(1, 2), 0.5) 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_mul(self): 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(2, 3) * Rat(5, 7), Rat(10, 21)) 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10, 3) * 3, 10) 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(3 * Rat(10, 3), 10) 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10, 5) * 0.5, 1.0) 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(0.5 * Rat(10, 5), 1.0) 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_div(self): 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3)) 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10, 3) / 3, Rat(10, 9)) 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(2 / Rat(5), Rat(2, 5)) 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(3.0 * Rat(1, 2), 1.5) 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(1, 2) * 3.0, 1.5) 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_floordiv(self): 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10) // Rat(4), 2) 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10, 3) // Rat(4, 3), 2) 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10) // 4, 2) 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(10 // Rat(4), 2) 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_eq(self): 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10), Rat(20, 2)) 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10), 10) 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(10, Rat(10)) 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(Rat(10), 10.0) 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(10.0, Rat(10)) 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_future_div(self): 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exec future_test 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # XXX Ran out of steam; TO DO: divmod, div, future division 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfuture_test = """ 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom __future__ import division 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmself.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3)) 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmself.assertEqual(Rat(10, 3) / 3, Rat(10, 9)) 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmself.assertEqual(2 / Rat(5), Rat(2, 5)) 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmself.assertEqual(3.0 * Rat(1, 2), 1.5) 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmself.assertEqual(Rat(1, 2) * 3.0, 1.5) 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmself.assertEqual(eval('1/2'), 0.5) 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main(): 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test_support.run_unittest(RatTestCase) 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__": 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test_main() 332