I'm building a calculator that should behave more like handwritten arithmetic, so I'm writing my own Fraction class instead of using Python's built-in fraction library. I want to implement addition and multiplication between two Fraction objects, as well as between a Fraction and a regular integer. I also don't want the result to automatically reduce or simplify the fraction. How should I define the special methods for these operations, including cases where the integer appears on the left side?
1 Answer
Define __add__ and __mul__ on the class, calculate the new numerator and denominator, and return a new Fraction rather than changing either operand. For addition, use a common denominator: (a/b) + (c/d) becomes (a*d + c*b)/(b*d). For multiplication, multiply the numerators and denominators directly. You can convert an int to a Fraction inside the method. For integers on the left, such as 3 + fraction, implement __radd__ as well; it can usually delegate to __add__. Returning NotImplemented for unsupported types lets Python try the reflected operation or raise an appropriate error. For example: `def __add__(self, other):n if isinstance(other, int):n other = Fraction(other, 1)n if not isinstance(other, Fraction):n return NotImplementedn return Fraction(self.numerator * other.denominator + other.numerator * self.denominator, self.denominator * other.denominator)nndef __radd__(self, other):n return self.__add__(other)nndef __mul__(self, other):n if isinstance(other, int):n other = Fraction(other, 1)n if not isinstance(other, Fraction):n return NotImplementedn return Fraction(self.numerator * other.numerator, self.denominator * other.denominator)nndef __rmul__(self, other):n return self.__mul__(other)`. Since each operation creates a new object, the original fractions remain unchanged and no automatic simplification occurs.

That makes sense—I initially assumed the operation would modify the left-hand object, but returning a new Fraction is cleaner. I was also unsure what would happen with an expression like `3 + my_fraction`, so I’ll add the reflected methods too.