Python Forum
PayrollSystem with file handling
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PayrollSystem with file handling
#1
I have a problem in exercise. I tried ai, to solve it but the issue didn't go away. Here you can find my code, expected output and my output. I always have Incorrect output: program printed "2500", but should have printed "3277"
Expected output:
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 1
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
1
Please enter employee name:Jane Doe
Please enter monthly salary:5555
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
2
Please enter employee name:John Johnson
Please enter hours worked:45
Please enter hour rate:60
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
3
Please enter employee name:Richard Roe
Please enter monthly salary:2500
Please enter commission:777
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
0
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 4
Employee Payroll
================
Payroll for: 1 - Jane Doe
- Check amount: 5555

Employee Payroll
================
Payroll for: 2 - John Johnson
- Check amount: 2700

Employee Payroll
================
Payroll for: 3 - Richard Roe
- Check amount: 3277

(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 2
3 employee(s) added to employee.csv
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 3
3 employee(s) read from employee.csv
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 1
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
2
Please enter employee name:Mark Moe
Please enter hours worked:15
Please enter hour rate:30
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
0
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 4
Employee Payroll
================
Payroll for: 1 - Jane Doe
- Check amount: 5555

Employee Payroll
================
Payroll for: 2 - John Johnson
- Check amount: 2700

Employee Payroll
================
Payroll for: 3 - Richard Roe
- Check amount: 3277

Employee Payroll
================
Payroll for: 4 - Mark Moe
- Check amount: 450

(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 0
Service shutting down, thank you.


my output:
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 1
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
1
Please enter employee name:Jane Doe
Please enter monthly salary:5555
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
2
Please enter employee name:John Johnson
Please enter hours worked:45
Please enter hour rate:60
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
3
Please enter employee name:Richard Roe
Please enter monthly salary:2500
Please enter commission:777
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
0
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 4
Employee Payroll
================
Payroll for: 1 - Jane Doe
- Check amount: 5555

Employee Payroll
================
Payroll for: 2 - John Johnson
- Check amount: 2700

Employee Payroll
================
Payroll for: 3 - Richard Roe
- Check amount: 3277

(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 2
3 employee(s) added to employee.csv
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 3
3 employee(s) read from employee.csv
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 1
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
2
Please enter employee name:Mark Moe
Please enter hours worked:15
Please enter hour rate:30
Please enter salary type:
(1) monthly
(2) hourly
(3) commission
(0) Quit
0
(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 4
Employee Payroll
================
Payroll for: 1 - Jane Doe
- Check amount: 5555

Employee Payroll
================
Payroll for: 2 - John Johnson
- Check amount: 2700

Employee Payroll
================
Payroll for: 3 - Richard Roe
- Check amount: 2500

Employee Payroll
================
Payroll for: 4 - Mark Moe
- Check amount: 450

(1) Add employee to employees
(2) Write employees to file
(3) Read employees from file
(4) Print payroll
(0) Quit

Please select one: 0
Service shutting down, thank you.




my code:
def my_split(sentence, sep):
    lst = []
    tmp = ''
    for c in sentence:
        if c == sep:
            lst.append(tmp)
            tmp = ''
        else:
            tmp += c
    if tmp:
        lst.append(tmp)
    return lst
def my_join(lst, sep):
    mystr = ''
    for elem in lst[0:-1]:
        mystr += str(elem) + str(sep)
    mystr += str(lst[-1])
    return mystr

class PayrollSystem:
    def calculate_payroll(self, employeelist):
        for employee in employeelist:
            print('Employee Payroll')
            print('================')
            print(f'Payroll for: {employee.id} - {employee.name}')
            print(f'- Check amount: {employee.calculate_payroll()}')
            print('')

class Employee:
    def __init__(self, id, name):
        self.id = id
        self.name = name

    def ask_name(self):
        try:
            self.name = str(input("Please enter employee name:"))
        except ValueError:
            self.name = ''

class SalaryEmployee(Employee):
    def __init__(self, id, name, monthly_salary):
        super().__init__(id, name)
        self.salary_type = 'M'
        self.monthly_salary = int(monthly_salary)

    def ask_salary(self):
        try:
            self.monthly_salary = int(input("Please enter monthly salary:"))
        except ValueError:
            self.monthly_salary = 0

    def calculate_payroll(self):
        return self.monthly_salary

class CommissionEmployee(SalaryEmployee):
    def __init__(self, id, name, monthly_salary, commission):
        super().__init__(id, name, monthly_salary)
        self.commission = commission

    def ask_salary(self):
        super().ask_salary()
        try:
            self.commission = int(input('Please enter commission:'))
        except ValueError:
            print("Invalid commission value. Defaulting to 0.")
            self.commission = 0

    def calculate_payroll(self):
        total_payment = self.monthly_salary + self.commission
        return total_payment

class HourlyEmployee(Employee):
    def __init__(self, id, name, hours_worked=0, hour_rate=0):
        super().__init__(id, name)
        self.hours_worked = hours_worked
        self.hour_rate = hour_rate

    def ask_salary(self):
        try:
            self.hours_worked = int(input('Please enter hours worked:'))
            self.hour_rate = int(input('Please enter hour rate:'))
        except ValueError:
            self.hours_worked = 0
            self.hour_rate = 0
            print("Invalid input. Please enter a valid number.")

    def calculate_payroll(self):
        return self.hour_rate * self.hours_worked

def main():
    employeelist = []
    id_counter = 1

    while True:
        print("(1) Add employee to employees")
        print("(2) Write employees to file")
        print("(3) Read employees from file")
        print("(4) Print payroll")
        print("(0) Quit\n")

        selection = input("Please select one: ")

        if selection == '1':
            while True:
                salary_type = input("Please enter salary type:\n(1) monthly\n(2) hourly\n(3) commission\n(0) Quit\n")

                if salary_type == '0':
                    break

                if salary_type == '1':
                    employee = SalaryEmployee(id_counter, '', 0)
                    employee.ask_name()
                    employee.ask_salary()
                    employeelist.append(employee)
                    id_counter += 1

                elif salary_type == '2':
                    employee = HourlyEmployee(id_counter, '', 0, 0)
                    employee.ask_name()
                    employee.ask_salary()
                    employeelist.append(employee)
                    id_counter += 1

                elif salary_type == '3':
                    employee = CommissionEmployee(id_counter, '', 0, 0)
                    employee.ask_name()
                    employee.ask_salary()
                    employeelist.append(employee)
                    id_counter += 1
                else:
                    print("Incorrect selection.")

        elif selection == '2':
            try:
                file = open("employee.csv", "w")
                for employee in employeelist:
                    if isinstance(employee, SalaryEmployee):
                        employee_attributes_list = [employee.id, employee.name, employee.monthly_salary]
                    elif isinstance(employee, HourlyEmployee):
                        employee_attributes_list = [employee.id, employee.name, employee.hours_worked, employee.hour_rate]
                    elif isinstance(employee, CommissionEmployee):
                        employee_attributes_list = [employee.id, employee.name, employee.monthly_salary, employee.commission]
                    
                    employee_attributes_str = my_join(employee_attributes_list, ',')
                    file.write(f"{employee_attributes_str}\n")
                file.close()
                print(len(employeelist), " employee(s) added to employee.csv")
            except IOError:
                print("Error writing to file")

        elif selection == '3':
            try:
                file = open("employee.csv", 'r')
                employeelist = []
                for line in file:
                    attributes = my_split(line.strip(), ',')
                    if len(attributes) == 3:
                        employeelist.append(SalaryEmployee(int(attributes[0]), attributes[1], int(attributes[2])))
                    elif len(attributes) == 4:
                        if attributes[2].isdigit() and attributes[3].isdigit():
                            employeelist.append(HourlyEmployee(int(attributes[0]), attributes[1], int(attributes[2]), int(attributes[3])))
                        elif attributes[2].isdigit() and attributes[3].isdigit():
                            employeelist.append(CommissionEmployee(int(attributes[0]), attributes[1], int(attributes[2]), int(attributes[3])))
                file.close()
                print(len(employeelist), " employee(s) read from employee.csv")
            except IOError:
                print("Error reading from file")

        elif selection == '4':
            payroll_system = PayrollSystem()
            payroll_system.calculate_payroll(employeelist)

        elif selection == '0':
            print("Service shutting down, thank you.")
            break

        else:
            print("Incorrect selection.")

if __name__ == "__main__":
    main()
deanhystad write Apr-29-2024, 01:46 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#2
You do not save enough information in the csv file. There is no way to differentiate between commissioned and hourly employees. I would save all five employee fields PLUS a field identifying the employee wage type ("salary", "commission", "hourly"). This will make it easy to determine what class to use when loading employee data from the file.

All that code in main() should be part of PayrollSystem. I would expect main() to look more like this:
def main():
    payroll = PayrollSystem()
    payroll.restore()  # Restore from file at startup.
    while True:
        print("Options\n(1) Add employees\n(2) Print payroll\n(3) Quit")
        match input("Enter: "):
            case "1":
                payroll.add_employee()  # Add 1 employee
                payroll.save()  # Save updated employee list.
            case "2":
                payroll.print()
            case "3":
                break
case _:
print("Invalid selection.")
PayrollSystem should have the brains and the most main needs to do is provide a way to call the methods provided by the PayrollSystem.

Your Employee classes are backward. Your subclasses do most of the work, and the base class does almost nothing. Your base class should do most of the work, and the subclasses do only the parts that are specific to that class. The more work you can push up from subclasses to parent classes, the better the design (usually). As an example, the following method could be added to the Employee class and used to calculate pay for any employee.
    def pay(self):
        """Calculate employee pay."""
        return self.salary + self.commission + self.rate * self.hours
Salaried employees will have 0 for commission, rate and hours. Hourly employees will have 0 for salary and commission.
nikadry1 likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Handling IO Error / Reading from file Expel 10 4,979 Jul-18-2019, 01:21 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020