Object-Oriented Programming/Polymorphism/Python3

main.py

edit
"""This program demonstrates use of the Shape, 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)
print('rectangle sides:', rectangle.sides)
print('rectangle perimeter:', rectangle.perimeter)
print('rectangle area:', rectangle.area)

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

polygon.py

edit
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):
    def __init__(self, side1, side2, side3):
        """Creates a triangle.
        
        Args:
            side1 (float): Length of side 1.
            side2 (float): Length of side 2.
            side3 (float): Length of side 3.

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

        """
        side1 = self._validate_side(side1)
        side2 = self._validate_side(side2)
        side3 = self._validate_side(side3)
        self.sides = [side1, side2, side3]


    @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):
    def __init__(self, length, width):
        """Creates a rectangle.
        
        Args:
            length (float): Length of rectangle.
            width (float): Width of rectangle.

        Raises:
            ValueError: If any side is not numeric or not positive.
        """
        length = self._validate_side(length)
        width = self._validate_side(width)
        self.sides = [length, width, length, width]


    @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):
    def __init__(self, side):
        """Creates a square.
        
        Args:
            side (float): Length of a side.

        Raises:
            ValueError: If side is not numeric or not positive.
        """
        side = self._validate_side(side)
        self.sides = [side, side, side, side]


    @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

edit

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

See Also

edit