@@ -284,5 +284,55 @@ def area(self) -> float:
284284 return super ().area ()
285285
286286
287+ class Triangle (Polygon ):
288+ """
289+ A geometric triangle on a 2D surface.
290+
291+ >>> triangle = Triangle(3, 4, 5)
292+ >>> triangle.perimeter()
293+ 12
294+ >>> triangle.area()
295+ 6.0
296+ >>> Triangle(-3, 4, 5)
297+ Traceback (most recent call last):
298+ ...
299+ TypeError: length must be a positive numeric value.
300+ >>> Triangle(1, 2, 3)
301+ Traceback (most recent call last):
302+ ...
303+ ValueError: side lengths do not form a valid triangle.
304+ """
305+
306+ def __init__ (self , side_a_length : float , side_b_length : float , side_c_length : float ) -> None :
307+ super ().__init__ ()
308+ self .side_a_length = side_a_length
309+ self .side_b_length = side_b_length
310+ self .side_c_length = side_c_length
311+ self .post_init ()
312+
313+ def post_init (self ) -> None :
314+ self .side_a = Side (self .side_a_length )
315+ self .side_b = Side (self .side_b_length )
316+ self .side_c = Side (self .side_c_length )
317+
318+ if not self ._is_valid_triangle (self .side_a .length , self .side_b .length , self .side_c .length ):
319+ raise ValueError ("side lengths do not form a valid triangle." )
320+
321+ super ().add_side (self .side_a )
322+ super ().add_side (self .side_b )
323+ super ().add_side (self .side_c )
324+
325+ @staticmethod
326+ def _is_valid_triangle (a : float , b : float , c : float ) -> bool :
327+ return a + b > c and a + c > b and b + c > a
328+
329+ def perimeter (self ) -> float :
330+ return self .side_a .length + self .side_b .length + self .side_c .length
331+
332+ def area (self ) -> float :
333+ s = self .perimeter () * 0.5
334+ return math .sqrt (s * (s - self .side_a .length ) * (s - self .side_b .length ) * (s - self .side_c .length ))
335+
336+
287337if __name__ == "__main__" :
288338 __import__ ("doctest" ).testmod ()
0 commit comments