Accessing multiple instances through a function of a class - python

How to access multiple instances at same time through a function in a class?
I have learnt about parameters like other, but what if I have 3 objects and I need to access them all in the same function at the same time, how can I do that?
So here is the code I'm trying to correct:
class Vector2D:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other, other_1):
return Vector2D(self.x + other.x + other_1.x, self.y + other.y)
first = Vector2D(5, 7)
second = Vector2D(3, 9)
third = Vector2D(1, 1)
result = first + second + third
print(result.x)
print(result.y)}
It's showing the following error:
TypeError: __add__() missing 1 required positional argument: 'other_1'
How can I correct it?

Just remove the other_1 parameter:
>>> class Vector2D:
... def __init__(self, x, y):
... self.x = x
... self.y = y
... def __add__(self, other):
... return Vector2D(self.x + other.x, self.y + other.y)
...
>>> first = Vector2D(5, 7)
>>> second = Vector2D(3, 9)
>>> third = Vector2D(1, 1)
>>> result = first + second + third
>>>
>>> print(result.x)
9
>>> print(result.y)
17
The idea is that first + second + third is equivalent to (first + second) + third. Python only adds two things together at a time.

Related

finding distance between two points in python, passing inputs via two different objects

I have to write a code to find the different between two point by passing value via two objects as below.
But I am getting TypeError: init() missing 3 required positional arguments: 'x', 'y', and 'z'
class Point:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return '(point: {},{},{})'.format(self.x, self.y, self.z)
def distance(self, other):
return sqrt( (self.x-other.x)**2 + (self.y-other.y)**2 + (self.z -other.z)**2 )
p = Point()
p1 = Point(12, 3, 4)
p2 = Point(4, 5, 6)
p3 = Point(-2, -1, 4)
print(p.distance(p1,p3))
The problem comes from this line:
p = Point()
When you defined you class, you specified it has to be passed 3 parameters for it to be initialised (def __init__(self, x, y,z)).
If you still want to be able to create this Point object without having to pass those 3 parameters, you can make them optional like this :
def __init__(self, x=0, y=0, z=0):
self.x = x
self.y = y
self.z = z
This way, if you were to not specify these parameters (as you did), it will create a point with coordinates {0, 0, 0} by default.
You are not passing the required 3 arguments for p = Point()
fixed your errors
from math import sqrt
class Point:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return '(point: {},{},{})'.format(self.x, self.y, self.z)
def distance(self, other):
return sqrt( (self.x-other.x)**2 + (self.y-other.y)**2 + (self.z -other.z)**2 )
# p = Point() # not required
p1 = Point(12, 3, 4)
p2 = Point(4, 5, 6)
p3 = Point(-2, -1, 4)
print(p1.distance(p3)) # use this to find distance between p1 and any other point
# or use this
print(Point.distance(p1,p3))
class Point:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return '(point: {},{},{})'.format(self.x, self.y, self.z)
def distance(self, other):
return math.sqrt( (self.x-other.x)**2 + (self.y-other.y)**2 + (self.z -other.z)**2 )
p1 = Point(12, 3, 4)
p2 = Point(4, 5, 6)
p3 = Point(-2, -1, 4)
print(Point.distance(p1,p3))
It works like this.You should not define a P point seperate than the other three points. Every point is a seperate instance. But when you try to use the function just call the class.

Changing one line inside a method has consequences that I don't understand

Why does changing the str method affect other methods? It seems like changing the __str__method also changes the other methods that return a Point2d object.
import math
class Point2d(object):
def __init__( self, x0, y0 ):
self.x = x0
self.y = y0
def magnitude(self):
return math.sqrt(self.x**2 + self.y**2)
# 2.1
def __str__(self):
#return str((self.x, self.y))
return 'self.x, self.y'
# 2.2
def __sub__(self, other):
return Point2d(self.x - other.x, self.y - other.y)
# 2.4
def __eq__(self, other):
if self.x == other.x and self.y == other.y:
return True
p = Point2d(0,4)
q = Point2d(5,10)
r = Point2d(0,4)
leng = Point2d.magnitude(q)
print("Magnitude {:.2f}".format( leng ))
print(p.__str__(), type(p.__str__())) # 2.1
print(p-q) # 2.2
print(Point2d.__sub__(p,q)) # 2.2 same as line above (line 60).
print(p.__eq__(r))
Expected results:
Magnitude 11.18
self.x, self.y <class 'str'>
(-5, -6)
(-5, -6)
True
Actual results:
Magnitude 11.18
self.x, self.y <class 'str'>
self.x, self.y
self.x, self.y
True
When you call print(something), the __str__ method of something is called:
All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.
So your changes don't really affect every other function, they affect how they are printed. If you will launch your code in Jupyter notebook and will remove print word, you will see your Point2d object.
__str__() is a "special" method. You'll notice that
print(p.__str__())
and
print(p)
give you the same result.
Since __sub__() (and all similar functions) return their result,
print(p-q) # 2.2
is the same as
z = p - q
print(z)
which, as we said, is the same as
print(z.__str__())

