Python Class-Based Objects Multiple Appending

Question:

I am trying to write a program that can automaticaly generate timeatbles using python’s oop capabilities, i have implemented objects as classes to create objects, like rooms and sessions.
Below is the code.

# The class below is a miniturized version of my code but ive extracted the important parts
class Session:
    def __init__(self, subject_name: str, room_name: str, instructor_name: str):
        self.subject_name = subject_name
        self.room_name = room_name
        self.instructor_name = instructor_name

    def __repr__(self):
        return self

    def __str__(self):
        return f'{self.subject_name} in {self.room_name} with {self.instructor_name}'

    def __del__(self):
        self.subject_name = str
        self.room_name = str
        self.instructor_name = str


# Below is a room class that takes in a title and a room capacity
class Room:
    holder = []

    def __init__(self, title: str, capacity: int):
        self.title = title
        self.capacity = capacity

    def __repr__(self):
        return self

    def __str__(self):
        return f'{self.title}:{self.capacity} with {len(self.holder)} Sessions'

    def __del__(self):
        self.capacity = int
        self.title = str
        self.holder = []

    def AddSession(self, session: Session):
        self.holder.append(session)

# Below is the main class



class Main:
    room_holder = []
    session_holder = []

    def __init__(self):
        self.GenerateData()
        self.FeedSessionsToRooms()
        self.GetStatistics()

    def GetStatistics(self):
        for room in self.room_holder:
            print(room)

    def GenerateData(self):
        """Randomly Generated Data For the Purposes of the example"""
        room_names = ["A01", "A02", "A03", "A04"]
        for room_name in room_names:
            self.room_holder.append(Room(room_name, random.choice([20, 30, 40])))
        instructor_names = ["Eric", "Julius", "Nancy", "Susan", "Steve", "Silas"]
        subject_names = ["English", "Swahili", "Physics", "Chemistry", "Biology", "French", "Mathematics", "Computer"]
        for i in range(10):
            self.session_holder.append(Session(random.choice(subject_names), random.choice(room_names), random.choice(instructor_names)))

    def FeedSessionsToRooms(self):
        for room in self.room_holder:
            for session in self.session_holder:
                if session.room_name == room.title:
                    room.AddSession(session)


Main()

Inside the Main Class, Generate Data is used to allocate data, and rooms objects are created based on their names

Session Objects are then created based on randomly generated room_names, instructor_names, and subject_names

Each Room is then allocated Sessions that are equivalent to the room title inside the FeedSessionsToRooms function in Main()

The problem though is the fact that inside the FeedSessionsToRooms Function all the room Objects inside the room_holder are allocated all sessions contrary to what I want.
So in the end all rooms get all the 10 sessions generated instead of being placed inside a specific room
in the end, I got this

I thought the problem might be in my magic method use but after going through pythons documentation on magic methods

Asked By: stephen telian

||

Answers:

In your Room class, holder is a class variable. So when you modify it in an instance, it gets modified everywhere. Check this simple example to see the difference between class and instance variables:

>>> class a:
        v1 = []
        def __init__(self):
            self.v2 = []
        
>>> a1=a()
>>> a2=a()
        
>>> a1.v1.append('xxx')
>>> a1.v1
['xxx']
>>> a2.v1
['xxx']

>>> a1.v2.append('xxx')
>>> a1.v2
['xxx']
>>> a2.v2
[]
Answered By: gimix
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.