def testComputeLength(self): l1 = Line(1, 2, 4, 10) self.assertAlmostEqual(8.544, l1.computeLength(), places=3) l2 = Line(1, 2, 1, 3) self.assertAlmostEqual(1, l2.computeLength(), places=3) l3 = Line(3, -2, -4, 10) self.assertAlmostEqual(13.892, l3.computeLength(), places=3)
class Triangle: def __init__(self, *args, **kwargs): try: if not self.__constructWithPoints(args[0], args[1], args[2]): if not self.__constructWithLines(args[0], args[1], args[2]): if not self.__constructWithCoords( args[0], args[1], args[2], args[3], args[4], args[5]): raise ShapeException("Triangle construction failed") except IndexError: raise ShapeException("Invalid arguments for triangle construction") def __constructWithCoords(self, x1, y1, x2, y2, x3, y3): try: self.__line1 = Line(x1, y1, x2, y2) self.__line2 = Line(x2, y2, x3, y3) self.__line3 = Line(x3, y3, x1, y1) Validator.validateTriangle(value=self, errorMessage="Triangle invalid") return True except ShapeException: return False def __constructWithPoints(self, point1, point2, point3): try: self.__line1 = Line(point1, point2) self.__line2 = Line(point2, point3) self.__line3 = Line(point3, point1) Validator.validateTriangle(value=self, errorMessage="Triangle invalid") return True except ShapeException: return False def __constructWithLines(self, line1, line2, line3): try: self.__line1 = line1 self.__line2 = line2 self.__line3 = line3 Validator.validateTriangle(value=self, errorMessage="Triangle invalid") return True except ShapeException: return False @property def point1(self): return self.__line1.point1 @property def point2(self): return self.__line2.point1 @property def point3(self): return self.__line3.point1 @property def line1(self): return self.__line1 @property def line2(self): return self.__line2 @property def line3(self): return self.__line3 def move(self, deltaX, deltaY): self.__line1.move(deltaX, deltaY) self.__line2.move(deltaX, deltaY) self.__line3.move(deltaX, deltaY) def computeArea(self): """Compute area using Heron's formula""" a = self.__line1.computeLength() b = self.__line2.computeLength() c = self.__line3.computeLength() s = (a + b + c) / 2 return math.sqrt(s * (s - a) * (s - b) * (s - c))
class Rectangle: def __init__(self, *args, **kwargs): try: # Construct with x1, y1, x2, y2, x3, y3, x4, y4 if not self.__constructWithPoints(args[0], args[1], args[2], args[3]): if not self.__constructWithLines(args[0], args[1], args[2], args[3]): if not self.__constructWithCoords( args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]): raise ShapeException("Rectangle construction failed") except IndexError: raise ShapeException("Invalid arguments for shape construction") def __constructWithCoords(self, x1, y1, x2, y2, x3, y3, x4, y4): try: self.__line1 = Line(x1, y1, x2, y2) self.__line2 = Line(x2, y2, x3, y3) self.__line3 = Line(x3, y3, x4, y4) self.__line4 = Line(x4, y4, x1, y1) Validator.validateRectangle(value=self, errorMessage="Invalid Rectangle") return True except ShapeException: return False def __constructWithPoints(self, point1, point2, point3, point4): try: self.__line1 = Line(point1, point2) self.__line2 = Line(point2, point3) self.__line3 = Line(point3, point4) self.__line4 = Line(point4, point1) Validator.validateRectangle(value=self, errorMessage="Invalid Rectangle") return True except ShapeException: return False def __constructWithLines(self, line1, line2, line3, line4): try: self.__line1 = line1 self.__line2 = line2 self.__line3 = line3 self.__line4 = line4 Validator.validateRectangle(value=self, errorMessage="Invalid Rectangle") return True except ShapeException: return False @property def point1(self): return self.__line1.point1 @property def point2(self): return self.__line2.point1 @property def point3(self): return self.__line3.point1 @property def point4(self): return self.__line4.point1 @property def line1(self): return self.__line1 @property def line2(self): return self.__line2 @property def line3(self): return self.__line3 @property def line4(self): return self.__line4 def move(self, deltaX, deltaY): self.__line1.move(deltaX, deltaY) self.__line2.move(deltaX, deltaY) self.__line3.move(deltaX, deltaY) self.__line4.move(deltaX, deltaY) def computeWidth(self): return self.__line1.computeLength() def computeHeight(self): return self.__line2.computeLength() def computeArea(self): return self.computeWidth() * self.computeHeight()