Move points and check specific start value, using classes python - 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)>]

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.

Operating with Python class and objects

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()

Calling a method from parent class that has a different name in the subclass

Having the following code:
class Point:
'class that represents a point in the plane'
def __init__(self, xcoord=0, ycoord=0):
''' (Point,number, number) -> None
initialize point coordinates to (xcoord, ycoord)'''
self.x = xcoord
self.y = ycoord
def setx(self, xcoord):
''' (Point,number)->None
Sets x coordinate of point to xcoord'''
self.x = xcoord
def sety(self, ycoord):
''' (Point,number)->None
Sets y coordinate of point to ycoord'''
self.y = ycoord
def get(self):
'''(Point)->tuple
Returns a tuple with x and y coordinates of the point'''
return (self.x, self.y)
def move(self, dx, dy):
'''(Point,number,number)->None
changes the x and y coordinates by dx and dy'''
self.x += dx
self.y += dy
def __repr__(self):
'''(Point)->str
Returns canonical string representation Point(x, y)'''
return 'Point('+str(self.x)+','+str(self.y)+')'
class Rectangle(Point):
def __init__(self,bottom_left,top_right,color):
self.get = bottom_left
self.get = top_right
self.color = color
def get_bottom_left(self,bottom_left):
print ()
r1 = Rectangle(Point(0,0), Point(1,1), "red")
r1.get_bottom_left()
I want to be able to print "Point(0,0)" by calling self__rep__(self) from class Point from the method get_bottom_left, but I just have no idea how. I know how to use inheritance if the functions have the same name, but in this case I am stuck and it is a requirement for the child function to have the method names it has. If it looks that I am just looking for the answer, I would like the response to just explain me a similar case of this application please!
When I do the following:
class Rectangle(Point):
def __init__(self,bottom_left,top_right,color):
self.get = bottom_left
self.get = top_right
self.color = color
def get_bottom_left(self,bottom_left):
print (self.bottom_left)
I get: get_bottom_left() missing 1 required positional argument: 'bottom_left'
As mentioned in the comment, Rectangle should contain Point instances and not inherit Point. If you change Rectangle class as shown below, you'll see the expected result:
class Rectangle():
def __init__(self, bottom_left, top_right, color):
self.bottom_left = bottom_left
self.top_right = top_right
self.color = color
def get_bottom_left(self):
print self.bottom_left

Python Circle Shape Collison Class

this code needs to take in a x, y, and radius for 2 circles that is input by me and see if it collides. i'm confused on the circle class part on the collision and distance methods. i already typed in the formula which i think is correct to find the distance but i don't know how to call c1 and c2 coordinates so that part i know is wrong. as for the collision i was planning to write a if statement checking if the sum of c1 and c2 radius is equal or greater than the distance, that i also don't know how to do. so if anyone could help it is very much appreciated. also my professor gave us main class part and i don't understand why he put a for loop there so i don't know what that loop is for
class Shape:
"""Shape class: has methods move(), location(), and __init__().
Complete the location() method."""
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, deltaX, deltaY):
self.x = self.x + deltaX
self.y = self.y + deltaY
def location(self):
'''Returns a tuple containing the ~x,y~ coordinates of an object.
return "Circle at coordinates (%d, %d)"\ % (self.x, self.y)
pass
class Circle(Shape):
"""Circle is a sub-class of shape and inherits the move() and location() methods."""
pi = 3.14159
def __init__(self, x=0, y=0, r=1):
Shape.__init__(self, x, y)
self.radius = r
def area(self):
return self.radius * self.radius * self.pi
def __str__(self):
return "Circle of radius %s at coordinates (%d, %d)"\ % (self.radius, self.x, self.y)
# Class methods
#classmethod
def is_collision(Circle, c1, c2):
'''Return True or None'''
if c1.r + c2.r >= dist:
pass # fill this in
else:
not
#classmethod
def distance(Circle, c1, c2):
"""calculate distance between two circles"""
dist = math.sqrt(((c1.x-c2.x)**2)+((c1.y-c2.y)**2))
pass
from shape import Shape
from circle import Circle
c1 = Circle(100, 100, 100)
c2 = Circle(150, 150, 100)
c1_xdelta = 2
c1_ydelta = 3
c2_xdelta = 1
c2_ydelta = -1
for i in range(1,20):
c1.move(c1_xdelta, c1_ydelta)
c2.move(c2_xdelta, c2_ydelta)
# Print c1.__str__()
print(c1)
# Print c2.__str__()
print(c2)
# Print collision True or None
print("Collision: {collision}".format(collision = Circle.is_collision())
Example Output:
~Circle~ 1: Circle: x,y; coordinates: 0, 0; radius: 5.
~Circle~ 2: Circle: x,y; coordinates: 0, 0; radius: 5.
Collision: True
~Circle~ 1: Circle: x,y; coordinates: 16, 16; radius: 5.
~Circle~ 2: Circle: x,y; coordinates: 16, 136; radius: 5.
Collision: None
After correcting the collision() and distance() methods, your code should look something like:
import math
class Shape:
"""Shape class: has methods move(), location(), and __init__()."""
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, deltaX, deltaY):
self.x = self.x + deltaX
self.y = self.y + deltaY
def location(self):
return "Circle at coordinates (%d, %d)" % (self.x, self.y)
class Circle(Shape):
"""Circle is a sub-class of shape and inherits the move() and location() methods."""
pi = 3.14159
def __init__(self, x=0, y=0, r=1):
Shape.__init__(self, x, y)
self.radius = r
def area(self):
return self.radius * self.radius * self.pi
def __str__(self):
return "Circle of radius %s at coordinates (%d, %d)" % (self.radius, self.x, self.y)
# Class methods
#classmethod
def is_collision(Circle, c1, c2):
'''Return True or False'''
return c1.radius + c2.radius >= Circle.distance(c1, c2)
#classmethod
def distance(Circle, c1, c2):
"""calculate distance between two circles"""
return math.sqrt(((c1.x-c2.x)**2)+((c1.y-c2.y)**2))
Example use:
from circle import Circle
c1 = Circle(0, 0, 5)
c2 = Circle(0, 0, 5)
print(c1)
print(c2)
print("Collision: {collision}".format(collision = Circle.is_collision(c1, c2)))
c1.move(16, 16)
c2.move(16, 136)
print(c1)
print(c2)
print("Collision: {}".format(Circle.is_collision(c1, c2)))
Example output:
Circle of radius 5 at coordinates (0, 0)
Circle of radius 5 at coordinates (0, 0)
Collision: True
Circle of radius 5 at coordinates (16, 16)
Circle of radius 5 at coordinates (16, 136)
Collision: False

Categories