Use object from one class as attribute for another class - python

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

Related

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

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

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

Learning class in python but having issue that probably is simple

I have simple code that creates a rectangle
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
class Rectangle:
def __init__(self, posn, w, h):
self.corner = posn
self.width = w
self.height = h
def __str__(self):
return "({0},{1},{2})".format(self.corner, self.width, self.height)
box = Rectangle(Point(0, 0), 100, 200)
print("box: ", box)
The output of this code is
('box: ', <__main__.Rectangle instance at 0x0000000002368108>)
I expect the output to be
box: ((0, 0), 100, 200)
Can someone please help?
You don't define a __repr__() on your Rectangle class. Printing a tuple (as you are doing) uses the repr() of the class, not the str(). You also need a __str__() on your Point class.
You need to define __repr__ in both the Classes, like this
class Point(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __repr__(self):
return "({}, {})".format(self.x, self.y)
class Rectangle(object):
def __init__(self, posn, w, h):
self.corner = posn
self.width = w
self.height = h
def __repr__(self):
return "({0},{1},{2})".format(self.corner, self.width, self.height)
print "box: ", box
# box: ((0, 0),100,200)
It seems like you're using Python 2.x: In Python 2.x, print is statement, not a function.
By putting (...), you're printing str(("box:", box)). (A tuple containing a string and Rectangle object)
Remove parentheses, and define Point.__str__ to get what you expected.
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return str((self.x, self.y))
# OR return '({0.x}, {0.y})'.format(self)
class Rectangle:
def __init__(self, posn, w, h):
self.corner = posn
self.width = w
self.height = h
def __str__(self):
return "({0},{1},{2})".format(self.corner, self.width, self.height)
box = Rectangle(Point(0, 0), 100, 200)
print("box: ", box) # This prints a tuple: `str(("box: ", box))`
print "box: ", box # This prints `box: ` and `str(box)`.
output:
('box: ', <__main__.Rectangle instance at 0x00000000027BC888>)
box: ((0, 0),100,200)

Categories