Home > front end >  Calling a list inside a class
Calling a list inside a class

Time:12-14

I am currently stuck on this problem. the answer should first print a 2 and the a 1. But I keep getting a 1 and then a 1.

Modify the classes below so that when a new instance of Pet is created, it is automatically added to its Owner's list of pets. Only classes can be modified

class Name:
    def __init__(self, first, last):
        self.first = first
        self.last = last

class Pet:
    def __init__(self, name, owner):
        self.name = name
        self.owner = owner
        
class Owner:
    def __init__(self, name):
        self.name = name
        self.pets = []


        # this is the only change that I have made to the code.
        #only chnages can be made to the code above

        self.pets.append(Pet(self, Owner).name)
      
#Answer should be
#2
#1
owner_1 = Owner(Name("David", "Joyner"))
owner_2 = Owner(Name("Audrey", "Hepburn"))

pet_1 = Pet(Name("Boggle", "Joyner"), owner_1)
pet_2 = Pet(Name("Artemis", "Joyner"), owner_1)
pet_3 = Pet(Name("Pippin", "Hepburn"), owner_2)

print(len(owner_1.pets))
print(len(owner_2.pets))

I am trying to add new pet names to the list by using append on self.pets. The Owner class already has a name parameter. so this should be able to make sure pet names are being added to the right list. my reasoning is off somewhere but I can not figure out where or why.

CodePudding user response:

You were close - the key is putting the code that updates Owner in Pet.

class Name:
    def __init__(self, first, last):
        self.first = first
        self.last = last

class Pet:
    def __init__(self, name, owner):
        self.name = name
        self.owner = owner      

        # this is the key part
        owner.pets.append(self)
        
class Owner:
    def __init__(self, name):
        self.name = name
        self.pets = []

CodePudding user response:

Identify the "trigger" and update there

So the first thing to understand here is the sequence of steps you are taking in instantiating the classes. This will tell you what is the "trigger" that should make an update to the Owners.pets list.

Here are the steps you are taking -

# Define 2 users
owner_1 = Owner(Name("David", "Joyner"))         #<-- No pets defined yet
owner_2 = Owner(Name("Audrey", "Hepburn"))       #<-- No pets defined yet

# Define 3 pets
pet_1 = Pet(Name("Boggle", "Joyner"), owner_1)   #<-- This should trigger something
pet_2 = Pet(Name("Artemis", "Joyner"), owner_1)  #<-- This should trigger something
pet_3 = Pet(Name("Pippin", "Hepburn"), owner_2)  #<-- This should trigger something

print(len(owner_1.pets))
print(len(owner_2.pets))

The steps where pets are being defined against an Owner object, is where the magic should happen. That's the trigger. Each time you define a pet, it should automatically update the Owner.pets list.

Therefore, modifying Owner class will not yield anything, since you are only defining the Owner objects as the first 2 steps before even the pets are created. Here is a solution -

class Name:
    def __init__(self, first, last):
        self.first = first
        self.last = last

class Pet:
    def __init__(self, name, owner):  #<-- This __init__ should trigger an update
        self.name = name
        self.owner = owner            #<-- After the "Owner" is defined
        self.owner.pets.append(self)  #<-- Update pets from Owner class
        
class Owner:
    def __init__(self, name):
        self.name = name
        self.pets = []
        
        #This wont help, because Owners are defined before pets
        #Also, this creates a "garbage" pet object which is not defined by your code
        #self.pets.append(Pet(self, Owner).name)

owner_1 = Owner(Name("David", "Joyner"))
owner_2 = Owner(Name("Audrey", "Hepburn"))

pet_1 = Pet(Name("Boggle", "Joyner"), owner_1)
pet_2 = Pet(Name("Artemis", "Joyner"), owner_1)
pet_3 = Pet(Name("Pippin", "Hepburn"), owner_2)

print(len(owner_1.pets))
print(len(owner_2.pets))
2
1

Analysing updates to the list

You can actually analyze the self of an object by printing the object.__dict__ before and after your code has run.

Here is how you can debug -

print('BEFORE DEFINING PETS')
owner_1 = Owner(Name("David", "Joyner"))
owner_2 = Owner(Name("Audrey", "Hepburn"))
print(owner_1.__dict__)
print(owner_2.__dict__)
print('')

print('ADDING PET 1')
pet_1 = Pet(Name("Boggle", "Joyner"), owner_1)
print(owner_1.__dict__)
print(owner_2.__dict__)
print('')

print('ADDING PET 2')
pet_2 = Pet(Name("Artemis", "Joyner"), owner_1)
print(owner_1.__dict__)
print(owner_2.__dict__)
print('')

print('ADDING PET 3')
pet_3 = Pet(Name("Pippin", "Hepburn"), owner_2)
print(owner_1.__dict__)
print(owner_2.__dict__)
BEFORE DEFINING PETS
{'name': <__main__.Name object at 0x145542590>, 'pets': []}
{'name': <__main__.Name object at 0x145541e10>, 'pets': []}
#0 pets for owner 1, 0 for owner 2

ADDING PET 1  
{'name': <__main__.Name object at 0x145542590>, 'pets': [<__main__.Pet object at 0x145543d30>]}
{'name': <__main__.Name object at 0x145541e10>, 'pets': []}
#1 pet for owner 1, 0 for owner 2

ADDING PET 2
{'name': <__main__.Name object at 0x145542590>, 'pets': [<__main__.Pet object at 0x145543d30>, <__main__.Pet object at 0x1433aada0>]}
{'name': <__main__.Name object at 0x145541e10>, 'pets': []}
#2 pets for owner 1, 0 for owner 2

ADDING PET 3
{'name': <__main__.Name object at 0x145542590>, 'pets': [<__main__.Pet object at 0x145543d30>, <__main__.Pet object at 0x1433aada0>]}
{'name': <__main__.Name object at 0x145541e10>, 'pets': [<__main__.Pet object at 0x145539c00>]}
##2 pets for owner 1, 1 for owner 2
  • Related