0

I am trying to override the __iadd__ method in python with fractions, now this is what I did. Please could some one check to see if I did it right. I have this and this, but that's not what I want. It should be used from a class perspective.

My __iadd__ code:

def __iadd__(self, other):
    """
    Implementation of the '+='
    augmented function
    :param other:
    :return:
    """       
    newnum = self.num * other.den + self.den * other.num
    newden = self.den * other.den

    v = Fraction(newnum, newden)

    return v

This is done in a class Fractionwith this structure:

def gcd(m, n):
    while m % n != 0:
        oldm = m
        oldn = n

        m = oldn
        n = oldm % oldn
    return n


class Fraction:
    # initializing variables for class
    def __init__(self, top, bottom):

        # check if entered fraction is an integer
        if isinstance(top, int) and isinstance(bottom, int):
            # reduce the given fractions to lowest term
            common = gcd(top, bottom)

            self.num = abs(top) // common
            self.den = abs(bottom) // common
        else:
            raise "Please only integers are allowed"

    def __str__(self):
        return str(self.num) + "/" + str(self.den)

This actually return the write value when done like this:

f1 = Fraction(1, 2)
f2 = Fraction(8, 10) 
f1 += f2
print(f1)

Also did it by calling an overridden __add__ method:

def __iadd__(self, other):
    """
    Implementation of the '+='
    augmented function
    :param other:
    :return:
    """
    if other == 0:
        return self
    else:
        return self.__add__(other)

The overridden __add__:

def __add__(self, otherfraction):
    newnum = self.num * otherfraction.den + self.den *     otherfraction.num
    newden = self.den * otherfraction.den

    return Fraction(newnum, newden)
George Udosen
  • 906
  • 1
  • 13
  • 28

1 Answers1

3
  • Use __iadd__ to increment in-place.
  • Use __add__ to increment and create a new instance.

So, you can change your code as follow.

def __iadd__(self, other):
    self.num = self.num * other.den + self.den * other.num
    self.den = self.den * other.den
    return self

See also this question: implementing add and iadd for custom class in python?

Note that Python has a Rational numbers module. Check the source code… But Fraction objects are immutable, so __iadd__ is not implemented.

Community
  • 1
  • 1
Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103
  • Tried it doesn't return the right answer. From what I read [there](https://stackoverflow.com/questions/20204230/implementing-add-and-iadd-for-custom-class-in-python) we can either return `self` or `not` – George Udosen Aug 17 '16 at 07:10
  • @udoyen I wrote a small Fraction class using the above `__iadd__` method and it does work. What do you mean by _it doesn't return the right answer_? – pschill Aug 17 '16 at 07:20
  • with that `code` and this `f1 = Fraction(1, 2), f2 = Fraction(8, 10), f1 += f2 print(f1)`. It returns `1/2` the fraction in `f1` rather than `13/10`. – George Udosen Aug 17 '16 at 07:39
  • @udoyen I used the numbers in your example (1/2, 8/10). The result is 26/20. See http://pythonfiddle.com/fractions/ – pschill Aug 17 '16 at 08:24
  • My bad pschill, Laurent, I missed the variable `self.num` and `self.den` – George Udosen Aug 17 '16 at 08:48
  • I am implementing this in an assignment as a python student, so need the best possible application method, +1. Thanks Laurent and pschill – George Udosen Aug 17 '16 at 08:50