Error details PetHotel.__init__() missing 1 required positional argument: 'hotel_name'

Hi guys im a beginnerPreformatted text and i need some help.
Im trying to practise use of aggregation and i have class Pet and Pethotel as below but im getting an error. Im not sure whats missing or where im going wrong
Error details PetHotel.init() missing 1 required positional argument: ‘hotel_name’

class Pet:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age


    def get_name(self):
        return self.__name

    def set_name(self, name):
        self.__name = name

    def get_age(self):
        return self.__age

    def set_age(self, age):
        self.__age = age



class PetHotel:
    def __init__(self, hotel_name):
        self.__hotel_name = hotel_name
        self.__pets = []  # aggregation: a list of Pet objects

    def add_pet(self, pet):
        self.__pets.append(pet)

    def remove_pet(self, pet):
        self.__pets.remove(pet)

# Create pets
pet1 = Pet("Bella", 4)
pet2 = Pet("Charlie", 2)

# Create a pet hotel and add pets
hotel = PetHotel("Happy Tails")
hotel.add_pet(pet1)
hotel.add_pet(pet2)
hotel.remove_pet(pet2)

hotel.list_pets()

There’s nothing wrong in the code you’ve posted.

When I run that code it works for me up until the last line hotel.list_pets() which makes sense as there is no list_pets method in PetHotel. Can you please share the output from your run?

Error details
PetHotel.init() missing 1 required positional argument: ‘hotel_name’

that my mistake. i can see that, i wanted to get the pet list that i loaded on add_pet method.

But even when i remove that last one, i still get the error

Hello,

for your list method, you can use something like this:

    def list_pets(self):

        print('\nPets in hotel:')
        print('-------------')

        if self.__pets:

            for index, pet in enumerate(self.__pets):

                values = dict([attr for attr in pet.__dict__.items()])
                print(f'{str(index + 1) + '.'} Name: {values['_Pet__name'] :<8} Age: {values['_Pet__age']}')

        else:
            print('* There are no pets in the hotel. *')

Then, every time that you call the list_pets method, you’ll get both the name of the pet and its age.

1 Like

As others have already mentioned, running the code you posted does not produce the error you’ve indicated; which implies you must be running different code (that presumably is missing the hotel_name argument in a call to PetHotel()). Please share the code you are actually running for us to be able to help you.

1 Like

Just to note, this is unrelated to the error the OP is asking about here, and giving a full copy and paste solution to a question that was not asked may subvert the learning goal of the exercise the OP is attempting to complete here.

Furthermore, even making the unstated assumption that the intended purpose of PetHotel.list_pets() is to print to the terminal a list of pets and their age, the design in the snippit is rather inexplicable to me. Specificallly, in this bit:

I’m really struggling to understand what plausible benefit relying on extremely fragile and trivially easy to break assumptions around the contents and order of the internal attribute __dict__ brings that would outweigh the huge, obvious pitfalls of this approach, at least if you’re hardcoding the attribute names, order, etc. versus just replacing this with much simpler, more obvious and less needlessly fragile

                print(f'{index+1}. Name: {pet.get_name()} Age: {pet.get_age()}')

(Also, simplified the needlessly complex {str(index + 1) + '.'} to just {index + 1}.)

Going a step further, the above design requires PetHotel.list_pets() to be concerned with representing the details of Pet (which could change); instead, this concern should be centralized in Pet’s __str__ method (or __repr__, if appropriate), e.g.

    def __str__(self):
        return f"Name: {pet.get_name()} Age: {pet.get_age()}"

and then these lines:

            for index, pet in enumerate(self.__pets):

                values = [attr for attr in pet.__dict__.values()]
                print(f'{str(index + 1) + '.'} Name: {values[0]:<8} Age: {values[1]}')

become simply

            pets = (f'{idx+1}. {pet}' for idx, pet in enumerate(self.__pets))
            print("\n".join(pets))

(Of course, getters and setters like this are verbose and un-Pythonic vs just using properties, but that’s getting a bit beside the point).

2 Likes

The code I posted here is the actual code that I am running. I removed the list call at the end which was highligthed by DAN here on the forum to be incorrect. Please see screenshot

when debugging a failing test, it is often helpful to run the code outside of a test environment.

You have a failing test, but what you post here is a failing script.

I would recommend attempting to turn your test into a script, and trying to run it in Jupyter. Jupyter is rather nice for investigating what’s happening in code.

If you prune it down to a script that throws an error, you’ll get a better traceback than you show in the screenshot, and we’d be able to help with the script more easily than a failing test.
If you can’t replicate the failure in a script, you can post here the script code and the test function code and ask wether anyone can see what the difference is. TBH I’d recommend also asking a chatbot.

The script you posted works, but the screenshot mentions test_add_pet and test_remove_pet, which you haven’t posted. It looks like the bugs are in those 2 functions.

1 Like

Thank you so much for your response. It was successful on Google Colab and Juptyer but on the Udemy test environment it fails and it seems im not the only user with this issue

Thank you so much for your response. those are not methods but tests on the udemy exercise. It was successful on Google Colab and Juptyer but on the Udemy test environment it fails and it seems im not the only user with this issue

Lacking both the test code or the full requirements specification for the PetHotel class that you were given (that in turn motivates what is tested) we can only guess at where the code you wrote does not match those requirements.

However, given the error the test code appears to be instantiating a PetHotel without any arguments, i.e. not passing a hotel_name. Therefore, one can infer that either this argument is intended to be optional (with a default name), or not passed to the constructor at all.

You should carefully read through the requirements/problem specification you were given to determine how to correctly handle this, and any other discrepancies between the same and what you actually implemented in your code.

1 Like