A drawing program's shapes all report their area and perimeter in the same format, and they can be compared by size. Write a small family of classes:
Shape, the base class. It cannot be created on its own:Shape()raisesTypeError. Every shape hasarea()andperimeter(), and the base class provides, for every shape:describe(), returning"<ClassName>: area <a>, perimeter <p>"with both numbers to 2 decimals, where<ClassName>is the name of the object's own class;bigger_than(other), which isTruewhen this shape's area is larger thanother's.
Rectangle(width, height), with attributeswidthandheight.Square(side), which is a rectangle (isinstance(Square(2), Rectangle)isTrue) whose width and height both equalside.Circle(radius).Triangle(a, b, c)from its three side lengths; if the sides cannot make a triangle (one side is at least the sum of the other two), it raisesValueError.
The tests also build shapes of their own, as subclasses of your Shape, with the helper custom_shape(name, area, perimeter); describe() and bigger_than() must work for them unchanged. The helper raises(fn, *args) returns the name of the exception a call raises, or None.
Examples
Input: [s.describe() for s in [Rectangle(3, 4), Square(2), Circle(1)]]
Output: ['Rectangle: area 12.00, perimeter 14.00',
'Square: area 4.00, perimeter 8.00',
'Circle: area 3.14, perimeter 6.28']
Input: Triangle(3, 4, 5).bigger_than(Square(2)), raises(Shape), raises(Triangle, 1, 2, 3)
Output: (True, 'TypeError', 'ValueError')
Constraints
- All lengths are positive numbers up to
10**4. - Use
math.pifor circles.
Goals
- Put behaviour shared by every shape in one base class
- Override only what differs in each subclass, and extend `__init__` with `super()`
- Make a base class that cannot be used on its own