CommissionEmployee
¶Class CommissionEmployee
provides the following features:
__init__
creates the data attributes _first_name
, _last_name
and _ssn
(Social Security number), and uses the setter's of properties gross_sales
and commission_rate
to create their corresponding data attributesfirst_name
, last_name
and ssn
, which return the corresponding data attributesgross_sales
and commission_rate
in which the setter
s perform data validationearnings
, which calculates and returns a CommissionEmployee
’s earnings__repr__
, which returns a string representation of a CommissionEmployee
# commmissionemployee.py
"""CommissionEmployee base class."""
from decimal import Decimal
class CommissionEmployee:
"""An employee who gets paid commission based on gross sales."""
def __init__(self, first_name, last_name, ssn,
gross_sales, commission_rate):
"""Initialize CommissionEmployee's attributes."""
self._first_name = first_name
self._last_name = last_name
self._ssn = ssn
self.gross_sales = gross_sales # validate via property
self.commission_rate = commission_rate # validate via property
@property
def first_name(self):
return self._first_name
@property
def last_name(self):
return self._last_name
@property
def ssn(self):
return self._ssn
@property
def gross_sales(self):
return self._gross_sales
@gross_sales.setter
def gross_sales(self, sales):
"""Set gross sales or raise ValueError if invalid."""
if sales < Decimal('0.00'):
raise ValueError('Gross sales must be >= to 0')
self._gross_sales = sales
@property
def commission_rate(self):
return self._commission_rate
@commission_rate.setter
def commission_rate(self, rate):
"""Set commission rate or raise ValueError if invalid."""
if not (Decimal('0.0') < rate < Decimal('1.0')):
raise ValueError(
'Interest rate must be greater than 0 and less than 1')
self._commission_rate = rate
def earnings(self):
"""Calculate earnings."""
return self.gross_sales * self.commission_rate
def __repr__(self):
"""Return string representation for repr()."""
return ('CommissionEmployee: ' +
f'{self.first_name} {self.last_name}\n' +
f'social security number: {self.ssn}\n' +
f'gross sales: {self.gross_sales:.2f}\n' +
f'commission rate: {self.commission_rate:.2f}')
object
¶object
CommissionEmployee
’s header could have been written asclass CommissionEmployee(object):
CommissionEmployee
indicate inheritance and may contain object
(cont.)¶CommissionEmployee
inherits all the methods of class object
object
are __repr__
and __str__
__repr__
overrides the default implementation from class object
CommissionEmployee
¶CommissionEmployee
’s featuresfrom commissionemployee import CommissionEmployee
from decimal import Decimal
c = CommissionEmployee('Sue', 'Jones', '333-33-3333',
Decimal('10000.00'), Decimal('0.06'))
c
CommissionEmployee
’s earningsprint(f'{c.earnings():,.2f}')
CommissionEmployee
’s gross sales and commission rate, then recalculate the earningsc.gross_sales = Decimal('20000.00')
c.commission_rate = Decimal('0.1')
print(f'{c.earnings():,.2f}')
SalariedCommissionEmployee
¶SalariedCommissionEmployee
’s capabilities are similar, if not identical, to those of class CommissionEmployee
SalariedCommissionEmployee
¶SalariedCommissionEmployee
inherits most of its capabilities from class CommissionEmployee
SalariedCommissionEmployee
is a CommissionEmployee
(because inheritance passes on the capabilities of class CommissionEmployee
)SalariedCommissionEmployee
also has the following features:__init__
, which initializes all the data inherited from class CommissionEmployee
, then uses the base_salary
property’s setter
to create a _base_salary
data attributebase_salary
, in which the setter
performs data validation.earnings
__repr__
# salariedcommissionemployee.py
"""SalariedCommissionEmployee derived from CommissionEmployee."""
from commissionemployee import CommissionEmployee
from decimal import Decimal
class SalariedCommissionEmployee(CommissionEmployee):
"""An employee who gets paid a salary plus
commission based on gross sales."""
def __init__(self, first_name, last_name, ssn,
gross_sales, commission_rate, base_salary):
"""Initialize SalariedCommissionEmployee's attributes."""
super().__init__(first_name, last_name, ssn,
gross_sales, commission_rate)
self.base_salary = base_salary # validate via property
@property
def base_salary(self):
return self._base_salary
@base_salary.setter
def base_salary(self, salary):
"""Set base salary or raise ValueError if invalid."""
if salary < Decimal('0.00'):
raise ValueError('Base salary must be >= to 0')
self._base_salary = salary
def earnings(self):
"""Calculate earnings."""
return super().earnings() + self.base_salary
def __repr__(self):
"""Return string representation for repr()."""
return ('Salaried' + super().__repr__() +
f'\nbase salary: {self.base_salary:.2f}')
CommissionEmployee
¶class SalariedCommissionEmployee(CommissionEmployee):
SalariedCommissionEmployee
inherits from CommissionEmployee
CommissionEmployee
’s data attributes, properties and methods in class SalariedCommissionEmployee
, but they are there__init__
and Built-In Function super
¶__init__
must explicitly call its base class’s __init__
to initialize the data attributes inherited from the base class__init__
methodsuper().__init__
uses the built-in function super
to locate and call the base class’s __init__
methodearnings
¶SalariedCommissionEmployee
’s earnings
method overrides class CommissionEmployee
’s earnings
method to calculate the earnings of a SalariedCommissionEmployee
CommissionEmployee
’s earnings
method with the expression super().earnings()
__repr__
¶SalariedCommissionEmployee
’s __repr__
method overrides class CommissionEmployee
’s __repr__
method to return a String
representation that’s appropriate for a SalariedCommissionEmployee
super().__repr__()
calls CommissionEmployee
's __repr__
methodSalariedCommissionEmployee
¶from salariedcommissionemployee import SalariedCommissionEmployee
s = SalariedCommissionEmployee('Bob', 'Lewis', '444-44-4444',
Decimal('5000.00'), Decimal('0.04'), Decimal('300.00'))
print(s.first_name, s.last_name, s.ssn, s.gross_sales,
s.commission_rate, s.base_salary)
SalariedCommissionEmployee
object has all of the properties of classes CommissionEmployee
and SalariedCommissionEmployee
SalariedCommissionEmployee
’s earningsprint(f'{s.earnings():,.2f}')
gross_sales
, commission_rate
and base_salary
properties, then display the updated data via the SalariedCommissionEmployee
’s __repr__
methods.gross_sales = Decimal('10000.00')
s.commission_rate = Decimal('0.05')
s.base_salary = Decimal('1000.00')
print(s)
SalariedCommissionEmployee
’s updated earningsprint(f'{s.earnings():,.2f}')
Functions issubclass
and isinstance
are used to test “is a” relationships
issubclass
determines whether one class is derived from anotherissubclass(SalariedCommissionEmployee, CommissionEmployee)
isinstance
determines whether an object has an “is a” relationship with a specific typeisinstance(s, CommissionEmployee)
isinstance(s, SalariedCommissionEmployee)
CommissionEmployee
s and SalariedCommissionEmployee
s Polymorphically¶employees = [c, s]
for employee in employees:
print(employee)
print(f'{employee.earnings():,.2f}\n')
©1992–2020 by Pearson Education, Inc. All Rights Reserved. This content is based on Chapter 5 of the book Intro to Python for Computer Science and Data Science: Learning to Program with AI, Big Data and the Cloud.
DISCLAIMER: The authors and publisher of this book have used their best efforts in preparing the book. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. The authors and publisher make no warranty of any kind, expressed or implied, with regard to these programs or to the documentation contained in these books. The authors and publisher shall not be liable in any event for incidental or consequential damages in connection with, or arising out of, the furnishing, performance, or use of these programs.