In: Computer Science
A negative Rational could either be represented by a negative value stored in __numerator or a negative value stored in __denominator. If negative values are stored in both, the reduce() method that is provided for you will make them both positive.
If a Rational happens to reduce to a whole number, it will still be saved in Rational form. In other words, if the result of an add() call creates a fraction 6/2, it should reduce to 3/1 but will remain 3/1 rather than turning into 3.
Before moving into the methods that you will create, here is a quick overview of methods that are provided for you (don't change the functionality of these methods):
__init__(self, iNum, iDen): Initializes a new Rational object with value iNum/iDen stored in hidden __numerator and __denominator variables. These are the only instance variables that you should need to define as a part of your Rational class. This method also calls the reduce() method, described next.
reduce(self): Reduces a Rational object to its lowest terms, e.g., 2/4 is reduced to 1/2. If both the numerator and denominator are negative, this method makes them both positive. After that, it repeatedly calls the gcf() method (defined next) to find common factors between the numerator and denominator, which are used to reduce the Rational.
gcf(self): Determines the greatest common factor between the numerator and denominator. When it finds a number divisible by both, it breaks the search loop and returns that number. The smallest factor that can be returned is 1.
__str__(self): Returns a string representation of the Rational object, e.g., "1/8". This is a "dunder" method that will be useful for you in debugging. You can call print(r1) on Rational object r1 to use this method.
__eq__(self, r2): Determines if two Rationals are exactly equal to each other (same numerator and same denominator, no consideration of reducing the numbers). This method is necessary for the grading code, but you can also use it to test your methods by checking r1==r2 for Rational objects r1 and r2.
Next, the methods that you will write. In the method descriptions and usage cases below, you can assume that r1 and r2 are Rational objects with __numerator and __denominator instance variables initialized with values.
Accessors and mutators: You should create accessors and mutators (or "getters" and "setters") for both the __numerator and __denominator instance variables. There are thus four required methods here: getNumerator(self), getDenominator(self), setNumerator(self, n), and setDenominator(self, d). Additionally, the mutators should call the reduce() method to put the updated Rational in lowest terms, e.g., calling setDenominator(4) on the Rational 2/7 should update the Rational to 2/4 and then reduce it to 1/2. Only the accessors should return a value.Usage: n = r1.getNumerator(). If r1 is 3/4, returns 3.Usage: d = r1.getDenominator(). If r1 is 3/4, returns 4. Usage: r1.setNumerator(7) If r1 is 3/14, updates r1 to 7/14 and then reduces to ½. Usage: r1.setDenominator(-4). If r1 is 3/4, updates r1 to 3/-4
isValid(self): Rational numbers cannot have a 0 in the denominator. This method should return True if the Rational is valid, and should return False if the Rational has a 0 denominator. Usage: val = r1.isValid(). If r1 is 7/4, returns True. If r1 is -7/0, returns False
add(self, num2): Given input Rational num2, you should add num2 to the current Rational, updating the self.__numerator and self.__denominator instance variables to the sum of self and num2. You should also call the reduce() method to put the Rational in lowest terms. Nothing is returned by this method. Usage: r1.add(r2). If r1 is 1/4 and r2 is 1/8, updates r1 to ⅜. sub(self, num2): Same as the add() method, but subtracting num2 from self. Usage: r1.sub(r2). If r1 is 1/4 and r2 is 1/8, updates r1 to ⅛. mult(self, num2): Same as the add() method, but multiplying num2 by self. Usage: r1.mult(r2). If r1 is 1/4 and r2 is 1/8, updates r1 to 1/32
div(self, num2): Same as the add() method, but dividing num2 out of self. Usage: r1.div(r2). If r1 is 1/4 and r2 is 1/8, updates r1 to 2/1.
Raw_code:
class Rational:
__numerator = None
__denominator = None
def __init__(self, iNum, iDen):
# __numerator is list of orignal numerator and reduced
numerator
# and similarly __denominator also
self.__numerator = [iNum, iNum]
self.__denominator = [iDen, iDen]
self.reduce()
def reduce(self):
if self.__numerator[0] < 0 and self.__denominator[0] <
0:
self.__numerator[0] *= -1
self.__denominator[0] *= -1
factor = self.gcf()
self.__numerator[1] = (int(self.__numerator[0]/factor))
self.__denominator[1] = (int(self.__denominator[0]/factor))
def gcf(self):
if self.__numerator[0] < self.__denominator[0]:
last = self.__numerator[0]
else:
last = self.__denominator[0]
for number in range(last, 1, -1):
if (self.__numerator[0] % number == 0
and self.__denominator[0] % number == 0):
return number
return 1
def __str__(self):
return str(self.__numerator[1]) + "/" +
str(self.__denominator[1])
def __eq__(self, r2):
if (self.__numerator[0] == r2.__numerator[0] and
self.__denominator[0] == r2.__denominator[0]):
return True
else:
return False
def getNumerator(self):
return self.__numerator[1]
def getDenominator(self):
return self.__denominator[1]
def setNumerator(self, n):
self.__numerator[0] = n
self.reduce()
def setDenominator(self, d):
self.__denominator[0] = d
self.reduce()
def isValid(self):
if self.__denominator[1] == 0:
return False
else:
return True
def add(self, num2):
if isinstance(num2, self.__class__):
self.__numerator[0] = (self.__numerator[1] *
num2.__denominator[1]
+ self.__denominator[1] * num2.__numerator[1])
self.__denominator[0] = (self.__denominator[1] *
num2.__denominator[1])
self.reduce()
def sub(self, num2):
if isinstance(num2, self.__class__):
self.__numerator[0] = (self.__numerator[1] *
num2.__denominator[1]
- self.__denominator[1] * num2.__numerator[1])
self.__denominator[0] = (self.__denominator[1] *
num2.__denominator[1])
self.reduce()
def mult(self, num2):
if isinstance(num2, self.__class__):
self.__numerator[0] = (self.__numerator[1] *
num2.__numerator[1])
self.__denominator[0] = (self.__denominator[1] *
num2.__denominator[1])
self.reduce()
def div(self, num2):
if isinstance(num2, self.__class__):
self.__numerator[0] = (self.__numerator[1] *
num2.__denominator[1])
self.__denominator[0] = (self.__denominator[1] *
num2.__numerator[1])
self.reduce()
r1 = Rational(1, 4)
print("Rational 1 is: ", r1)
r2 = Rational(1, 8)
print("Rational 2 is: ", r2)
r1.add(r2)
print("Rational 1 after adding Rational 2 : ", r1)
print()
r3 = Rational(1, 4)
print("Rational 3 is: ", r3)
r4 = Rational(1, 8)
print("Rational 4 is: ", r4)
r3.sub(r4)
print("Rational 3 after subtracting Rational 4 : ", r3)
print()
r5 = Rational(1, 4)
print("Rational 5 is: ", r5)
r6 = Rational(1, 8)
print("Rational 6 is: ", r6)
r5.mult(r6)
print("Rational 5 after subtracting Rational 6 : ", r5)
print()
r7 = Rational(1, 4)
print("Rational 7 is: ", r7)
r8 = Rational(1, 8)
print("Rational 8 is: ", r8)
r7.div(r8)
print("Rational 7 after subtracting Rational 7 : ", r7)
print()
r9 = Rational(2, 4)
print("Rational 9 is: 2/4")
r10 = Rational(3, 6)
print("Rational 10 is : 3/6")
print("Comparing Rational 9 and Rational 10 :", (r9 ==
r10))