class PolygonInteriorAngle(object):
def __init__(self, x):
self.x = self
def FindInteriorAngle(self):
degrees = int((x - 2) * 180)
interior = int(degrees / x)
return interior
def PrintInterior(self):
print("interior angle: " + str(self.FindInteriorAngle()))
class PolygonExteriorAngle(object):
def __init__(self, x):
self.x = self
def FindExteriorAngle(self):
exterior = int(360 / x)
return exterior
def PrintExterior(self):
print("exterior angle: " + str(self.FindExteriorAngle()))
class AngleAddition(object):
def __init__(self, x):
self.x = self
def Add(self):
sum = int(interior + exterior)
return sum
def PrintAdd(self):
print("sum of interior and exterior: " + str(self.Add()))
if __name__ == "__main__":
x = int(input("enter: "))
intObj = PolygonInteriorAngle(x)
intObj.FindInteriorAngle()
intObj.PrintInterior()
extObj = PolygonExteriorAngle(x)
extObj.FindExteriorAngle()
extObj.PrintExterior()
addObj = AngleAddition(x)
addObj.Add()
addObj.PrintAdd()
both classes (PolygonInteriorAngle and PolygonExteriorAngle) work fine, they print what they're expected to. what i want to do in the AngleAddition class is to add both of the final values (interior and exterior) that you get from the other two classes. i think it's pretty inefficient putting them in different classes, but that's what my computer science teacher asked me to and i'm not sure how to use a value from another class in a new class. if you do x = 6, you'll get 120 and 60. with AngleAddition i want to print 180.
General comments:
You need to check very carefully the variables in your instance methods. example:
def Add(self):
sum = int(interior + exterior)
return sum
Both interior and exterior are not specified in the instance method arguments.
I agree with User: Tim Roberts's comment. Either you make a base class "angle" and let the "interior/exterior angle" class inherit from the "angle" class, or just use angle class for both interior/exterior angles. It depends on how you want to write the __init__ method for interior/exterior angle classes.
Note that I overrode the magic method to perform the sum of two angles. There are other ways of doing that cause in my way the + operator is being redefined.
Anyways:
class AngleBase:
def __init__(self,angle):
self.angle=angle
def __add__(self,angleobj):
return int(self.angle+angleobj.angle)
class PolygonInteriorAngle(AngleBase):
def __init__(self, side):
degrees = int((side - 2) * 180)
interior = int(degrees / side)
AngleBase.__init__(self,interior)
def FindInteriorAngle(self):
return self.angle
def PrintInterior(self):
print("interior angle: " + str(self.angle))
class PolygonExteriorAngle(AngleBase):
def __init__(self, side):
exterior = int(360 / side)
AngleBase.__init__(self,exterior)
def FindExteriorAngle(self):
return self.angle
def PrintExterior(self):
print("exterior angle: " + str(self.angle))
class AngleAddition:
def __init__(self, x):
pass
def Add(self,interior, exterior):
sum = int(interior + exterior)
return sum
def PrintAdd(self,interior, exterior):
print("sum of interior and exterior: " + str(self.Add(interior, exterior)))
if __name__ == "__main__":
x = int(input("enter: "))
intObj = PolygonInteriorAngle(x)
print(intObj.angle)
intObj.FindInteriorAngle()
intObj.PrintInterior()
extObj = PolygonExteriorAngle(x)
extObj.FindExteriorAngle()
extObj.PrintExterior()
addObj = AngleAddition(x)
addObj.Add(extObj,intObj)
addObj.PrintAdd(extObj,intObj)
Related
import random
class point:
def __init__(self,p):
self.p = p
def fill_point(self):
x = random.uniform(0,100)
y = random.uniform(0,100)
z = random.uniform(0,100)
self.p = [x,y,z]
return self.p
def distance_between_points(self,p1,p2):
D = ((self.p1[0]-self.p2[0])**2 + (self.p1[1]-self.p2[1])**2 + (self.p1[2]-self.p2[2])**2)**(1/2)
return D
def main():
point1 = point(fill_point())
point2 = point(fill_point())
Distance = distance_between_points(point1,point2)
print(Distance)
main()
im quite new to classes and am having a hard time understanding what im doing wrong.
import random
from math import sqrt
class Point:
def __init__(self, name='anonym_point',x=0,y=0,z=0):
self.name = name
self.x = x
self.y = y
self.z = z
#property
def coord(self):
return (self.x, self.y, self.z)
def __repr__(self):
return ("{} has coordinate {} {} {}".format(self.name, self.x, self.y, self.z))
def makepoint(namepoint):
return Point(namepoint, random.uniform(0,100), random.uniform(0,100), random.uniform(0,100))
def distance_between_points(p1,p2):
dist = sqrt((p2.x-p1.x)**2 + (p2.y-p1.y)**2 + (p2.z-p1.z)**2)
print("distance between point ",p1.name," and the point ",p2.name," : ",dist)
point1 = makepoint("p1")
point2 = makepoint("p2")
print(point1)
print(point2)
Distance = distance_between_points(point1,point2)
The issue is that you are accessing the class method just as a normal method, you need to initialize class object first then call the method by class object you created, again use only the variables you are sure you need,. keeping code easy for you because I think you already know what you needed I did this
import random
class Point:
def fill_point(self):
x = random.uniform(0,100)
y = random.uniform(0,100)
z = random.uniform(0,100)
p = [x,y,z]
return p
def distance_between_points(self,p1,p2):
D = ((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2 + (p1[2]-p2[2])**2)**(1/2)
return D
def main():
obj = Point()
point1 = obj.fill_point()
point2 = obj.fill_point()
distance = obj.distance_between_points(point1,point2)
print(distance)
main()
it would not kill if you try to understand python classes better, python best naming, etc...
i think that what you are trying to do is something like this.
import math
class Point():
def __init__(self,x,y,z):
self.coordinates = (x,y,z)
def distance(self,point):
return math.sqrt((point.coordinates[0] - self.coordinates[0])**2 + (point.coordinates[1] - self.coordinates[1])**2 + (point.coordinates[1] - self.coordinates[1])**2)
a = Point(4,2,8)
b = Point(2,7,3)
print(a.distance(b))
what you are doing by executing this python code is simply creating a "Point" class, this point class has an attribute (coordinates) that contains its coordinates into a tuple.
so to create a point object you just have to use this code point = Point(x_coordinates,y_coordinates,z_coordinates).
In the last line the code calculates the distance between two points, in that case you are calculating the distance of "b" respect to "a", but you could also do viceversa by doing something like this: print(b.distance(a))
to calculate the distance between random point all you have to do is this:
import math, random
class Point():
def __init__(self,x,y,z):
self.coordinates = (x,y,z)
def distance(self,point):
return math.sqrt((point.coordinates[0] - self.coordinates[0])**2 + (point.coordinates[1] - self.coordinates[1])**2 + (point.coordinates[1] - self.coordinates[1])**2)
r = lambda: random.uniform(0,100)
a = Point(r(),r(),r())
b = Point(r(),r(),r())
print(a.distance(b))
this is how to do that, but i really don't understand why you should calculate the distance between two random numbers
I'm writing this code and there is a need to send objects as parameters in functions. My problem is one of the objects needs to be resued with its original values but as I need to return an object from the functions.
I don't know how I can send the answer and keep the original values in the object
safe for reuse. Is there any way to make an object from the class declaration itself?
import math
class Points(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __sub__(self, no):
no.x = no.x - self.x
no.y = no.y - self.y
no.z = no.z - self.z
return(no)
def dot(self, no):
ans = (self.x * no.x)+(self.y * no.y)+(self.z * no.z)
return ans
def cross(self, no):
x = (self.y * no.z)-(self.z * no.y)
y = (self.x * no.z)-(self.z * no.x)
z = (self.x * no.y)-(self.y * no.x)
self.x = x
self.y = y
self.z = z
return(self)
def absolute(self):
return pow((self.x ** 2 + self.y ** 2 + self.z ** 2), 0.5)
if __name__ == '__main__':
points = list()
for i in range(4):
a = list(map(float, input().split()))
points.append(a)
a, b, c, d = Points(*points[0]), Points(*points[1]), Points(*points[2]), Points(*points[3])
x = (b - a).cross(c - b)
y = (c - b).cross(d - c)
angle = math.acos(x.dot(y) / (x.absolute() * y.absolute()))
print("%.2f" % math.degrees(angle))
I want to do something like:
def function_name(self,other)
temp.x = self.x + other.x
temp.y = self.y + other.y
return temp
This way both input objects will have their original values but I don't know how to get that temp.
Thanks everyone who helped. I got the answer to what I was looking. I wanted an object to act as a container that can store the class variables,
and I didn't knew I can just make a new object of the class from within it!
import math
class Points(object):
def __init__(self, x, y, z):
self.x=x
self.y=y
self.z=z
def __sub__(self, no):
return Points((self.x-no.x),(self.y-no.y),(self.z-no.z))
def dot(self, no):
return (self.x*no.x)+(self.y*no.y)+(self.z*no.z)
def cross(self, no):
return Points((self.y*no.z-self.z*no.y),(self.z*no.x-self.x*no.z),(self.x*no.y-self.y*no.x))
def absolute(self):
return pow((self.x ** 2 + self.y ** 2 + self.z ** 2), 0.5)
As you can see using points, i.e the constructor for class Points, I can store the result of any operations and can return it as an object while not altering my input objects.
If what you're trying to do is reuse a variable that you have passed to a class object, you can just duplicate it in your __init__ statement, or in the function where you use it.
e.g
class Foo:
def __init__(self, my_var1, my_var2):
self.my_var1 = my_var1
self.my_var2 = my_var2
def bar(self):
bar_var1 = self.my_var1
bar_var2 = self.my_var2
bar_var1 = bar_var1 + bar_var2
return bar_var1
Although, I am a little confused by why you are attempting to return self in your cross function, as self is a class parameter, and you don't seem to be using it in its intended purpose. If you're confused about how you should be using self, a brief read through the python class tutorial might be helpful. However, barring that, I hope this answers your question.
Why does trying to set “points” via Python properties cause infinite recursion?
Using Python 3
import Task
myTask = Task.Task("Test",-5)
myTask.points = -7
print(myTask)
class Task:
def __init__(self,name="",points=0,times_done=0):
self.name = name
self.points = points
self.times_done = times_done
#property
def points(self):
return self.points
#points.setter
def points(self, points):
if (points < 0):
self.points = 0
else:
self.points = points
def __str__(self):
return "The task '" + self.name + "' is worth " + str(self.points) + " and has been completed " + str(self.times_done) + " times."
When it tries constructing it with value -5 (which should set it to 0, via the property), it infinitely recurses on the line self.points = points in the setter function/decoration #points.setter.
Thanks!
Because self.points = ... call the setter; inside the setter, self.points = ... is executed which call the setter; recursion repeated until stack overflow.
By using other name, you can prevent the recursion: self._points for example.
Or instead of using self.points = ..., use self.__dict__['points'] = .. (same for getter):
#property
def points(self):
return self.__dict__['points']
#points.setter
def points(self, points):
if points < 0:
self.__dict__['points'] = 0
else:
self.__dict__['points'] = points
# self.__dict__['points'] = max(0, points)
That's because inside your property setter, it calls itself again:
#points.setter
def points(self, points):
if (points < 0):
self.points = 0 # call itself again here
else:
self.points = points # call itself again here
You need another field to store the actually value when you use property, and it would be better to be a "private" field:
class Task(object):
def __init__(self,name="",points=0,times_done=0):
self.name = name
self.points = points
self.times_done = times_done
#property
def points(self):
return self._points
#points.setter
def points(self, points):
if (points < 0):
self._points = 0
else:
self._points = points
I'm just beginning working with object-oriented programming. I have created some classes and am trying to complete the rectangle class. Any and all help is appreciated.
I'm confused about when you need to refer to self and when you can just create variables. For example, in defining the length of the rectangle, I don't know if I should call the variable self.length or just length, and I haven't been able to find any rectangle classes defined in this way.
import math
class Point (object):
# constructor
def __init__ (self, x = 0, y = 0):
self.x = x
self.y = y
# get distance
def dist (self, other):
return math.hypot (self.x - other.x, self.y - other.y)
# get a string representation of a Point object
def __str__ (self):
return '(' + str(self.x) + ", " + str(self.y) + ")"
# test for equality
def __eq__ (self, other):
tol = 1.0e-16
return ((abs (self.x - other.x) < tol) and (abs(self.y - other.y) < tol))
class Circle (object):
# constructor
def __init__ (self, radius = 1, x = 0, y = 0):
self.radius = radius
self.center = Point (x, y)
# compute cirumference
def circumference (self):
return 2.0 * math.pi * self.radius
# compute area
def area (self):
return math.pi * self.radius * self.radius
# determine if point is strictly inside circle
def point_inside (self, p):
return (self.center.dist(p) < self.radius)
# determine if a circle is strictly inside this circle
def circle_inside (self, c):
distance = self.center.dist (c.center)
return (distance + c.radius) < self.radius
# determine if a circle c intersects this circle (non-zero area of overlap)
def does_intersect (self, c):
# string representation of a circle
def __str__ (self):
# test for equality of radius
def __eq__ (self, other):
tol = 1.0e-16
class Rectangle (object):
# constructor
def __init__ (self, ul_x = 0, ul_y = 1, lr_x = 1, lr_y = 0):
if ((ul_x < lr_x) and (ul_y > lr_y)):
self.ul = Point (ul_x, ul_y)
self.lr = Point (lr_x, lr_y)
else:
self.ul = Point (0, 1)
self.lr = Point (1, 0)
# determine length of Rectangle
def length (self):
# determine width of Rectangle
def width (self):
# determine the perimeter
def perimeter (self):
# determine the area
def area (self):
# determine if a point is strictly inside the Rectangle
def point_inside (self, p)
# determine if another Rectangle is inside this Rectangle
def rectangle_inside (self, r):
# determine if two Rectangles overlap
def does_intersect (self, other):
# determine the smallest rectangle that circumscribes a circle
def rect_circumscribe (self, c):
# give string representation of a rectangle
def __str__ (self):
# determine if two rectangles have the same length and width
def __eq__ (self, other):
Basically, setting a value to self.length gives you the ability to access this value from other functions inside the class and from outside of the class. If you set a value to length, you are able to access this variable only in the current function inside the class.
Just a start, try to continue yourself:
class Rectangle (object):
# constructor
def __init__ (self, ul_x = 0, ul_y = 1, lr_x = 1, lr_y = 0):
# Called if you say: my_rectancle = Rectangle (-10, 10, 10, -10)
# Puts parameters in fields of your newly created object of class Rectancle
self.ul_x = ul_x
self.ul_y = ul_y
self.lr_x = lr_x
self.lr_y = lr_y
# compute cirumference
def circumference (self):
return 2 * (self.ur_x - self.lr_x) + 2 * (self.ul_y - self.lr_y)
# compute area
def area (self):
return (self.ur_x - self.lr_x) * (self.ul_y - self.lr_y)
[EDIT]
With regard to the additional code in your comment, it's quite close to what it should be. With some corrections:
# determine length of Rectangle
def length (self):
return self.ul_y - self.lr_y
# determine width of Rectangle
def width (self):
return self.lr_x - self.ul_x
# self. has been added, since e.g. lr_x is not a parameter
# of the width function, but a field of the object you make
# by instantiation: 'rectangle = Rectangle (10, 20, 100, 200)'
# After that, self refers to the object 'rectangle' you created,
# which has class 'Rectangle'.
#
# Note that a class is a type.
# You can have a type 'Dog'.
# Dog 'fluffy' is an instance of that class, so a particular dog.
# In the methods (functions) of 'Dog', 'self' refers to the particular
# dog you're working with.
# determine the perimeter
def perimeter (self):
return 2 * self.width () + 2 * self.length ()
# Note the () after width and length.
# They're needed because width and length are
# function calls (they DO something) rather than fields (data)
# You could also have stored width and length into fields,
# just like the constructor did with ul_x, ul_y, lr_x and lr_y,
# storing them in self.ul_x, self.ul_y etc.
# Then the braces wouldn't have been needed.
# But also out some superfluous braces here
# Multiplication goes before addition anyhow
# And return returns everything after it, no braces needed.
# determine the area
def area (self):
return self.width () * self.length ()
So, how far did you get now?
I got a problem with an iterator which I created for some OOP exercises.
Here is the problematic generator:
def shapeIterator(listOfShapes):
print("Generator...")
print(listOfShapes)
listOfShapessoretedbyArea = shape.sortedByArea(listOfShapes)
for shapes in listOfShapessoretedbyArea:
yield str(shapes)
shape.sortedByArea(listOfShapes) is a static method, which need one argument, a list, which is sorted by the calculate area, and returned to the caller.
This method works perfectly in this main function:
if __name__ == '__main__':
rect = rectangle(20, 5)
squa = square(2)
tri = equiTria(2, 5)
circ = circle(2)
pent = pentagon(5)
hexa = hexagon(3)
listOfShapes = [rect, squa, hexa, tri, circ, pent]
listOfShapessoretedbyArea = sorted(listOfShapes, key=lambda x: x.calculate_area())
listOfShapessoretedbyPeri = sorted(listOfShapes, key=lambda x: x.calculate_perimeter())
listOfShapessoretedbyArea2 = shape.sortedByArea(listOfShapes)
listOfShapessoretedbyPeri2 = shape.sortedByPerim(listOfShapes)
iterator = shapeIterator(listOfShapes)
for i in range(6):
sleep(1)
value = next(iterator)
print(value)
print("NOT SORTED")
for shape in listOfShapes:
print(str(shape))
print("\nSORTED BY AREA")
for shape in listOfShapessoretedbyArea:
print(str(shape))
print("\nSORTED BY PERIMETER")
for shape in listOfShapessoretedbyPeri:
print(str(shape))
print("\nSORTED BY AREA v2")
for shape in listOfShapessoretedbyArea2:
print(str(shape))
print("\nSORTED BY PERIMETER v2")
for shape in listOfShapessoretedbyPeri2:
print(str(shape))
but when I move this part:
iterator = shapeIterator(listOfShapes)
for i in range(6):
sleep(1)
value = next(iterator)
print(value)
at the end of the main, like this:
if __name__ == '__main__':
rect = rectangle(20, 5)
squa = square(2)
tri = equiTria(2, 5)
circ = circle(2)
pent = pentagon(5)
hexa = hexagon(3)
listOfShapes = [rect, squa, hexa, tri, circ, pent]
listOfShapessoretedbyArea = sorted(listOfShapes, key=lambda x: x.calculate_area())
listOfShapessoretedbyPeri = sorted(listOfShapes, key=lambda x: x.calculate_perimeter())
listOfShapessoretedbyArea2 = shape.sortedByArea(listOfShapes)
listOfShapessoretedbyPeri2 = shape.sortedByPerim(listOfShapes)
print("NOT SORTED")
for shape in listOfShapes:
print(str(shape))
print("\nSORTED BY AREA")
for shape in listOfShapessoretedbyArea:
print(str(shape))
print("\nSORTED BY PERIMETER")
for shape in listOfShapessoretedbyPeri:
print(str(shape))
print("\nSORTED BY AREA v2")
for shape in listOfShapessoretedbyArea2:
print(str(shape))
print("\nSORTED BY PERIMETER v2")
for shape in listOfShapessoretedbyPeri2:
print(str(shape))
iterator = shapeIterator(listOfShapes)
for i in range(6):
sleep(1)
value = next(iterator)
print(value)
I got this error:
TypeError: sortedByArea() takes 1 positional argument but 2 were given
That's very strange. Trying to do some naive debug, I printed the argument passed at the function sortedByArea() in the second case, and I got effectively two arguments. One is the to string value printed in the last for each statement, and the second is the list itself.
The last to string value is referred to this for each statement:
for shape in listOfShapessoretedbyPeri2:
print(str(shape))
I also tried to change the value of the list, and effectively the value "concatenated" to the argument passed to the shapeIterator function is the last string printed.
If needed here are the classes and import used in the main .py:
from math import pi
from math import sqrt
from time import sleep
class shape():
def calculate_area():
pass
def calculate_perimeter():
pass
def ltarea(self, other):
return self.calculate_area() < other.calculate_area()
def ltperim(self, other):
return self.calculate_perimeter() < other.calculate_perimeter()
def sortedByArea(shapes):
return sorted(shapes, key=lambda x: x.calculate_area())
def sortedByPerim(shapes):
return sorted(shapes, key=lambda x: x.calculate_perimeter())
def nametype(self):
return "shape"
def __str__(self):
return "{0}, area: {1}, perim: {2}".format(self.nametype(),
self.calculate_area(),
self.calculate_perimeter())
class rectangle(shape):
def __init__(self, side1, side2):
self.__side1 = side1
self.__side2 = side2
def calculate_area(self):
return self.__side1 * self.__side2
def calculate_perimeter(self):
return (self.__side1 * 2) + (self.__side2 * 2)
def nametype(self):
return "rectangle"
class square(rectangle):
def __init__(self, side):
self._rectangle__side1 = side
self._rectangle__side2 = side
def nametype(self):
return "square"
class equiTria(shape):
def __init__(self, side, height):
self.__side = side
def calculate_area(self):
self.__height = self.calculate_perimeter() / (2 * sqrt(3))
return (self.__side * self.__height)/2
def calculate_perimeter(self):
return self.__side * 3
def nametype(self):
return "equiTria"
class circle(shape):
def __init__(self, radius):
self.__radius = radius
def calculate_area(self):
return pi * pow(self.__radius, 2)
def calculate_perimeter(self):
return 2 * pi * self.__radius
def nametype(self):
return "circle"
class pentagon(shape):
def __init__(self, side):
self.__side = side
self.__apothem = side * 0.688
def calculate_perimeter(self):
return self.__side * 5
def calculate_area(self):
return (self.calculate_perimeter() * self.__apothem) / 2
def nametype(self):
return "pentagon"
class hexagon(shape):
def __init__(self, side):
self.__side = side
def calculate_area(self):
self.__apothem = self.__side * 0.866
return (self.calculate_perimeter() * self.__apothem) / 2
def calculate_perimeter(self):
return self.__side * 6
def nametype(self):
return "hexagon"
def shapeIterator(listOfShapes):
print("Generator...")
print(listOfShapes)
listOfShapessoretedbyArea = shape.sortedByArea(listOfShapes)
for shapes in listOfShapessoretedbyArea:
yield str(shapes)
You rebind shape in your loops, so it is no longer the class, but one instance.
For example, just above your use of the generator:
for shape in listOfShapessoretedbyPeri2:
print(str(shape))
The variables in the __main__ section are still globals, so that replaced the class used by the generator.
Your options are:
Use a different name for the loop variable; ashape for example.
Use a different name for the class. The Python style guide recommends using CamelCase for class names, so renaming it to Shape would do nicely here.
Put all the code under the if __name__ == '__main__': block in a function, so that variable names like the loop target become locals.
Personally, I'd implement both 2 and 3; avoiding polluting your global namespace is always a good idea, and so is following the almost universally adopted Python style guide; this helps avoid such mistakes in the future.
In addition, if sortedByArea is meant to be a static method, do at least use the #staticmethod decorator. That way it is still useable as a static method even on instances:
class Shape:
# ...
#staticmethod
def sortedByArea(shapes):
return sorted(shapes, key=lambda x: x.calculate_area())
#staticmethod
def sortedByPerim(shapes):
return sorted(shapes, key=lambda x: x.calculate_perimeter())
You reused the shape variable, once for the shape class and once for the loop variable in all your for shape in loops.