Did you find the redundant line of code in the previous lesson? Just in case you did not, it was line 22. We were asking Python to simplify two integers before returning a new Fraction object. However, in calling Fraction(), we automatically ask Python to simplify [line 10] the arguments. We want to keep line 10, as it gives the required result for our test on line 43; so, we can eliminate the call to simplify() on line 22.
Now, we are ready to add a division method. To divide two fractions, we multiply the first fraction by the multiplicative inverse of the second; Something like this:
1 3 1 4 4 2 - / - = - * - = - = - 2 4 2 3 6 3
The multiplicative inverse of a fraction is obtained by interchanging the numerator with the denominator ("flipping" the fraction upside down). Let's see how we do that with Python.
To tell Python to understand that the using the symbol "/" between two fractions means that we want to divide these two fractions, we make the appropriate definition for the function __div__(). Here are the relevant parts of our new code:
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 24 def __div__(self, other): 25 num = self.num * other.denom 26 denom = self.denom * other.num 27 return Fraction(num, denom) 38 if __name__ == "__main__": 39 a = Fraction(1, 2) 40 b = Fraction(3, 1) 41 assert str(a) == "(1/2)" 42 assert str(b) == "(3)" 43 assert str(a*b) == "(3/2)" 44 c = Fraction(1, 3) 45 assert str(b*c) == "(1)" 46 d = Fraction(5, 10) 47 assert str(d) == "(1/2)" 48 print a/b 49 print a/a
The result is
(1/6) (1)
as desired. All we need to do is convert the print statements [lines 48 and 49] into assert statements and we are ready to continue.
The next thing we want to do is add and substract fractions. We will start with the addition. However, this time we will proceed differently: we will first start by using assert to express results that we would expect, if Python knew how to add two fractions. Of course, it will fail by raising an exception. We will then go back, write the code required to make the tests work.
This approach is known as Test driven development. It is a modern way to used to write computer programs and is getting more and more popular as it really helps to prevent bugs.
38 if __name__ == "__main__": 39 a = Fraction(1, 2) 40 b = Fraction(3, 1) 41 assert str(a) == "(1/2)" 42 assert str(b) == "(3)" 43 assert str(a*b) == "(3/2)" 44 c = Fraction(1, 3) 45 assert str(b*c) == "(1)" 46 d = Fraction(5, 10) 47 assert str(d) == "(1/2)" 48 assert str(a/b) == "(1/6)" 49 assert str(a/a) == "(1)" 50 assert str(a+a) == "(1)" 51 assert str(b+b) == "(6)" 52 assert str(a+b) == "(7/2)" 53 assert str(c+c) == "(2/3)"
And here's the required addition to the class Fraction:
29 def __add__(self, other): 30 denom = self.denom * other.denom 31 num = self.num*other.denom + self.denom*other.num 32 return Fraction(num, denom)
Try it!
You now should be able to make Python subtract two fractions. Use __sub__(), and check your results!
Before going on to the next lesson, try the following:
one = Fraction(1)
print one + 1