Operating with Python class and objects - python

I want to create both a Vector class and a Point class and have a function inside the Vector class that is able to add a Vector object and a Point object, but I don't understand how I have to operate with the internal variables of the classes. This is the code I have right now:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def AddVector(self, point):
point2 = Point(0, 0)
point.x + self.x = point2.x
point.y + self.y = point2.y
return point2
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Point(2,3)
v1 = Vector(4,7)
def main():
Vector.AddVector(p1,v1)
print(point2.x, point2.y)
main()

First, don't use global variables. It is a bad habit. Move them into main.
Then, the main problem, call method on the instances (p1 and v1) and not on classes (Vector and Point). Third, use the returned variable. Therefore:
def main():
p1 = Point(2,3)
v1 = Vector(4,7)
p2 = p1.AddVector(v1)
print(p2.x, p2.y)
The next problem is, this is invalid syntax:
point.x + self.x = point2.x
The correct way to assign is the other way around:
point2.x = point.x + self.x
Then, you have AddVector method on Vector. It should be on a Point and it should receive a Vector as argument.
All together:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def AddVector(self, v):
point2 = Point(0, 0)
point2.x = self.x + v.x
point2.y = self.y + v.y
return point2
def main():
p1 = Point(2,3)
v1 = Vector(4,7)
p2 = p1.AddVector(v1)
print(p2.x, p2.y)
main()
Of course, it could be nicer, this is more advanced, but here it is for completeness:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'Vector({}, {})'.format(self.x, self.y)
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, v):
return Point(self.x + v.x, self.y + v.y)
def __repr__(self):
return 'Point({}, {})'.format(self.x, self.y)
def main():
p1 = Point(2,3)
v1 = Vector(4,7)
p2 = p1 + v1
print(p2)
main()

Related

Use object from one class as attribute for another class

I am trying to make a circle which asks only for a center and radius. Here is my code:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def print_point(self):
print(f"Point: {self.x, self.y}")
class Circle:
def __init__(self, center, radius):
self.center = center
self.radius = radius
def print_circle(self):
print(f"Circle: {(self.center), self.radius}")
p1 = Point(150, 100)
c1 = Circle(p1, 75)
c1.print_circle()
What am I doing wrong?
You can assign the __repr__ method to your point class:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point: {self.x, self.y}"
class Circle:
def __init__(self, center, radius):
self.center = center
self.radius = radius
def print_circle(self):
print(f"Circle: {((self.center)), self.radius}")
p1 = Point(150, 100)
c1 = Circle(p1, 75)
c1.print_circle()
It looks like you're not actually getting any info from the class that's being passed, and just trying to print the object itself. I haven't tested this code myself but try
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def print_point(self):
print(f"Point: {self.x, self.y}")
class Circle:
def __init__(self, center, radius):
self.center = center
self.radius = radius
def print_circle(self):
print(f"Circle: {((self.center.x),(self.center.y)), self.radius}")
p1 = Point(150, 100)
c1 = Circle(p1, 75)
c1.print_circle()
or use another function that returns the string to be printed:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def print_point(self):
print(f"Point: {self.x, self.y}")
def get_point(self):
return f'Point: {self.x, self.y}'
class Circle:
def __init__(self, center, radius):
self.center = center
self.radius = radius
def print_circle(self):
print(f"Circle: {self.center.get_point()},{self.radius}")
p1 = Point(150, 100)
c1 = Circle(p1, 75)
c1.print_circle()

ID of object not being saved

I have the following class which I made:
import math
class Point:
"""Two-Dimensional Point(x, y)"""
def __init__(self, x=0, y=0):
# Initialize the Point instance
self.x = x
self.y = y
def __iter__(self):
yield self.x
yield self.y
def __add__(self, other):
addedx = self.x + other.x
addedy = self.y + other.y
return Point(addedx, addedy)
def __mul__(self, other):
mulx = self.x * other
muly = self.y * other
return Point(mulx, muly)
def __rmul__(self, other):
mulx = self.x * other
muly = self.y * other
return Point(mulx, muly)
#classmethod
def from_tuple(cls, tup):
x, y = tup
return cls(x, y)
def loc_from_tuple(self, tup):
self.x, self.y = tup
#property
def magnitude(self):
# """Return the magnitude of vector from (0,0) to self."""
return math.sqrt(self.x ** 2 + self.y ** 2)
def distance(self, self2):
return math.sqrt((self2.x - self.x) ** 2 + (self2.y - self.y) ** 2)
def __str__(self):
return 'Point at ({}, {})'.format(self.x, self.y)
def __repr__(self):
return "Point(x={},y={})".format(self.x, self.y)
I don't exactly know how to explain it but I basically want to be able to maintain a points id despite mathematical operations. For example:
point1 = Point(2, 3)
point2 = Point(4, 5)
id1 = id(point1)
point1 += point2
print(point1)
Point(x=6, y=8)
print(id1 == id(point1))
True
print(point2)
Point(x=4, y=5)
Is there a reason this doesn't happen in my code. It says False during the id part in mine.
The id is basically the memory address. If you make a new object, it will probably have a different id. If you want a mutable Point object for some reason consider the __iadd__ (and friends) methods instead, which can do the update in-place.

