I'm trying to write a method(it) that compares the size (area) of the rectangle with the area of another rectangle passed as a parameter:
class Rectangle:
def __init__(self, x, y):
self.width = x
self.height = y
def area(self):
a = self.width * self.height
return a
def __it__(self,second):
return self.area < second.area
But I keep getting error:
TypeError: unorderable types: Rectangle() < Rectangle()
I'm not to sure how to fix this problem
You had a typo. It's __lt__, not __it__, and you need to call the area() as a function unless you set that as a property.
Fixing all that...
>>> class Rectangle:
... def __init__(self, x, y):
... self.width = x
... self.height = y
... def area(self):
... a = self.width * self.height
... return a
... def __lt__(self,second):
... return self.area() < second.area()
...
>>> Rectangle(1,3) > Rectangle(4,5)
False
Area is a method, you're using it as though it's a variable. Adding parens should fix it (and if you're trying to do less than, it should be __lt__):
def __lt__(self, second):
return self.area() < second.area()
Related
This is just academic. Consider the following example:
class Shape():
def __init__(self, x, y):
self.x = x
self.y = y
def position(self):
return self.x, self.y
class Rectangle(Shape):
def __init__(self, x, y, height, width):
#super().__init__(x, y) # OK
self.x = x # not OK!
self.y = y # not OK!
self.height = height
self.width = width
r1 = Rectangle(1, 2, 3, 4)
If I asked someone to implement the class Rectangle, and they implemented with the "not OK" statements (instead of the with the "OK" statement as they should), then r1.x would be an attribute of Rectangle instead of Shape. Is there a way I can check if r1.x is a member of the Rectangle class or of the Shape class? Essentially, I want to make sure the initialization of the super class is being run, and no unnecessary new attributes are being created.
what the codes is supposed to is take the users input and then movie the rectangle around and when I run the code i get a Typeerror:<=' not supported between instances of 'str' and 'int'
these were some of the comments made on my code
For both Point and Rectangle class constructors, you are providing default values for the parameters. You should not since the assignment states, you should make them required arguments. (-4)
rectangleCount static attribute of the Rectangle class not kept up to date (should be incremented in the constructor to keep track of count of Rectangle objects created so far) (-2)
Rectangle's constructor doesn't check if width and height is negative, and if so print error message. (-2)
Calculations in the bottomRight property is incorrect. (-2) It should be
#property
def bottomRight(self):
return Point(self.topLeft.x + self.width, self.topLeft.y + self.height)
Calculations in the perimeter proper
# Prog 120
# Rectangle & Point Classes
class Point:
def __init__(self, x, y): # makes the value required
self.__x = x
self.__y = y
#property # read only property for x
def x(self):
return self.__x
#property # read only property for y
def y(self):
return self.__y
def translate(self, dx, dy): # moves x coordinate by 'dx' amount of time and move dy
self.__x += dx
self.__y += dy
class Rectangle:
DEFAULT_WIDTH = 1 # static attributes
DEFAULT_HEIGHT = 1
rectangleCount = 0
def __init__(self, topLeft, width, height):
self.__topLeft = topLeft
# check width argument
if (width <= 0):
print("Invalid width")
self.__width = Rectangle.DEFAULT_WIDTH
else:
self.__width = width
# check height argument
if (height <= 0):
print("Invalid Height")
self.__height = Rectangle.DEFAULT_HEIGHT
else:
self.__height = height
Rectangle.rectangleCount +=1 #updates the count of rectangels created
#property
def topLeft(self):
return self.__topLeft
#topLeft.setter
def topLeft(self, newTopLeft):
self.__topLeft = newTopLeft
#property
def width(self):
return self.__width
#width.setter
def width(self, newWidth):
if (newWidth <= 0):
print("Width cannot be less than '0'. ")
else:
self.__width = newWidth
#property
def height(self):
return self.__height
#height.setter
def height(self, newHeight):
if (newHeight <= 0):
print("Height cannot be less than '0'. ")
else:
self.__height = newHeight
#property
def bottomRight(self):
return Point(self.topLeft.x + self.topLeft.y + self.height)
#property
def area(self):
return self.__width * self.__height
#property
def perimeter(self):
return self.__width *2 + self.__height *2
def translate(self, dx, dy): # moves x coordinate by 'dx' amount of time and move y
self.__topLeft.translare(dx,dy)
def main():
bill = Point(x="", y="")
will = Rectangle(topLeft="", width="", height="")
if will.width and will.height < 0:
print("Width and Height cannot be less than 0.")
will.width = will.DEFAULT_WIDTH
will.height = will.DEFAULT_HEIGHT
will.rectangleCount += 1
if __name__ == "__main__":
main()
bill = Point(x="", y="")
will = Rectangle(topLeft="", width="", height="")
Here you are setting the attributes in Rectangle to the empty string.
And here:
def __init__(self, topLeft, width, height):
self.__topLeft = topLeft
# check width argument
if (width <= 0):
print("Invalid width")
self.__width = Rectangle.DEFAULT_WIDTH
You are comparing that string to 0 - an int. Obviously you can't compare "" with 0. That doesn't make any sense. That's what python is telling you with that error message.
Maybe try passing integers to the constructors. Like this:
bill = Point(x=5, y=9)
will = Rectangle(topLeft=2, width=4, height=1)
I have a problem with a task for school. I want my last method to test if two rectangles are the same. The only problem there is that I can't seem to differentiate between the two different heights, widiths and the different point(this is the left-low corner point of the rectangle) of the two different rectangles, any advice?
Thanks a lot
class Point():
def __init__(self,x,y):
self.x=x
self.y=y
class Rectangle():
def __init__(self,Point,w,h):
self.Point=Point
self.widith=w**strong text**
self.height=h
def same(self,Rectangle):
if Rectangle.self.Point==self.Point and Rectangle.self.widith==self.widith and Rectangle.self.height==self.height:
return True
else:
return False
First of all don't use the same name for function params and classes. It makes the code confusing and error prone. Try this:
class Rectangle:
def __init__(self, point, width, height):
self.point = point
self.widith = width
self.height = height
Now I assume that point variable is an instance of Point class. In that case comparing one point to another via == will fail, because by default == checks if two objects are the same in the sense of being the same object in memory.
Thus your implemenatation of same method may look like this:
def same(self, other):
return (
self.point.x == other.point.x
and self.point.y == other.point.y
and self.width == other.width
and self.height == other.height
)
If you overwrite builtin __eq__ method (which is responsible for the behaviour of == operator) on Point class like this:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
then same method can be simplified to:
def same(self, other):
return (
self.point == other.point # now __eq__ will be called here
and self.width == other.width
and self.height == other.height
)
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)
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()