# Object-Oriented Programming/Inheritance/Python3

## main.py

```"""This program demonstrates use of the Polygon, Triangle, Rectangle, and Square classes."""

from polygon import *

triangle = Polygon([3, 4, 5])
print('triangle sides:', triangle.sides)
print('triangle perimeter:', triangle.perimeter)

rectangle = Polygon([4, 2, 4, 2])
print('rectangle sides:', rectangle.sides)
print('rectangle perimeter:', rectangle.perimeter)

square = Polygon([2, 2, 2, 2])
print('square sides:', square.sides)
print('square perimeter:', square.perimeter)

triangle = Triangle([3, 4, 5])
print('triangle sides:', triangle.sides)
print('triangle perimeter:', triangle.perimeter)
print('triangle area:', triangle.area)

rectangle = Rectangle([4, 2, 4, 2])
print('rectangle sides:', rectangle.sides)
print('rectangle perimeter:', rectangle.perimeter)
print('rectangle area:', rectangle.area)

square = Square([2, 2, 2, 2])
print('square sides:', square.sides)
print('square perimeter:', square.perimeter)
print('square area:', square.area)
```

## polygon.py

```import math

class Polygon(object):
"""Supports polygon calculations for perimeter and area. """

sides = []

def __init__(self, sides):
"""Creates a Polygon object.

Args:
sides (list of floats): List of lengths of each side.

Raises:
ValueError: If any side is not numeric or not positive.

"""
try:
for side in sides:
side = self._validate_side(side)
self.sides = sides
except:
raise

@property
def perimeter(self):
"""Gets perimeter of the shape.

Returns:
float: Perimeter of the shape.
"""
return sum(self.sides)

def _validate_side(self, side):
"""Validates length of a side.

Args:
side (float): length of a side

Returns:
float: validated length of the side

Raises:
ValueError: If side is not a valid float.
ValueError: If side is not positive.

"""
try:
side = float(side)
except ValueError:
raise ValueError("side must be a float. Received '" + str(side) + "'")
except:
raise

if side <= 0:
raise ValueError("side must be positive. Received %f" % side)

return side

class Triangle(Polygon):
@property
def area(self):
"""Gets area of the triangle.

Returns:
float: Area of the triangle.

References:
https://www.mathsisfun.com/geometry/herons-formula.html
"""
s = self.perimeter / 2
a = self.sides[0]
b = self.sides[1]
c = self.sides[2]
area = math.sqrt(s * (s - a) * (s - b) * (s - c))
return area

class Rectangle(Polygon):
@property
def area(self):
"""Gets area of the rectangle.

Returns:
float: Area of the rectangle.

Note:
Allows for lengths and widths to have been entered in any order.
"""
length = self.sides[0]
width = self.sides[1]
if length == width:
width = self.sides[2]
area = length * width
return area

class Square(Polygon):
@property
def area(self):
"""Gets area of the square.

Returns:
float: Area of the square.
"""
side = self.sides[0]
area = side * side
return area
```

## Try It

Copy and paste the code above into one of the following free online development environments or use your own Python3 compiler / interpreter / IDE.