Assignment 5: Worth 12% of the Homework grade Due: Monday, July 20th at 11:59 pm To turnin program 5 (rat.py) from lectura, type % turnin 380assignment5 rat.py 1. The object of this assignment is to become familiar with Python classes. You will be writing a class called Rational which implements "infinite precision" rational numbers in Python. For example: % python >> from rat import * >> a = Rational(3,4) # 3 is the numerator, 4 is the denominator >> print a 3/4 >> b = Rational(4,4) >> print b # Notice it prints in fully reduced form 1/1 >> c = a + b >> print c 7/4 # Your class supports addition >> d = Rational(111111111111, 222222222222) >> print d 1/1 # Using infinite integers for both num and den Notice that the Rationals are always printed in fully reduced form. Internally, they should be represented that way as well. The class should support the standard operations: +,-,*,/ >>> a = Rational(3,4) >>> b = Rational(3,4) >>> a + b rat.Rational(3,2) >>> print a + b 3/2 >>> print a - b 0/1 >>> print a * b 9/16 >>> print a/b 1/1 The class should also support <, <=, >, >=, ==, != and cmp >>> a = Rational(-1, 2) >>> b = Rational(1,2) >>> a < b True >>> a <= b True >>> a > b False >>> a >= b False >>> cmp(a,b) -1 >>> a != b True >>> a is b False The class should return a "repr" string as many standard Python classes do: "rat.Rational(x,y)" (see examples below), where rat is the module, and Rational is the class in the module. This is reminiscent of how they are constructed. If the denominator is ever 0, then the representation will always be 1/0 (our infinity). Any mathematical operation (+,-,*,/) with 1/0 results in 1/0. Two infinities are considered equal. >>> a = Rational(1,0) >>> b = Rational(2,3) >>> a+b rat.Rational(1,0) >>> a*b rat.Rational(1,0) >>> a/b rat.Rational(1,0) >>> a==b False >>> inf1 = Rational(1,0) >>> inf2 = Rational(2,0) >>> print inf1 == inf1 True >>> inf1 < inf2 False Be careful with the sign. If a Rational is negative, it should always be associated with the numerator. >>> a = Rational(-1, -2) >>> print a 1/2 >>> repr(a) 'rat.Rational(1,2)' >>> b = Rational(3,-4) >>> print b -3/4 >>> repr(b) 'rat.Rational(-3,4)' >>> a + b rat.Rational(-1,4) Your class should work well with other basic types, namely longs, floats and ints. In particular, you should support the following: >>> a = Rational(12) # Construct, num implictly 1 >>> print a 12/1 >>> b = Rational(1.5) # Drop fractional part >>> print b 1/1 >>> c = Rational(3.6) # ...don't round, just drop >>> print c 3/1 >>> d = Rational(3,4) >>> print d 3/4 >>> d * 12 # In lhs*rhs, rhs can be float, int, long or rat.Rational(9,1) # a Rational >>> 12 * d Traceback (most recent call last): File "", line 1, in ? TypeError: unsupported operand type(s) for *: 'int' and 'Rational' So, your class should work well with longs, ints, floats and Rationals if a Rational is on the left hand side. All +,-,*,/ should support ints, longs, floats, Rationals on the right hand side. >>> a = Rational(1,2) >>> a + 2 rat.Rational(5,2) >>> a - 1.0 rat.Rational(-1,2) >>> a / 2L rat.Rational(1,4) >>> a * 17 rat.Rational(17,2) Some other miscellany: Your class should stay ints as long as possible, until it has to be a long. >>> import sys >>> a = Rational(sys.maxint) >>> print a 9223372036854775807/1 >>> repr(a) 'rat.Rational(9223372036854775807,1)' >>> a = a + 1 >>> print a 9223372036854775808/1 >>> repr(a) 'rat.Rational(9223372036854775808L,1)' As always, document your class well, using docstrings and make sure help works for your class. We aren't requiring a particular format for help, but we are definitely going to be looking for one, as well as commenting and code style.