# employee.py # Walker M. White (wmw2) # November 1, 2013 """Module with two classes to show off inheritance This version of employee shows off properties and inheritance""" class Employee(object): """Instance is an employee with a salary. INSTANCE ATTRIBUTES: _name: Employee's name [string, not empty] _start: Year hired [int > 1970; -1 if undefined] _salary: Salary [int or float >= 0] """ # PROPERTIES @property def name(self): """The employee's name. Invariant: A string. Cannot be empty.""" return self._name @name.setter def name(self,value): assert type(value) == str and value != '', `value`+' is an invalid name' self._name = value @property def start(self): """The year hired. Invariant: An int > 1970, or -1 if undefined.""" return self._start @start.setter def start(self,value): assert type(value) == int, `value`+' is not an int' assert value > 1970 or value == -1, `value`+' is an invalid start date' self._start = value @property def salary(self): """Annual salary Invariant: A number (int or float) >= 0.""" return self._salary @salary.setter def salary(self,value): assert type(value) == int or type(value) == float, `value`+' is not a number' assert value >= 0, `value`+' is negative' self._salary = value @property def compensation(self): """Annual compensation. Read only property.""" return self.salary # INITIALIZER def __init__(self, n, d=-1, s=50000.0): """Initializer: Makes an Employee with name n, year hired d, salary s Preconditions: n is a nonempty string d is an int > 1970 or -1 if undefined (default) s is an int or float >= 0 (50000.0 default) """ # LET THE SETTERS ENFORCE THE PRECONDITIONS self.name = n self.start = d # HAVE TO TREAT SALARY DIFFERENTLY IN THIS CASE assert type(s) == int or type(s) == float, `s`+' is not a number' assert s >= 0, `s`+' is negative' self._salary = s # OPERATIONS def __str__(self): """Return: String representation of this Employee""" return self.name + ', year ' + str(self.start) + ', salary ' + str(self.salary) def __eq__(self,other): """Return: True if e an Employee, with the same attributes as self. False otherwise.""" # Check if this is an Employee if not isinstance(other,Employee): # WILL DISCUSS NEXT LECTURE return False return (self.name == other.name and self.start == other.start and self.salary == other.salary) def __ne__(self,other): """Return: False if e an Employee, with the same attributes as self. True otherwise.""" return not self == other # SUBCLASS class Executive(Employee): """An instance is an Employee with a bonus. INSTANCE ATTRIBUTES: _bonus: annual bonus [float >= 0] """ # PROPERTIES @property def bonus(self): """Bonus salary. Invariant: A number (int or float) >= 0.""" return self._bonus @bonus.setter def bonus(self,value): assert type(value) == int or type(value) == float, `value`+' is not a number' assert value >= 0, `value`+' is negative' self._bonus = value # Override compensation. @property def compensation(self): """Annual compensation. Read only property.""" return self.salary+self.bonus # Override salary to be read-only. @property def salary(self): return self._salary # NO SETTER. MAKES SALARY READ ONLY # INITIALIZER def __init__(self, n, d, b=0.0): """Initializer: Make an Executive w/ name n, year hired d, and bonus b The default salary of an executive is 50k Preconditions: n is a nonempty string d is an int > 1970 or -1 if undefined (default) b is an int or float >= 0 (0.0 default) """ # Asserts precondition for n and d super(Executive,self).__init__(n,d) self.bonus = b def __str__(self): """Return: a string representation of this Executive""" # Add on to the string representation of the base class. return Employee.__str__(self) + ', bonus ' + str(self.bonus) def __eq__(self,other): """Return: True if e an Executive, with the same attributes as self. False otherwise.""" # Check if this is an Executive if not isinstance(other,Executive): # WILL DISCUSS NEXT LECTURE return False # Use previous __eq__ as helper return Employee.__eq__(self,other) and self.bonus == other.bonus