0

I am new to Python programming and I was coding the following script to increase my understanding of Pyhton OOP.

# Python OOP
class Employee:

    num_of_emps = 0
    raise_amt = 1.04

    def __init__(self, first_name, last_name, pay):
        self.first_name = first_name
        self.last_name = last_name
        self.pay = pay
        self.email = first_name.lower() + '.' + last_name.lower() + '@company.com'
        Employee.num_of_emps += 1

    def fullname(self):
        return self.first + ' ' + self.last

    def apply_raise(self):
        self.pay = int(self.pay * self.raise_amt)

    @classmethod
    def from_string(cls, emp_str):
        name, surname, pay = emp_str.split('-')
        return cls(name, surname, pay)


class Developer(Employee):
    raise_amt = 1.01  # overriding raise_amt

    def __init__(self, first_name, last_name, pay, prog_lang=None):
        super().__init__(first_name, last_name, pay)
        self.prog_lang = prog_lang

    @classmethod
    def with_prog_lang(cls, first_name, last_name, pay, prog_lang):
        return cls(first_name, last_name, pay, prog_lang)

    @classmethod
    def from_string_kebab_case(cls, emp_str):
        first_name, last_name, pay, prog_lang = emp_str.split('-')
        return cls(first_name, last_name, pay, prog_lang)


class Manager(Employee):
    raise_amt = 1.1
    supervised_employee = []

    def __init__(self, first_name, last_name, pay, employees=None):
        super().__init__(first_name, last_name, pay)
        if employees is not None:
            self.supervised_employee.append(employees)

    def add_emp(self, employee):
        if employee not in self.supervised_employee:
            self.supervised_employee.append(employee)

    def remove_emp(self, employee):
        if employee in self.supervised_employee:
            self.supervised_employee.pop()

    def show_employees(self):
        if (len(self.supervised_employee) == 0):
            print(f"{self.first_name} is managing no one")
        else:
            print(f"{self.first_name} is managing ", end='')
            output = ''
            for emp in self.supervised_employee:
                output = output + emp + ' ,'
            print(f"{output}")


emp1 = Developer('Burak', 'Aksoy', 5000)

manager1 = Manager('Ahmet', 'Nazli', 10000, 'Burak')
manager1.add_emp('John')
manager2 = Manager('Faruk', 'Tuncer', 10000)

print(manager1.supervised_employee)
manager1.show_employees()
manager2.show_employees()

Here, I have the following output as I run the code ->

{'first_name': 'Ahmet', 'last_name': 'Nazli', 'pay': 10000, 'email': 'ahmet.nazli@company.com'}
['Burak', 'Harun']
Ahmet is managing Burak ,John ,
Faruk is managing Burak ,John ,

When I add 'Burak' and 'John' as employees to manager1, I see that manager2 is also affected by this, but I don't want this to happen.. How do you think I can fix this?

Any help is appreciated.

Best.

Burakhan Aksoy
  • 319
  • 3
  • 14
  • 1
    initialize/assign instance variable in `__init__`. Do not use mutable object, `list` this case, in class variables if not intended. – Aaron Apr 01 '21 at 20:32
  • What's the reason for not using a mutable object in constructor? – Burakhan Aksoy Apr 01 '21 at 20:33
  • You just have a single `supervised_employee` list that's shared by all the instances. You need to create a new list for each manager. – Barmar Apr 01 '21 at 20:34
  • Variable defined in constructor `__init__` are instance variables/attributes. For class variables, this reduce the chance that accidentally modify the object like your case. – Aaron Apr 01 '21 at 20:35
  • @Barmar yes, how can I do that :)) – Burakhan Aksoy Apr 01 '21 at 20:36
  • `self.supervised_employee = []` in the `__init__` method. – Barmar Apr 01 '21 at 20:37
  • The same as all your other instance attributes. – Barmar Apr 01 '21 at 20:37
  • You titled the question "how to use class attribute as instance attribute". You cannot do that - you can only *find* a class attribute by looking at the instance. The reason the problem occurs is that you are trying to use a class attribute. There is only one `Manager` class, so there is only one `Manager.supervised_employee` class attribute. If you want each manager to manage separate employees, then a class attribute is not appropriate. Use an instance attribute. – Karl Knechtel Apr 01 '21 at 20:39
  • Thank you all guys.. Appreciate the answers, please all create as an answer and I am going to upvote. – Burakhan Aksoy Apr 01 '21 at 20:44

0 Answers0