Move points and check specific start value, using classes python

I need to be able to move points and check a specific point value. This is the code:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def move(self)
#Here I want to move my points
Next class is a linestring. It must be able to handle x set of points
class LineString(Point):
def __init__(self, *points):
self.points = []
for point in points:
if not isinstance(point, Point):
point = Point(*point)
self.points.append(point)
def __getitem__(self):
#Here I want to inspect the value of the specific
# e.g. y value for the start point after it has been moved
I'm a bit unsure of how to get the __getitem__ to work and whether it's in the right position. Should it be under class Point? Could this be done in another way?
Edited code;
from numpy import sqrt
import math
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def dist(self, point):
return math.hypot(self.x - point.x, self.y - point.y)
def move(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy
class LineString(Point):
def __init__(self, *points):
self.points = []
for point in points:
if not isinstance(point, Point):
point = Point(*point)
self.points.append(point)
def length(self):
return sum(p1.dist(p2) for p1, p2 in zip(self.points[1:], self.points[:-1]))
def move (self, x, y):
for p in self.points:
p.move(x, y)
def __getitem__(self, key):
return self.points[key]
I think this is roughly what you want:
You don't seem to actually need a dictionary (for a line, I think a list makes more sense anyway). So the Line class is just a list of Points, and it provides a move_all_points function to translate them all. Because Line subclasses a list, you get all the standard behaviour of lists for free:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "<Point({},{})>".format(self.x, self.y)
def __str__(self):
return(repr(self))
def move(self, dx, dy):
"""Move the point by (dx, dy)."""
self.x += dx
self.y += dy
class Line(list):
"""A list of points that make up a line."""
def move_all_points(self, dx, dy):
for p in self:
p.move(dx, dy)
So then you can use them as follows:
>>> p1, p2, p3 = Point(0, 0), Point(5, 0), Point(10, 10)
>>> my_line = Line((p1, p2, ))
>>> print my_line
[<Point(0,0)>, <Point(5,0)>]
>>> my_line.append(p3)
>>> print my_line
[<Point(0,0)>, <Point(5,0)>, <Point(10,10)>]
>>> p4 = Point(100,100)
>>> my_line.move_all_points(1, 1)
>>> print my_line
[<Point(1,1)>, <Point(6,1)>, <Point(11,11)>]
>>> my_line.append(p4)
>>> print my_line
[<Point(1,1)>, <Point(6,1)>, <Point(11,11)>, <Point(100,100)>]

How can I use the class Point with 2D for 3D, Python3?

I've got a class about Points with only 2 coordinates (x,y) and I want this same class and all its methods using it with 3 coordinates, too (x,y,z) I've read about *args but i don't know how i can use it with that problem. The code:
#/usr/bin/env python3
# -*- coding: utf-8 -*-
from math import sqrt, pow, hypot, atan2, cos, sin
class Point(object):
__slots__ = ['x', 'y']
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
#del P destroy (delete) a point
class_name = self.__class__.__name__
def __add__(self, P):
S = Point(self.x, self.y)
S.x = self.x + P.x
S.y = self.y + P.y
return S
__radd__ = __add__
def __sub__(self, P):
R = Point(self.x, self.y)
R.x = self.x - P.x
R.y = self.y - P.y
return R
__rsub__ = __sub__
def __mul__(self, num):
M = Point(self.x, self.y)
M.x = num * self.x
M.y = num * self.y
return M
__rmul__ = __mul__
def __pow__(self, n):
P = Point(self.x, self.y)
P.x = self.x ** n
P.y = self.y ** n
return P
def __neg__(self):
O = Point(self.x, self.y)
O.x = - self.x
O.y = - self.y
return O
def __invert__(self):
I = Point(self.x, self.y)
I.x = 1. / self.x
I.y = 1 / self.y
return I
def dist(self, P):
return sqrt(pow(self.x - P.x, 2) + pow(self.y - P.y, 2))
def pto_medio(self, P):
Q = Point(self.x, self.y)
R = (1. / 2.) * (P + Q)
return R
def traslacion(self, tx, ty):
T = Point(self.x, self.y)
T.x = self.x + tx
T.y = self.y + ty
return T
def incentro(self, B, C):
A = Point(self.x, self.y)
a = B.dist(B)
b = A.dist(C)
c = A.dist(B)
sumd = a + b + c
A = (a / sumd) * A + (b / sumd) * B + (c / sumd) * C
return A
def rect2pol(self):
P = Point(self.x, self.y)
P.x = hypot(self.x, self.y)
P.y = atan2(self.y, self.x)
return(P)
def pol2rect(self):
P = Point(self.x, self.y)
P.x = self.x * cos(self.y)
P.y = self.x * sin(self.y)
return(P)
def entrada(self):
point = raw_input('Introduce un punto:\n')
point = point.replace('(', '')
point = point.replace(')', '')
l1 = point.rsplit(',')
self.x = float(l1[0])
self.y = float(l1[1])
l1 = []
def __repr__(self):
return('({}, {})'.format(self.x, self.y))
def main():
p = Point()
q = Point()
Point.entrada(p)
Point.entrada(q)
s = p + q
r = p - q
m = 5 * p
pol = p.rect2pol()
rect = pol.pol2rect()
print(('s = {}'.format(s)))
print(('r = {}'.format(r)))
print(('m = {}'.format(m)))
print(('p ^ 3 = {}'.format(p ** 3)))
print(('opuesto = {}'.format(- p)))
print(('inverso = {}'.format(~ p)))
print(('distancia = {}'.format(p.dist(q))))
print(('Punto Medio = {}'.format(p.pto_medio(q))))
print(('TraslaciĆ³n = {}'.format(p.traslacion(5, -2))))
print(('En Polares = {}'.format(pol)))
print(('En Rectangulares = {}'.format(rect)))
A = Point(0, 0)
B = Point(1, 0)
C = Point(1. / 2., sqrt(3.) / 2.)
I = A.incentro(B, C)
print(('Incentro = {}'.format(I)))
if __name__ == '__main__':
main()
All functions in this class I can reuse them with 3D. I don't want make a new derivative class only for 3D because I should rewrite all methods again, or make a new class for 3D points. Is it possible?
Just give your z parameter a default value of None:
class Point(object):
__slots__ = ['x', 'y', 'z']
def __init__(self, x=0, y=0, z=None):
self.x = x
self.y = y
self.z = z
then detect if z is not set to None where needed for calculations:
def __add__(self, P):
S = Point(self.x, self.y, self.z)
S.x = self.x + P.x
S.y = self.y + P.y
if self.z is not None:
if P.z is None:
raise ValueError('Cannot add a 2D point to a 3D point')
S.z = self.z + P.z
return S

Not recognizing object parameter as int

class Ball:
def __init__(self,pos,vel):
self.pos = Vector(pos.x,pos.y)
self.vel = Vector(vel.x,vel.y)
def curx(self):
return (self.pos.x + self.vel.x)
def cury(self):
return (self.pos.y + self.vel.y)
def forcex(velx):
self.vel.deltax(velx)
def forcey(vely):
self.vel.deltay(vely)
class Vector:
def __init__(self,x,y):
self.x = x
self.y = y
def x(self):
return self.x
def y(self):
return self.y
def delx(self,deltax):
self.x = self.x + deltax
def dely(self,deltay):
self.y = self.y + deltay
Here are my two classes, but when I initialize and try to get curx or cury back from ball:
ball = Ball(Vector(0,0),Vector(0,0))
print ball.curx
I get: <bound method Ball.curx of <__main__.Ball instance at 0x1142fd0>>
I feel like there should be a fairly simple answer to this and I'm just not getting it.
curx is a method of Ball. So, you have to invoke it:
print ball.curx()
Edit:
#user2357112 has noticed two more problems:
The definitions of Ball.forcex and Ball.forcey are missing their self parameters.
Vector.x and Vector.y are entirely useless methods. You already have x and y as attributes of Vector through self.x and self.y. So, you should just remove the methods altogether.
Here is how the code should be:
class Ball:
def __init__(self,pos,vel):
self.pos = Vector(pos.x,pos.y)
self.vel = Vector(vel.x,vel.y)
def curx(self):
return (self.pos.x + self.vel.x)
def cury(self):
return (self.pos.y + self.vel.y)
def forcex(self, velx):
self.vel.deltax(velx)
def forcey(self, vely):
self.vel.deltay(vely)
class Vector:
def __init__(self,x,y):
self.x = x
self.y = y
def delx(self,deltax):
self.x = self.x + deltax
def dely(self,deltay):
self.y = self.y + deltay
ball = Ball(Vector(0,0),Vector(0,0))
print ball.curx()

Categories