forked from ArjanCodes/2021-composition-vs-inheritance
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwith_composition.py
113 lines (80 loc) · 2.87 KB
/
with_composition.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""
Very advanced Employee management system.
"""
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional
class Contract(ABC):
"""Represents a contract anda payment process for a particular employeee."""
@abstractmethod
def get_payment(self) -> float:
"""Compute how much to pay an employee under this contract."""
@dataclass
class Commission(ABC):
"""Represents a commission payment process."""
@abstractmethod
def get_payment(self) -> float:
"""Returns the commission to be paid out."""
@dataclass
class ContractCommission(Commission):
"""Represents a commission payment process based on the number of contracts landed."""
commission: float = 100
contracts_landed: int = 0
def get_payment(self) -> float:
"""Returns the commission to be paid out."""
return self.commission * self.contracts_landed
@dataclass
class Employee:
"""Basic representation of an employee at the company."""
name: str
id: int
contract: Contract
commission: Optional[Commission] = None
def compute_pay(self) -> float:
"""Compute how much the employee should be paid."""
payout = self.contract.get_payment()
if self.commission is not None:
payout += self.commission.get_payment()
return payout
@dataclass
class HourlyContract(Contract):
"""Contract type for an employee being paid on an hourly basis."""
pay_rate: float
hours_worked: int = 0
employer_cost: float = 1000
def get_payment(self) -> float:
return self.pay_rate * self.hours_worked + self.employer_cost
@dataclass
class SalariedContract(Contract):
"""Contract type for an employee being paid a monthly salary."""
monthly_salary: float
percentage: float = 1
def get_payment(self) -> float:
return self.monthly_salary * self.percentage
@dataclass
class FreelancerContract(Contract):
"""Contract type for a freelancer (paid on an hourly basis)."""
pay_rate: float
hours_worked: int = 0
vat_number: str = ""
def get_payment(self) -> float:
return self.pay_rate * self.hours_worked
def main() -> None:
"""Main function."""
henry_contract = HourlyContract(pay_rate=50, hours_worked=100)
henry = Employee(name="Henry", id=12346, contract=henry_contract)
print(
f"{henry.name} worked for {henry_contract.hours_worked} hours "
f"and earned ${henry.compute_pay()}."
)
sarah_contract = SalariedContract(monthly_salary=5000)
sarah_commission = ContractCommission(contracts_landed=10)
sarah = Employee(
name="Sarah", id=47832, contract=sarah_contract, commission=sarah_commission
)
print(
f"{sarah.name} landed {sarah_commission.contracts_landed} contracts "
f"and earned ${sarah.compute_pay()}."
)
if __name__ == "__main__":
main()