CS 3723
  Programming Languages  
  Fraction class   

Fraction Example
Python Fraction class test_fraction.py
# fraction.py: implement fractions
import sys
# num = top = numerator; den = bottom = denomiator
def gcd(m,n):  # m can be negative
    while m%n != 0:
        oldm = m
        oldn = n
        m = oldn
        n = oldm%oldn
    return n

class Fraction:
    def __init__(self,top,bottom):
        self.num = top
        self.den = bottom
        #sys.stdout.write("New: ")
        #Fraction.show(self)
        #sys.stdout.write("\n")

    def __str__(self):
        return str(self.num)+"/"+str(self.den)

    def show(self):
        sys.stdout.write(str(self.num) + "/" +
          str(self.den))

    def __add__(self,other):
        newnum = self.num*other.den + \
                      self.den*other.num
        newden = self.den * other.den
        com = gcd(newnum,newden)
        return Fraction(newnum//com,newden//com)
 
    def __sub__(self,other):
        newnum = self.num*other.den - \
                      self.den*other.num
        newden = self.den * other.den
        com = gcd(newnum,newden)
        return Fraction(newnum//com,newden//com)
 
    def __mul__(self, fract):
        newnum = self.num*fract.num
        newden = self.den*fract.den
        common = gcd(newnum, newden)
        return Fraction(newnum//common,
          newden//common)

    def __div__(self, other):
        sign = 1
        if other.num == 0:
            return None # divide by 0
        if other.num < 0:
            sign = -1
            othernum = -other.num
        else:
            othernum = other.num
        newnum = self.num*other.den
        newden = self.den*othernum
        common = gcd(newnum, newden)
        return Fraction(sign*newnum//common,
          newden//common)

    def __eq__(self, other):
        firstnum = self.num * other.den
        secondnum = other.num * self.den
        return firstnum == secondnum
        
    def __ne__(self, other):
        return not self.__eq__(other)

    def __lt__(self, other):
        firstnum = self.num * other.den
        secondnum = other.num * self.den
        return firstnum < secondnum

    def __le__(self, other):
        return self.__lt__(other) or \
          self.__eq__(other)

    def __ge__(self, other):
        return not self.__lt__(other)

    def __gt__(self, other):
        return not self.__le__(other)
        
    def float(self):
        return float(self.num) / float(self.den)

    def getNum(self):
        return self.num

    def getDen(self):
        return self.den
# test_fraction.py: test fraction class
import sys
from mpmath import * # arbitrary precision
from fraction import Fraction

def partA():
    u = Fraction(1, 2)
    v = Fraction(2, 3)
    w = Fraction(3, 7)
    x = Fraction(-4, 11)
    y = Fraction(-7, 13)
    z = Fraction(-2, 5)
    
    sys.stdout.write("x.getNum(): " +
          str(x.getNum()) + "\n")
    sys.stdout.write("x.getDen(): " +
          str(x.getDen()) + "\n")
    
    sys.stdout.write("u != v: " + str(u != v) + "\n")
    sys.stdout.write("u <  v: " + str(u < v) + "\n")
    sys.stdout.write("u <= v: " + str(u <= v) + "\n")
    sys.stdout.write("u == v: " + str(u == v) + "\n")
    sys.stdout.write("u >  v: " + str(u > v) + "\n")
    sys.stdout.write("u >= v: " + str(u >= v) + "\n")
    sys.stdout.write("x != y: " + str(x != y) + "\n")
    sys.stdout.write("x <  y: " + str(x < y) + "\n")
    sys.stdout.write("x <= y: " + str(x <= y) + "\n")
    sys.stdout.write("x == y: " + str(x == y) + "\n")
    sys.stdout.write("x >  y: " + str(x > y) + "\n")
    sys.stdout.write("x >= y: " + str(x >= y) + "\n")
    sys.stdout.write("u + v: " + str(u + v) + "\n")
    sys.stdout.write("u - v: " + str(u - v) + "\n")
    sys.stdout.write("w + x: " + str(w + x) + "\n")
    sys.stdout.write("w - x: " + str(w - x) + "\n")
    sys.stdout.write("u + y: " + str(u + y) + "\n")
    sys.stdout.write("u - y: " + str(u - y) + "\n")
    sys.stdout.write("x + y: " + str(x + y) + "\n")
    sys.stdout.write("x - y: " + str(x - y) + "\n")
    sys.stdout.write("w * x: " + str(w * x) + "\n")
    sys.stdout.write("y * z: " + str(y * z) + "\n")
    sys.stdout.write("w * y: " + str(w * y) + "\n")
    sys.stdout.write("u / v: " + str(u / v) + "\n")
    sys.stdout.write("w / x: " + str(w / x) + "\n")
    sys.stdout.write("x / z: " + str(x / z) + "\n")
    sys.stdout.write("y / v: " + str(y / v) + "\n")

def partB():
    c1 = Fraction(1, 1)
    c2 = Fraction(2, 1)
    c3 = Fraction(3, 1)
    c7 = Fraction(7, 1)
    c14 = Fraction(14, 1)
    c15 = Fraction(15, 1)
    c292 = Fraction(292, 1)
    
    pi1 = c3 + c1 / (c7 + c1 / (c15 + c1))
    pi2  = c3 + c1 / (c7 + c1 / (c15 + c1 / (c1 +
      c1 / c292)))
    pi3 = c3+c1/(c7+c1/(c15+c1/(c1+c1/(c292+c1/(c1+
      c1/(c1+c1/(c1+c1/(c2+c1/(c1+c1/(c3+c1/(c1+
      c1/c14)))))))))))
    
    sys.stdout.write("pi1: " + str(pi1) + "\n")
    sys.stdout.write("pi1: %20.16f\n" % 
      (float(pi1.getNum()) / float(pi1.getDen())) )
    
    sys.stdout.write("pi2: " + str(pi2) + "\n")
    sys.stdout.write("pi2: %20.16f\n" % 
      (float(pi2.getNum()) / float(pi2.getDen())) )
    
    sys.stdout.write("pi3: " + str(pi3) + "\n")
    sys.stdout.write("pi3: %20.16f\n" % 
      (float(pi3.getNum()) / float(pi3.getDen())) )

def partC(j):
    sys.stdout.write("\nCall C(" + str(j) + ")\n")
    c1 = Fraction(1,1)
    c2 = Fraction(2,1)
    c4 = Fraction(4,1)
    fi = Fraction(j, 1)
    ft = Fraction(2*j+1, 1)
    while fi >= c1:
        ft = (fi * fi) / ft
        ft = ((c2 * fi) - c1) + ft
        fi = fi - c1
    ft = c4 / ft
    sys.stdout.write(str(ft.getNum()) + " /\n")
    sys.stdout.write(str(ft.getDen()) + " \n")
    mp.dps = j # set precision = j digits
    sys.stdout.write("High precision: " + 
      str(mp.dps) + "\n")
    n = mpf(ft.getNum()) # hi precision num
    d = mpf(ft.getDen()) # hi precision den
    sys.stdout.write("Fraction:" + str(n/d) + "\n")
    sys.stdout.write("Pi:      " + str(pi) + "\n")

sys.stdout.write("Part A:\n")
partA()

sys.stdout.write("\nPart B:\n")
partB()

sys.stdout.write("\nPart C:\n")
partC(15)
partC(20)
partC(50)
partC(100)

Output
% python test_fraction.py
Part A:
x.getNum(): -4
x.getDen(): 11
u != v: True
u <  v: True
u <= v: True
u == v: False
u > v: False
u >= v: False
x != y: True
x <  y: False
x <= y: False
x == y: False
x >  y: True
x >= y: True
u + v: 7/6
u - v: -1/6
w + x: 5/77
w - x: 61/77
u + y: -1/26
u - y: 27/26
x + y: -129/143
x - y: 25/143
w * x: -12/77
y * z: 14/65
w * y: -3/13
u / v: 3/4
w / x: -33/28
x / z: 10/11
y / v: -21/26
Part B:
pi1: 355/113
pi1:   3.1415929203539825
pi2: 103993/33102
pi2:   3.1415926530119025
pi3: 80143857/25510582
pi3:   3.1415926535897927

Part C:

Call C(15)
3111643512832 /
990466892415 
High precision: 15
Fr:3.14159265358689
Pi:3.14159265358979

Call C(20)
188557135970304 /
60019600489849 
High precision: 20
Fr:3.1415926535897936713
Pi:3.1415926535897932385

Call C(50)
771373182244496277073168949216840445253910528 /
245535709845474029253525527117296976467970025 
High precision: 50
Fr:3.1415926535897932384626433832795028842018664333691
Pi:3.1415926535897932384626433832795028841971693993751

Call C(100)
230472573934774707842404216444096156856954356127677523896716863794721544322478959628646350848 /
73361698777663417823509011957888573950952305745241626687452984196759740688178926126151382145 
High precision: 100
Fr:3.141592653589793238462643383279502884197169399375105820974944592307816406286233829351709883016261376
Pi:3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

(Revision date: 2014-12-15. Please use ISO 8601, the International Standard.)