class Point(object):
''' A point on a grid at location x, y '''
def __init__(self, x, y):
self.X=x
self.Y=y
def __str__(self):
return "X=" + str(self.X), "Y=" + str(self.Y)
def __add__(self, other):
if not isinstance(other, Point):
raise TypeError("must be of type point")
x= self.X+ other.X
y= self.Y+ other.Y
return Point(x, y)
p1= Point(5, 8)
print p1 + [10, 12]
When trying to add list or tuple at RHS i.e. print p1 + [10, 12], I'm getting
attributeError: int object has no attribute
How can this problem be solved?
First of all I can't reproduce the exact error you show, but I believe that is some sort of a "typo". You are trying to add a list instance to a Point instance, while the __add__ method of the later throws the error whenever you try to add anything that is not a Point instance.
def __add__(self, other):
if not isinstance(other, Point):
raise TypeError("must be of type point")
You could possibly overcome it by adding a fair bit of polymorphism.
from collections import Sequence
class Point(object):
...
def _add(self, other):
x = self.X + other.X
y = self.Y + other.Y
return Point(x, y)
def __add__(self, other):
if isinstance(other, type(self)):
return self._add(other)
elif isinstance(other, Sequence) and len(other) == 2:
return self._add(type(self)(*other))
raise TypeError("must be of type point or a Sequence of length 2")
You may have a comma instead of a plus. Look at
def __str__(self):
return "X=" + str(self.X), "Y=" + str(self.Y)
Which should be
def __str__(self):
return "X=" + str(self.X) + ", Y=" + str(self.Y)
At least on python3 when I correct it your code runs nicely. Obviously using print(p1 + Point(10,12)).
Related
I am trying to perform the following task :
For two points (𝑥1,𝑦1)+(𝑥2,𝑦2)=(𝑥1+𝑥2,𝑦1+𝑦2)
I have this code executed :
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Point({0}, {1})".format(self.x, self.y)
def __add__(self, other):
return [self.x + other.x, self.y + other.y]
def __sub__(self, other):
return [self.x - other.x, self.y - other.y]
when I try to run the following piece of code, it says:
from functools import reduce
def add_sub_results(points):
points = [Point(*point) for point in points]
return [str(reduce(lambda x, y: x + y, points)),
str(reduce(lambda x, y: x - y, points))]
it returns
return [str(reduce(lambda x, y: x + y, points)),
5 str(reduce(lambda x, y: x - y, points))]
6
TypeError: can only concatenate list (not "Point") to list
how can I solve this?
I think your __add__() and __sub__() methods of your Point class should be:
class Point(object):
...
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y) #<-- MODIFIED THIS
def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y) #<-- MODIFIED THIS
So the task is to make a universal Vector class to perform add method whatever(str or int) the x,y values are.
So here is the code that i've tried to execute just to check if try,except somehow works inside a class
class Vector():
def __init__(self,x,y):
self.x = x
self.y = y
def __valuecheck__(self):
try:
self.x + "a"
except TypeError:
return str(self.x)
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __repr__(self):
return "Vector({},{})".format(self.x,self.y)
a = Vector(1,"a")
b = Vector("a",2)
c = a.__add__(b)
print(c)
The expected output is
Vector(1a,a2)
I've tried different variants, defining classic function e.g. def valuecheck(), as well tried adding try,except to add and init method, but none seem to work. Need your help guys, any tip is very appreciated!
Cheers!
I think I have found the answer.
class Vector():
def __init__(self,x,y):
self.x = x
self.y = y
def __valuecheck__(self):
try:
self.x + "a"
except TypeError:
return str(self.x)
def __repr__(self):
return "Vector({},{})".format(self.x,self.y)
def __add__(self, other):
mvbh = str(self.x), str(self.y) # My Vector Before Hand
myVector = ''.join(mvbh)
ovbh = str(other.x), str(other.y) # Other Vector Before Hand
otherVector = ''.join(ovbh)
final = "Vector({}, {})".format(myVector, otherVector) # Change this to create a new vector
print(final)
a = Vector(1,"a")
b = Vector("a",2)
a.__add__(b)
class Vector():
def __init__(self,x,y):
self.x = x
self.y = y
def __valuecheck__(self):
try:
self.x + "a"
except TypeError:
return str(self.x)
def __add__(self, other):
return Vector(str(self.x) + str(other.x), str(self.y) + str(other.y))
def __repr__(self):
return "Vector({},{})".format(self.x,self.y)
a = Vector(1,"a")
b = Vector("a",2)
c = a.__add__(b)
print(c)
The problem is to implement scalar and inner product in the vector class in Python. Here is the code:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'Point(%s, %s)' % (self.x, self.y)
def __mul__(self,other):
x, y = self.x*other.x, self.y*other.y
return self.__class__(x,y)
def __rmul__(self,other):
x,y = other*self.x,other*self.y
return self.__class__(x,y)
def __add__(self,other):
x,y = self.x + other.x, self.y + other.y
return self.__class__(x, y)
def __sub__(self,other):
x,y = self.x - other.x, self.y - other.y
return self.__class__(x, y)
With inner product it works great, but with scalar multiplication(like if I call Point(3,2)*2) it gives the following error:
AttributeError: 'int' object has no attribute 'x'.
How do I fix this?
Look carefully at your __mul__ method:
def __mul__(self,other):
x, y = self.x*other.x, self.y*other.y
return self.__class__(x,y)
When you're trying to multiply a Point and an int, you're passing the int as the second argument (to the other parameter) to Point.__mul__. Then your method will try to access other.x and other.y, and an int doesn't have these attributes:
You can manually check for the type of other and decide whether you should be doing scalar or vector product:
def __mul__(self,other):
if isinstance(other, Point):
x, y = self.x*other.x, self.y*other.y
return self.__class__(x,y)
elif isinstance(other, (int, float, complex)):
x, y = other * self.x, other * self.y
return self.__class__(x, y)
else:
raise TypeError
def __rmul__(self, other):
return self * other
Also, the way you're doing multiplication is strange. A dot product of two vectors should be a number, not a vector.
https://en.wikipedia.org/wiki/Dot_product
You need to add a check for the type of other, it can be a Point instance or other
Here the code for __mul__
def __mul__(self, other):
if isinstance(other, Point):
return Point(self.x * other.x, self.y * other.y) # Point * Point
return Point(self.x * other, self.y * other) # Point * othertype
def __rmul__(self, other):
return Point(self.x * other, self.y * other) # othertype * Point
I've got a lesson doubt. Here is the objective from the class exercise:
Objective: Define a Python class V2, which represents two-dimensional vectors and supports the following operations:
Create a new vector out of two real numbers: v = V2(1.1, 2.2)
Convert a vector to a string (with the __str__ method)
Access the components (with the getX and getY methods)
Add two V2s to get a new V2 (with add and __add__ methods)
Multiply a V2 by a scalar (real or int) and return a new V2 (with the mul
and __mul__ methods)
Further information is given here:
Step 3. Define the add and mul methods, so that you get the following behavior:
>>> a = V2(1.0, 2.0)
>>> b = V2(2.2, 3.3)
>>> print a.add(b)
V2[3.2, 5.3]
>>> print a.mul(2)
V2[2.0, 4.0]
>>> print a.add(b).mul(-1)
V2[-3.2, -5.3]
Here is what I've been able to code:
class V2:
def __init__(self, x, y):
self.vector = [x, y]
self.x = x
self.y = y
def __str__(self):
return 'V2[' + str(self.x) + ', ' + str(self.y) + ']'
def __add__(self, other):
return 'V2[' + str(self.x + other.x) + ', ' + str(self.y + other.y) + ']'
def add(self, other):
return 'V2[' + str(self.x + other.x) + ', ' + str(self.y + other.y) + ']'
def __mul__(self, y):
return 'V2[' + str(self.x * y) + ', ' + str(self.y * y) + ']'
def mul(self, y):
return 'V2[' + str(self.x * y) + ', ' + str(self.y * y) + ']'
def getX(self):
return self.x
def getY(self):
return self.y
My question is how can I get print a.add(b)mul(-1) right? When I try to run this:
>>> p1 = V2(3, 2)
>>> p2 = V2(2, 3)
>>> p1.add(p2).mul(-1)
This error shows:
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
p1.add(p2).mul(-1)
AttributeError: 'str' object has no attribute 'mul'
I think I understand the error but I can't come up with a different way to do the add and mul methods without messing up other methods.
You need to create another instance of your class instead of a string:
def __add__(self, v):
return self.__class__(self.x + v.x, self.y + v.y)
def __mul__(self, n):
return self.__class__(self.x * n, self.y * n)
You can then use def add(self, v): return self + v. You might switch those, so that add() is the main method, and __add__ calls add.
The issue is that in each of your methods you are returning a string. You can't do any arithmetic with a string.Currently, your add method returns a string which then you call mul on (e.g. "[v1 3 4]".mul).
Change your add and mult method to the following where you return a V2.
def __add__(self, other):
return V2(self.x + other.x,self.y * other.y)
def __mul__(self, ascalar):
return V2(self.x * ascalar, self.y * ascalar)
In your methods, you are returning strings, instead of new instances of V2. So it should be:
class V2:
def __init__(self, x, y):
self.vector = [x, y]
self.x = x
self.y = y
def __str__(self):
return 'V2[' + str(self.x) + ', ' + str(self.y) + ']'
def __add__(self, other):
return V2(self.x + other.x, self.y + other.y)
def __mul__(self, c):
return V2(self.x * c ,self.y * c)
def getX(self):
return self.x
def getY(self):
return self.y
I'm trying to create a class that will allow me to add/multiply/divide objects of the same class together or add/multiply numeric arguments to each member of the class
So my class is for coordinates (I am aware there are great packages out there that do everything I want better than I could ever hope to on my own, but now I'm just curious).
class GpsPoint(object):
"""A class for representing gps coordinates"""
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
def __radd__(self, other):
return GpsPoint(self.x + other, self.y + other, self.z + other)
def __str__(self):
return "%d, %d, %d" % (self.x, self.y, self.z)
This was my original attempt. I found it worked, but only if I used a numeric argument first
>>foo = GpsPoint(1,2,3)
>>print 5 + foo
6, 7, 8
>>print foo + 5
AttributeError: 'int' object has no attribute 'x'
So, what is the pythonic way to do this, is there a pythonic way, is this just silly? I see what the philosophical problem is with using isinstance() and I know I could toss in a try except block I'm just curious how I should go about this.
The "Pythonic" way is to "ask forgiveness rather than permission" - that is, instead of checking the type beforehand, try to add and, if it fails, catch the exception and deal with it, like so:
class GpsPoint(object):
"""A class for representing gps coordinates"""
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
try:
return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
except AttributeError:
return GpsPoint(self.x + other, self.y + other, self.z + other)
def __radd__(self, other):
try:
return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
except AttributeError:
return GpsPoint(self.x + other, self.y + other, self.z + other)
def __str__(self):
return "%d, %d, %d" % (self.x, self.y, self.z)
You are going to have to try to determine what type other is, at least to the extent that it's compatible with GpsPoint. If you can't figure it out then just return NotImplemented and the interpreter will try to handle it from there.
Short answer: use isinstance().
There is no other way to dermine the type of "other" in your methods. Also, if you check the sources of many python libraries you will find that there are lots of places where isinstance() is used. So this is just the state of art in python:-).