# Rational numbers def rat(num, den): return Rat().init(num, den) def gcd(a, b): while b: a, b = b, a%b return a class Rat: def init(self, num, den): if den == 0: raise ZeroDivisionError, 'rat(x, 0)' g = gcd(num, den) self.num = num/g self.den = den/g return self def __repr__(self): return 'rat' + `self.num, self.den` def __cmp__(a, b): c = a-b if c.num < 0: return -1 if c.num > 0: return 1 return 0 def __float__(self): return float(self.num) / float(self.den) def __long__(self): return long(self.num) / long(self.den) def __int__(self): return int(self.num / self.den) def __coerce__(a, b): t = type(b) if t == type(0): return a, rat(b, 1) if t == type(0L): return a, rat(b, 1L) if t == type(0.0): return a.__float__(), b raise TypeError, 'Rat.__coerce__: bad other arg' def __add__(a, b): if type(b) <> type(a): a, b = a.__coerce__(b) return a + b return rat(a.num*b.den + b.num*a.den, a.den*b.den) def __sub__(a, b): return rat(a.num*b.den - b.num*a.den, a.den*b.den) def __mul__(a, b): if type(b) <> type(a): a, b = a.__coerce__(b) return a * b return rat(a.num*b.num, a.den*b.den) def __div__(a, b): return rat(a.num*b.den, a.den*b.num) def __neg__(self): return rat(-self.num, self.den) def test(): print rat(-1L, 1) print rat(1, -1) a = rat(1, 10) print int(a), long(a), float(a) b = rat(2, 5) l = [a+b, a-b, a*b, a/b] print l l.sort() print l print rat(0, 1) print a+1 print a+1L print a+1.0 try: print rat(1, 0) raise SystemError, 'should have been ZeroDivisionError' except ZeroDivisionError: print 'OK' #test()