# Implement Fraction of integers with arithmetic operations and comparisons. # Author: Yotam Medini yotam.medini@gmail.com -- Created: 2006/October/04 import string def gcd(m, n): m = abs(m) n = abs(n) if m < n: t = m; m = n; n = t; # swap # Now we have: m >= n >= 0 while n > 0: # Euclid remainder = m % n m = n n = remainder return m def safe_int(s): "Convert string to integer, return None if bad string" try: n = int(s) except: n = None return n def str2nd(s): "Convert 'n1' or 'n1/n2' to pair (d,n) for fraction. None otherwise" ss = string.split(s, '/') n = None d = 1 if 1 <= len(ss) <= 2: n = safe_int(ss[0]) if len(ss) == 2: d = safe_int(ss[1]) nd = None # for bad input if n != None and d != None: nd = (n, d) return nd class Fraction: "Fraction of integers with arithmetic operations and comparisons" def __init__(self, n=0, d=1): self.n = n # Numerator self.d = d # Denominator > 0 self.reduce() def strset(self, s): nd = str2nd(s) ok = (nd != None) if ok: self.n = nd[0] self.d = nd[1] self.reduce() return ok def reduce(self): r = gcd(self.n, self.d) if r > 1: self.n /= r self.d /= r if self.d < 0: # We want positive denominator self.d = -self.d self.n = -self.n def __str__(self): return "(%d/%d)" % (self.n, self.d) def zero(self): return self.n == 0 def positive(self): return self.n > 0 def negative(self): return self.n < 0 def __neg__(self): return Fraction(-self.n, self.d) def __add__(self, other): n = self.n * other.d + other.n * self.d d = self.d * other.d return Fraction(n, d) def __sub__(self, other): return self + (-other) def __mul__(self, other): return Fraction(self.n * other.n, self.d * other.d) def __div__(self, other): return Fraction(self.n * other.d, self.d * other.n) def __cmp__(self, other): diff = self.n * other.d - other.n * self.d return diff zero = Fraction(0) one = Fraction(1) if __name__ == '__main__': import sys def usage(a0, rc=1): sys.stderr.write(""" Usage: %s Where and are fractions of the form: d or d/n with d and n integers. """[1:] % a0) sys.exit(rc) if len(sys.argv) != 3: usage(sys.argv[0]) f1 = Fraction() f2 = Fraction() f1.strset(sys.argv[1]) f2.strset(sys.argv[2]) sys.stdout.write(""" zero = %s, one = %s, f1 = %s, f2 = %s -f1 = %s, -f2 = %s f1 + f2 = %s f1 - f2 = %s f1 * f2 = %s f1 / f2 = %s f1 == f2 = %s f1 != f2 = %s f1 < f2 = %s f1 <= f2 = %s f1 > f2 = %s f1 >= f2 = %s """[1:] % ( zero, one, f1, f2, -f1, -f2, f1 + f2, f1 - f2, f1 * f2, f1 / f2, (f1 == f2), (f1 != f2), f1 < f2, f1 <= f2, f1 > f2, f1 >= f2 )) sys.exit(0)