How can I implement __radd__ in my fraction class?
class Fraction:
def __init__(self,num,den):
self.num = num
self.den = den
def __add__(self,other):
num = self.num * other.den + other.num * self.den
den = self.den * other.den
common = self.gcf(num,den)
return Fraction(num/common , den/common)
def __iadd__(self,other):
self.num = self.num * other.den + other.num * self.den
self.den = self.den * other.den
common = self.gcf(self.num,self.den)
self.num = self.num/common
self.den = self.den/common
return self
def __radd__(self,other):
pass
Assuming from your implementation you are always adding only fractions there is no need to implement __radd__, because you already have __add__.
object.__radd__
These functions are only called if the left operand does not support the corresponding operation and the operands are of different types.
But in case you wanted it anyway, you can just swap the parameters since addition is commutative.
def __radd__(self, other):
return other + self
Related
Error:
TypeError: Fraction.__str__() missing 1 required positional argument: 'self'
Code:
class Fraction:
def __init__(self, numerator, denominator):
self.n = numerator
self.d = denominator
def __str__(self):
return f'{self.n}/{self.d}'
__repr__ = __str__()
def __add__(self, other): # adding the numbers
n = self.n * other.d + self.d * other.n
d = self.d * other.d
return Fraction(n, d) # object at 0x000001F5E5E6BEB0 memory of the location object
You are trying to call __str__ and assign its return value to __repr__. You want to assign the function itself:
__repr__ = __str__
However, __repr__ should usually return something resembling Python code that could be used to reconstruct the value, not necessarily the same value as __str__. Consider this instead:
class Fraction:
def __init__(self, numerator, denominator):
self.n = numerator
self.d = denominator
def __str__(self):
return f'{self.n}/{self.d}'
def __repr__(self):
return f'Fraction({self.n}, {self.d})'
def __add__(self, other):
n = self.n * other.d + self.d * other.n
d = self.d * other.d
return Fraction(n, d)
class Math:
def __init__(self, number):
self.number = number
def add(self, add_num):
return self.number + add_num
def sub(self, sub_num):
return self.number - sub_num
Math(5).add(5)
I get 10 as expected
But if I do Math(5).add(5).sub(3):
I get this error AttributeError: 'int' object has no attribute 'sub'
for that to work your mehtods need to return self (or a fresh instance of Math):
class Math:
def __init__(self, number):
self.number = number
def add(self, add_num):
self.number += add_num
return self
# or:
# return Math(self.number + add_num)
def sub(self, sub_num):
self.number -= sub_num
return self
# or:
# return Math(self.number - add_num)
def __str__(self):
return str(self.number)
m = Math(5).add(5).sub(3)
print(m)
# 7
the add here now behaves more like an __iadd__.
Of course.
What you do is essentially
a = Math(5) # a is a "Math" object
b = a.add(5) # b is what add() returns, i. e. an int
c = b.sub(3) # an int has no sub() method
I don't know what exactly you want to achieve: do you want add() and sub() to modify the object you are operating on? In this case, you can do
class Math:
def __init__(self, number):
self.number = number
def add(self, add_num):
self.number = self.number + add_num
return self
def sub(self, sub_num):
self.number = self.number - sub_num
return self
If you don't want that, you can do instead
class Math:
def __init__(self, number):
self.number = number
def add(self, add_num):
return Math(self.number + add_num)
def sub(self, sub_num):
return Math(self.number - sub_num)
return self
In both cases, your intended way of chaining the calls works.
The value that you return is not an object of your Math class.
You must create an object of Math whose number attribute is your computed results and return that for your code to work.
When you execute return self.number + add_num, you return an integer, not an instance of your Math class. To solve this, you can change your add method to
return Math(self.number + add_num).
I want the add method of my object Foo to return averaged summation. For the summation of just two objects it is straightforward:
class Foo():
def __init__(self, n):
self.n = n
def __add__(self, other):
return Foo((self.n + other.n)/2)
How to do this for N>2 objects? E.g. Foo(0) + Foo(1) + Foo(2) + Foo(3) should return Foo((0 + 1 + 2 + 3)/4), i.e. Foo(1.5).
========================================
Edit: Here's my solution
class Foo():
def __init__(self, n):
self.n = n
self._n = n
self._count = 1
def __add__(self, other):
out = Foo(self._n + other._n)
out._count = self._count + other._count
out.n = out.n/out._count
return out
Not the best way to get the arithmetic mean, but I needed to do it in this way. Also, this demonstrates how to do special additions of user defined objects, which return a function of the total sum of the objects. E.g. make __add__ return the square root of the sum of the objects:
class Bar():
def __init__(self, n):
self.n = n
self._n = n
def __add__(self, other):
out = Bar(self._n + other._n)
out.n = (out.n)**0.5
return out
One solution could be storing in the class TWO numbers: the average value and the number of samples:
class Foo:
def __init__(self, avg, count=1):
self.avg = avg
self.count = count
def __add__(self, other):
return Foo((self.avg*self.count + other.avg*other.count)
/
(self.count + other.count),
self.count + other.count)
Even better would be just storing the sum and compute the average only if/when requested.
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)
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.
I need to make an operators to an object and I wonder what is the best way.
for example for the operator add
can I write this in this way?
def _add_(self,other):
new=self.add(self,other)// can I write like that?
return new
thanks for the help!
You would use the python magic function __add__ to take care of the +:
Example:
class A():
def __init__(self, num):
self.num = num
def __add__(self, other):
return self.num + other
a = A(6)
>>> print a+5
11
For greater flexibility, you should also define __radd__, this is for the reverse addition case 5+a which would not work in the example above.
class A():
def __init__(self, num):
self.num = num
def __add__(self, other):
return self.num + other
def __radd__(self, other):
return self.num + other
>>> a = A(6)
>>> print 5+a
11
>>> print a+5
11
Or if you want to return as an object instead of an int, you can do it as:
class A():
def __init__(self, num):
self.num = num
def __add__(self, other):
return A(self.num + other)
a = A(5)
b = a+5
print b.num
10
print a.num
5
What has been demonstrated above is operator overloading. It overrides the built-in default methods for handling operators by letting the user define custom methods for the operators.
Here is a list you might find useful as to which operators can be overloaded