# Rational numbers from types import * def rat(num, den): if type(num) == FloatType or type(den) == FloatType: return num/den return Rat(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)' if type(den) == FloatType or type(num) == FloatType: g = float(den) else: g = gcd(num, den) self.num = num/g self.den = den/g def __repr__(self): return 'Rat(%s, %s)' % (self.num, self.den) def __str__(self): if self.den == 1: return str(self.num) else: return '%s/%s' % (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 == IntType: return a, Rat(b, 1) if t == LongType: return a, Rat(b, 1L) if t == FloatType: return a, Rat(b, 1.0) if t == InstanceType and a.__class__ == b.__class__: return a, b raise TypeError, 'Rat.__coerce__: bad other arg' def __add__(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): 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()