cqstack
cqstack

Reputation: 155

Creating a rational class and operator overloading in python

I'm defining rational class, so for example a = Rational(1,2) #1/2, and b = Rational(2,3) #2/3, and I want to have c = a + b so that c = Rational(7,6) #7/6. My code so far is:

class Rational(object):
    def __init__(self, v1, v2):
        self.value = v1/v2
    def  __add__(self, value2):
        return Rational(self.value + value2.value)
a = Rational(1,2)
b = Rational(2,3)
c = a+b

But I get the TypeError message that init requires 3 arguments (2 given), where did it get wrong in the coding above pls? Thank you!

Upvotes: 1

Views: 2573

Answers (2)

Abdullah Rafiq
Abdullah Rafiq

Reputation: 209

class RationalNumber:
    numerator=1
    denominator=1
    lcm=1
    def __init__(self,numerator,denominator):
        if(denominator<=0):
            print('Denominator can not be <=0')
        else:
            gcd=1
            divisorsOfNum1 = []
            divisorsOfNum2 = []
            gotlcm=False
            for i in range(1, int(numerator)+1):
                if numerator % i == 0:
                    divisorsOfNum1.append(i)
            for i in range(1, int(denominator)+1):
                if denominator % i == 0:
                    divisorsOfNum2.append(i)
            for i in range(0, len(divisorsOfNum1)):
                for j in range(0, len(divisorsOfNum2)):
                    if divisorsOfNum1[i] == divisorsOfNum2[j]:
                        if(gotlcm==False):
                            gotlcm=True
                            self.lcm=divisorsOfNum1[i]
                        gcd = divisorsOfNum1[i]
                        continue
            self.numerator=numerator/gcd
            self.denominator=denominator/gcd
            print(self.numerator,self.denominator)
    def __add__(self,other):
       numeratr=self.numerator*other.denominator + other.numerator*self.denominator
       denominatr=self.denominator*other.denominator
       return RationalNumber(numeratr,denominatr)
    def __sub__(self,other):
       numeratr=self.numerator*other.denominator - other.numerator*self.denominator
       denominatr=self.denominator*other.denominator
       return RationalNumber(numeratr,denominatr)
    def __truediv__(self,other):
       numeratr=self.numerator*other.denominator  
       denominatr=other.numerator*self.denominator
       return RationalNumber(numeratr,denominatr)
    def __mul__(self,other):
        numeratr=self.numerator*other.numerator  
        denominatr=other.denominator*self.denominator
        return RationalNumber(numeratr,denominatr)
    def __ne__(self,other):
        if self.numerator!=other.numerator  and other.denominator!=self.denominator:
            return True
        else:  
            return False
    def __eq__(self,other):
        if self.numerator==other.numerator  and other.denominator==self.denominator:
            return True
        else:  
            return False
    def __gt__(self,other):
        if (self.numerator/self.denominator)>(other.numerator/other.denominator):
            return True
        else:  
            return False
    def __lt__(self,other):
        if (self.numerator/self.denominator)<(other.numerator/other.denominator):
            return True
        else:  
            return False
    def __ge__(self,other):
        if (self.numerator/self.denominator)>=(other.numerator/other.denominator):
            return True
        else:  
            return False
    def __le__(self,other):
        if (self.numerator/self.denominator)<=(other.numerator/other.denominator):
            return True
        else:  
            return False
r1=RationalNumber(48,36)
r2=RationalNumber(48,36)
print(r1+r2)

you can perform addition, subtraction, multiplication, division, relational and equality operations

Upvotes: 3

Tim
Tim

Reputation: 2049

According to your class, you create an instance of Rational by passing the numerator and denominator to it, but here you're trying to create one just by passing its (floating-point) value. Of course, it's possible to find a rational equivalent to a float, but you haven't taught your class how to do it, and it's not going to magically reverse-engineer itself.

Given the definition of adding fractions: p/q + r/s = (ps + qr) / qs, your addition function should return Rational(ps + qr, qs). The problem is, you haven't kept track of your numerator and denominator in your class, so you have no way of retrieving this information.

As things stand, the best you can do with your addition function is return a self.value + value2.value as a float. So as it stands, your class is basically a long-winded way to do division! To have a meaningful Rational class, I would strongly suggest you keep everything in terms of the numerator and denominator as far as possible.


Edit: I forgot to mention - if you're using Python 2.x your division won't work as it should unless you either convert one (or both) of v1 or v2 to float before doing division, or better still, include the line from __future__ import division at the top, so that division behaves as you'd expect.

Upvotes: 0

Related Questions