from operator import add, sub, mul, div, gt, lt, eq def gcd(frac): mod = frac[0] % frac[1] return frac[1] if not(mod) else gcd((frac[1], mod)) class Fraction: def __init__(self, *args): if len(args) == 2: self.frac = args else: arg = args[0] if isinstance(arg, Fraction): self.frac = arg.frac elif hasattr(arg, "__iter__"): self.frac = arg elif isinstance(arg, int): self.frac = arg, 1 elif isinstance(arg, float): d = 10 ** len(("%f" % arg).split(".")[1]) self.frac = (int(arg * d), d) elif isinstance(arg, str): self.frac = map(int, arg.split('/')) Frac = Fraction self.__getitem__ = self.frac.__getitem__ self.__iter__, self.__len__ = self.frac.__iter__, self.frac.__len__ self.__cmp__ = lambda x: cmp(float(self), float(Frac(x))) self.__str__ = lambda: "%d/%d" % tuple(self.frac) self.__float__ = lambda: div(*map(float, self)) self.__int__ = lambda: div(*self) self.__mul__ = lambda x: Frac(map(mul, self, Frac(x))) self.__div__ = lambda x: self * reversed(Frac(x)) op = lambda func, a, b: (func(*map(mul, a, b)), a[1] * b[0]) self.__add__ = lambda x: Frac(op(add, self, Frac(x).recip())) self.__sub__ = lambda x: Frac(op(sub, self, Frac(x).recip())) self.recip = lambda: Frac(reversed(self)) self.frac = map(div, self, [gcd(self)] * 2) if __name__ == "__main__": ops = {'+':add, '-':sub, '*':mul, '/':div, '>':gt, '<':lt, '=':eq} for fracs in (("1/2", 0.25), (1, (1, 3)), (0.01, [1, 5])): a, b = map(Fraction, fracs) print "For fractions '%s' and '%s'..." % (a, b) print "As floats: '%s' and '%s'" % (float(a), float(b)) for op, func in ops.items(): print "%s %s %s is %s" % (a, op, b, func(a, b)) print float(Fraction("1/2"))