turkadactyl - 1 year ago 115
Python Question

# Multiplying Fractions and Integers in Python

I'm trying to build a rational numbers class that will perform various arithmetic functions based on input values without using the

`fractions`
module. When I'm using two different fractions the code works fine, but as soon as I try to use an integer I'm getting errors in earlier class functions and am unsure why. What I'm trying to implement at this point is, again, adding an integer to a rational number (e.g.,
`print Rational(1,2) * 3`
).

I've included the code that I have thus far below - the problematic operation is
`__radd__`
, though when this is included in my code I receive an attribute error for
`__add__`
(this error does not show up until this new operation is included). I'm guessing the problem comes from still having the 2nd
`__radd__`
parameter as other (assuming a different case of the Rational class?), but am unsure how to proceed.

Edit: I'm using Python 2.7. The error from a sample run is included below the code.

``````def gcd(a, b):
if b == 0:
return a
else:
return gcd(b, a%b)
class Rational:
def __init__(self, nom, denom):
if denom == 0:
raise ZeroDivisionError, ("Cannot divide by zero!")
else:
self.reduce = gcd(nom, denom)
self.nom = nom / self.reduce
self.denom = denom / self.reduce
return Rational(self.nom*other.denom+other.nom*self.denom, self.denom*other.denom)
def __sub__ (self, other):
return Rational(self.nom * other.denom - other.nom * self.denom,self.denom * other.denom)
def __mul__ (self, other):
return Rational(self.nom * other.nom, self.denom * other.denom)
def __div__ (self, other):
return Rational(self.nom * other.denom, self.denom * other.nom)
return Rational(self.nom*1+other*self.denom, self.denom*1)
def __str__ (self):
return str(self.nom) + "/" + str(self.denom)
``````

# Sample error

``````print Rational(1,2) + 1

AttributeError                            Traceback (most recent call last)
<ipython-input-201-1ccb1fc0dfef> in <module>()
----> 1 print Rational(1,2) + 1

13             self.denom = denom / self.reduce
---> 15         return Rational(self.nom*other.denom+other.nom*self.denom, self.denom*other.denom)
16     def __sub__ (self, other):
17         return Rational(self.nom * other.denom - other.nom * self.denom,self.denom * other.denom)

AttributeError: 'int' object has no attribute 'denom'
``````

When Python see `Rational` on left side of `+` then it uses `__and__` but if there is no `Rational` on left size but it is on right side then Python use `__radd__`. (`r` in name `__radd__` means `right`)

In `__add__` you use `other.nom` and `other.denom` which doesn't exists in `int` so `Rational(1,2) + 1` doesn't work.

`1 + Rational(1,2)` works because in `__radd__` you use `other` instead of `other.nom` and `other. denom`

You can use `isinstance(other, int)` to recognize `int` and make different calculation in `__add__` and it will works with `Rational+int` and `Rational+Rational`

``````def __add__ (self, other):
if isinstance(other, int):
# Rational + int
return Rational(self.nom*1+other*self.denom, self.denom*1)
else:
# Rational + Rational
return Rational(self.nom*other.denom+other.nom*self.denom, self.denom*other.denom)

# ----

print(Rational(1,2) + 1)
print(Rational(1,2) + Rational(1,2))
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download