Taking a class on Python coding and trying to use inheritance to code an answer to this problem: Write an Employee class that keeps data attributes for the following piece of information:
Employee name
Employee ID
Employee phone #
Next, write a class named ProductionWorker class should keep data attributes for the following information:
Shift number (an integer, such as 1, 2, 3)
Room (bakery, topping, Quality control)
Hourly pay rate
The workday is divided into two shifts: day and night. The shift attribute will hold an integer value representing the shift that the employee works. The day shift 1 and the night shift is shift 2. Write the appropriate accessors and mutator methods for each class.
Once you have written the classes, write a program that creates an object of the ProductionWorker class which prompts the user to enter data for each of the object's data attributes. Store the data in the object, then use the object's accessor methods to retrieve it and display it to the screen.
Why am I getting the error I described in the title?
My Code:
class Employee(object):#Creates Superclass Employeedef __init__(self,name,EmplId,EmpPhone):#Creates Employee class with several parametersself.name = name#Initial Attribute for Employee Nameself.EmplId = EmplId#Initial Attribute for Employee ID #self.EmpPhone = EmpPhone#Initial attribute for Employee Phone #class Worker(Employee):#Creates Subclass of Employee called Workerdef __init__(self,name,EmplId,ShiftNum,EmpPhone,PayRate):#Set initial state of Worker SubclassEmployee.__init__(self,name,EmplId,EmpPhone) self.ShiftNum = ShiftNum#Initial Shift number value for class Workerself.PayRate = PayRate#Initial Payrate for class Workerdef main():#Creates Main methodWorkerName = " "WorkerIDNum = " "WorkerShiftNum = 0WorkerPayRate = 0.0WorkerPhoneNum = " "#Getting data attributes to passed into Employee and Worker classesWorkerName = input("Enter the Workers name: ")WorkerIDNum = ("Enter the Workers Id Number: ")WorkerShiftNum = input ("Enter the Workers shift number (1,2,or 3): ")WorkerPayRate = input ("Enter the works payrate in dollars an cents: ")WorkerPhoneNum = input ("Enter the employees 9 Digit phone number:")worker = Employee.Worker(WorkerName,WorkerIDNum,WorkerShiftNum,WorkerPhoneNum,WorkerPayRate)#Above line creates an Instance of the Employee superclass and Worker subclass called "worker"#Values the user entered are pass in as attributes to the object.#Printing User entered informationprint("Worker information entered: ")print("Name: ", worker.name)print("EMployee ID Number: ", worker.EmplId)print("Employee Shift Number: ", worker.ShiftNum)print("Worker Hourly Payrate: $", worker.PayRate)
main()```
The solution to your problem was provided in the comments... you must instantiate only the subclass (ie. Worker
, not Employee.Worker
), but I see more problems. My example below illustrates one way to fix them. You are creating a lot of arbitrary values, and not performing any checks or limits on them. Everything comes from outside of your class and needs to be clumsily injected into the __init__
arguments. Then to print the Worker
you gather all of the data externally and format it into print statements. Why not make your classes smart enough to handle all of this internally?
To put this another way. You are basically just grabbing a bunch of junk, throwing it in a class constructor and calling it a Worker
. You should be able to just call Worker
and it handles getting, formatting and limiting everything that it expects.
Below we store all the final values in private variables. We tie all assignments to "setters" and trigger those "setters" in __init__
. This allows us to force variables to satisfy certain conditions before we accept them. It also allows us to change properties of the Worker (after instantiation) while following the exact same system.
#Creates Superclass Employee
class Employee(object):@propertydef name(self) -> str:return self.__name@name.setterdef name(self, name:str) -> None:while not name:name = input("Enter The Worker's Name: ")self.__name = name@propertydef phone(self) -> str:return self.__phone@phone.setterdef phone(self, phone) -> None:phone = f'{phone}'#get and check phonewhile not phone.isdigit() or len(phone) != 10:phone = input("Enter The Worker's 10 digit Phone Number: ")#store phone self.__phone = phone@propertydef eid(self) -> int:return self.__eid@eid.setterdef eid(self, eid) -> None:if not isinstance(eid, int):eid = f'{eid}'#get and check employee idwhile not eid.isdigit():eid = input("Enter The Worker's ID Number: ")eid = int(eid)#store idself.__eid = eiddef __init__(self):self.name, self.phone, self.eid = '', '', ''#Creates Subclass of Employee called Worker
class Worker(Employee):@propertydef shift(self) -> int:return self.__shift@shift.setterdef shift(self, shift) -> None:if not isinstance(shift, int) or (isinstance(shift, int) and shift not in (1, 2, 3)):shift = f'{shift}'#get and check shift numberwhile not shift.isdigit() or not shift in ('1', '2', '3'):shift = input("Enter The Worker's Shift Number (1, 2, 3): ")shift = int(shift)#store shiftself.__shift = shift@propertydef rate(self) -> float:return self.__rate@rate.setterdef rate(self, rate) -> None:if not isinstance(rate, (float, int)):rate = f'{rate}'#get and check pay ratewhile True:try:float(rate)breakexcept ValueError:passrate = input("Enter The Worker's Pay Rate in Dollars and Cents: ")rate = float(rate)#store rateself.__rate = ratedef __init__(self):Employee.__init__(self) self.shift, self.rate = '', ''#for printing the worker propsdef __str__(self):return f'Worker Information:\n\tname: {self.name}\n\tid: {self.eid}\n\tphone: {self.phone}\n\tshift: {self.shift}\n\trate: {self.rate}'#this is so much cleaner. Make a Worker and print the instance.
if __name__ == "__main__":worker = Worker()print(worker)