"""Inheritance Example: Companies and Employees

=== CSC148 ===
Department of Computer Science,
University of Toronto

=== Module Description ===
This module contains an illustration of *inheritance* through an abstract
Employee class that defines a common interface for all of its subclasses.

NOTE: This is an incomplete, first version of the code, with methods but
no instance attributes. Instead, it hard-codes in specific values in methods
SalariedEmployee.get_monthly_payment and HourlyEmployee.get_monthly_payment.
"""
from datetime import date


class Employee:
    """An employee of a company.

    This is an abstract class. Only subclasses should be instantiated.
    """
    def get_monthly_payment(self) -> float:
        """Return the amount that this Employee should be paid in one month.

        Round the amount to the nearest cent.
        """
        raise NotImplementedError

    def pay(self, pay_date: date) -> None:
        """Pay this Employee on the given date and record the payment.

        (Assume this is called once per month.)
        """
        payment = self.get_monthly_payment()
        print(f'An employee was paid {payment} on {pay_date}.')


class SalariedEmployee(Employee):
    """An employee whose pay is computed based on an annual salary.
    """
    def get_monthly_payment(self) -> float:
        """Return the amount that this Employee should be paid in one month.

        Round the amount to the nearest cent.
        """
        # Assuming an annual salary of 60,000
        return round(60000.0 / 12.0, 2)


class HourlyEmployee(Employee):
    """An employee whose pay is computed based on an hourly rate.
    """
    def get_monthly_payment(self) -> float:
        """Return the amount that this Employee should be paid in one month.

        Round the amount to the nearest cent.
        """
        # Assuming a 160-hour work month and a $20/hour wage.
        return round(160.0 * 20.0, 2)


if __name__ == '__main__':
    employees = [
        SalariedEmployee(),
        HourlyEmployee(),
        SalariedEmployee()
    ]

    for employee in employees:
        employee.pay(date(2017, 9, 30))

    for e in employees:
        print(e.get_monthly_payment())