'int' object has no attribute 'x'

I'm trying to make a program to add vectors using __add __:
class vects:
def __init__(self,x,y):
self.x = x
self.y = y
def __add__(self, vect):
total_x = self.x + vect.x
total_y = self.y + vect.y
return vects(total_x, total_y)
plusv1 = vects.__add__(2,5)
plusv2 = vects.__add__(1,7)
totalplus = plusv1 + plusv2
The error produced is as follows:
line 12, in <module> plusv1 = vects.__add__(2,5)
line 7, in __add__ total_x = self.x + vect.x
AttributeError: 'int' object has no attribute 'x'
You don't use __add__ like that! :-) __add__ will get implicitly invoked when + is used on an instance of the Vects class.
So, what you should first do is initialize two vector instances:
v1 = Vects(2, 5)
v2 = Vects(1, 7)
and then add them:
totalplus = v1 + v2
If you add a nice __str__ to get a nice representation of your new vector:
class Vects:
def __init__(self,x,y):
self.x = x
self.y = y
def __add__(self, vect):
total_x = self.x + vect.x
total_y = self.y + vect.y
return Vects(total_x, total_y)
def __str__(self):
return "Vector({}, {})".format(self.x, self.y)
You can get a view of totalplus by printing it:
print(totalplus)
Vector(3, 12)

Calculate a point along a line segment one unit from a end of the seg

G'day! When I know the slope and y-intercept of a line, I need to calculate an x-value that is 1 unit out from the line.
For example, if pointA = (4,5), and I set a line going from it with 0 slope (and therefore 5 as the y-intercept), then the x value I want would be 5. If the slope were undefined (vertical), then the x value would be 4. And so on.
So far, I calculate x as x = m(point[0]+1)-b. This doesn't work so well for vertical lines, however.
This and this are similar, but I can't read C# for the first, and on the second one, I don't need to eliminate any possible points (yet).
This is kind of hitting a nail with a sledge hammer, but if you're going to be running into geometry problems often, I'd either write or find a Point/Vector class like
import math
class Vector():
def __init__(self, x=0.0, y=0.0, z=0.0):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
self.x += other.x
self.y += other.y
self.z += other.z
return self
def __sub__(self, other):
self.x -= other.x
self.y -= other.y
self.z -= other.z
return self
def dot(self, other):
return self.x*other.x + self.y*other.y + self.z*other.z
def cross(self, other):
tempX = self.y*other.z - self.z*other.y
tempY = self.z*other.x - solf.x*other.z
tempZ = self.x*other.y - self.y*other.x
return Vector(tempX, tempY, tempZ)
def dist(self, other):
return math.sqrt((self.x-other.x)**2 + (self.y-other.y)**2 + (self.z-other.z)**2)
def unitVector(self):
mag = self.dist(Vector())
if mag != 0.0:
return Vector(self.x * 1.0/mag, self.y * 1.0/mag, self.z * 1.0/mag)
else:
return Vector()
def __repr__(self):
return str([self.x, self.y, self.z])
Then you can do all kinds of stuff like find the vector by subtracting two points
>>> a = Vector(4,5,0)
>>> b = Vector(5,6,0)
>>> b - a
[1, 1, 0]
Or adding an arbitrary unit vector to a point to find a new point (which is the answer to your original question)
>>> a = Vector(4,5,0)
>>> direction = Vector(10, 1, 0).unitVector()
>>> a + direction
[4.995037190209989, 5.099503719020999, 0.0]
You can add more utilities, like allowing Vector/Scalar operations for scaling, etc.

Python subtracting floats

I have the following code embeded in a class.Whenever I run distToPoint it gives the error 'unsupported operand type(s) for -: 'NoneType' and 'float'' I don't know why it's returning with NoneType and how do I get the subtraction to work?
Both self and p are supposed to be pairs.
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def distToPoint(self,p):
self.ax = self.x - p.x
self.ay = self.y - p.y
self.ac = math.sqrt(pow(self.ax,2)+pow(self.ay,2))
For sake of comparison,
import math
class Point(object):
def __init__(self, x, y):
self.x = x + 0.
self.y = y + 0.
def distToPoint(self, p):
dx = self.x - p.x
dy = self.y - p.y
return math.sqrt(dx*dx + dy*dy)
a = Point(0, 0)
b = Point(3, 4)
print a.distToPoint(b)
returns
5.0
You should check what value of p you are sending to the function, so that it has an x and y that are floats.
Old post (on second thought, I don't think you were trying to use distToPoint this way):
distToPoint doesn't return a value, this is probably the problem.

Categories