1992-08-13 09:14:11 -03:00
|
|
|
# Rational numbers
|
|
|
|
|
1994-10-09 19:36:28 -03:00
|
|
|
from types import *
|
1992-08-13 09:14:11 -03:00
|
|
|
|
|
|
|
def rat(num, den):
|
1994-10-09 19:36:28 -03:00
|
|
|
if type(num) == FloatType or type(den) == FloatType:
|
|
|
|
return num/den
|
1993-12-17 10:23:52 -04:00
|
|
|
return Rat(num, den)
|
1992-08-13 09:14:11 -03:00
|
|
|
|
|
|
|
|
|
|
|
def gcd(a, b):
|
|
|
|
while b:
|
|
|
|
a, b = b, a%b
|
|
|
|
return a
|
|
|
|
|
|
|
|
|
|
|
|
class Rat:
|
|
|
|
|
1993-12-17 10:23:52 -04:00
|
|
|
def __init__(self, num, den):
|
1992-08-13 09:14:11 -03:00
|
|
|
if den == 0:
|
|
|
|
raise ZeroDivisionError, 'rat(x, 0)'
|
1994-10-09 19:36:28 -03:00
|
|
|
if type(den) == FloatType or type(num) == FloatType:
|
|
|
|
g = float(den)
|
|
|
|
else:
|
|
|
|
g = gcd(num, den)
|
1992-08-13 09:14:11 -03:00
|
|
|
self.num = num/g
|
|
|
|
self.den = den/g
|
|
|
|
|
|
|
|
def __repr__(self):
|
1994-10-09 19:36:28 -03:00
|
|
|
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)
|
1992-08-13 09:14:11 -03:00
|
|
|
|
|
|
|
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)
|
1994-10-09 19:36:28 -03:00
|
|
|
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__:
|
1993-12-17 10:23:52 -04:00
|
|
|
return a, b
|
1992-08-13 09:14:11 -03:00
|
|
|
raise TypeError, 'Rat.__coerce__: bad other arg'
|
1993-12-17 10:23:52 -04:00
|
|
|
|
1992-08-13 09:14:11 -03:00
|
|
|
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():
|
1994-10-09 19:36:28 -03:00
|
|
|
print Rat(-1L, 1)
|
|
|
|
print Rat(1, -1)
|
|
|
|
a = Rat(1, 10)
|
1992-08-13 09:14:11 -03:00
|
|
|
print int(a), long(a), float(a)
|
1994-10-09 19:36:28 -03:00
|
|
|
b = Rat(2, 5)
|
1992-08-13 09:14:11 -03:00
|
|
|
l = [a+b, a-b, a*b, a/b]
|
|
|
|
print l
|
|
|
|
l.sort()
|
|
|
|
print l
|
1994-10-09 19:36:28 -03:00
|
|
|
print Rat(0, 1)
|
1992-08-13 09:14:11 -03:00
|
|
|
print a+1
|
|
|
|
print a+1L
|
|
|
|
print a+1.0
|
1993-10-27 06:28:23 -03:00
|
|
|
try:
|
1994-10-09 19:36:28 -03:00
|
|
|
print Rat(1, 0)
|
1993-10-27 06:28:23 -03:00
|
|
|
raise SystemError, 'should have been ZeroDivisionError'
|
|
|
|
except ZeroDivisionError:
|
|
|
|
print 'OK'
|
1992-08-13 09:14:11 -03:00
|
|
|
|
1993-12-17 10:23:52 -04:00
|
|
|
test()
|