As you should have checked at the end of the previous lesson, Python does not know how to add an integer to a Fraction. We can correct that easily enough by doing the following:
The second step can be accomplished with a function like the following:
def convertToFraction(object): '''Converts "int" and "long" to Fractions''' if type(object) in (int, long): return Fraction(object) else: raise NotImplementedError
We first check if the object is an integer [int or perhaps long] and, if so, create a new Fraction from it (the integer will be the numerator of the new Fraction). Since we want fractions to be of the form (integer/integer), we will not allow any other kind of object; by raising an exception, we inform the user that the attempted operation is not permitted.
The first step will be something that we will add at the beginning of every operation. Here's the new code that does just that. [Note that we included the conversion to Fractions as a method of that class.]
1 def gcd(a, b): 2 '''gcd returns the greatest common divisor 3 of given 2 integers.''' 4 while b: 5 a, b = b, a%b 6 return a 7 8 class Fraction(object): 9 def __init__(self, numerator, denominator=1): 10 num, denom = self.simplify(numerator, denominator) 11 self.num = num 12 self.denom = denom 13 14 def __str__(self): 15 if self.denom == 1: 16 return "(%s)"%self.num 17 return "(%s/%s)"%(self.num, self.denom) 18 19 def __mul__(self, other): 20 if not type(other) == Fraction: 21 other = self.convertToFraction(other) 22 num = self.num * other.num 23 denom = self.denom * other.denom 24 return Fraction(num, denom) 25 26 def __div__(self, other): 27 if not type(other) == Fraction: 28 other = self.convertToFraction(other) 29 num = self.num * other.denom 30 denom = self.denom * other.num 31 return Fraction(num, denom) 32 33 def __add__(self, other): 34 if not type(other) == Fraction: 35 other = self.convertToFraction(other) 36 denom = self.denom * other.denom 37 num = self.num*other.denom + self.denom*other.num 38 return Fraction(num, denom) 39 40 def __sub__(self, other): 41 if not type(other) == Fraction: 42 other = self.convertToFraction(other) 43 denom = self.denom * other.denom 44 num = self.num*other.denom - self.denom*other.num 45 return Fraction(num, denom) 46 47 def simplify(self, a, b): 48 '''divides two integers by their common factor.''' 49 common_factor = gcd(a, b) 50 a /= common_factor 51 b /= common_factor 52 return a, b 53 54 def convertToFraction(self, object): 55 '''Converts "int" and "long" to Fractions''' 56 if type(object) in (int, long): 57 return Fraction(object) 58 else: 59 raise NotImplementedError 60 61 #== testing area below=== 62 63 if __name__ == "__main__": 64 a = Fraction(1, 2) 65 b = Fraction(3, 1) 66 assert str(a) == "(1/2)" 67 assert str(b) == "(3)" 68 assert str(a*b) == "(3/2)" 69 c = Fraction(1, 3) 70 assert str(b*c) == "(1)" 71 d = Fraction(5, 10) 72 assert str(d) == "(1/2)" 73 assert str(a/b) == "(1/6)" 74 assert str(a/a) == "(1)" 75 assert str(a+a) == "(1)" 76 assert str(b+b) == "(6)" 77 assert str(a+b) == "(7/2)" 78 assert str(c+c) == "(2/3)" 79 assert str(a-a) == "(0)" 80 assert str(a-b) == "(-5/2)" 81 assert str(a-c) == "(1/6)" 82 assert str(a+1) == "(3/2)" 83 assert str(a*2) == "(1)" 84 assert str(b-1) == "(2)" 85 assert str(b/3) == "(1)"
If you think we are done, try the following:
one = Fraction(1)
print 1 + one
Can you think of what make this go wrong?