-2

According to me, the child class can access the variables of the parent class. But I am not able to do so.

Parent Class

class Room:

    rooms = {}

    def __init__(self):
        self.roomno = 0
        self.rcap = 0

    def addRoom(self):
        self.rcap = input("Please enter room capacity:\n")
        self.rooms[self.roomno] = self.rcap

Child Class

class Booking(Room):

    def __init__(self):
        self.nog = 0

    def addBooking(self):
        global status
        rno = input("Please enter room number:\n")
        self.roomcheck(rno)
        while status is False:
            self.nog = input("Please enter number of guests:\n")
            while int(self.nog) > int(self.rcap):
                print("Guest count exceeds room capacity of: %d" % int(self.rcap))

Main Menu

z = Booking()

def mainMenu():
    choice = input()
    if choice == '2':
        z.addRoom()

mainMenu()

I am getting an error as follows:

File "D:/hotel/hotel6.py", line 159, in addBooking
    while int(self.nog) > int(self.rcap):
AttributeError: 'Booking' object has no attribute 'rcap'
Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117
Jaskaran Singh
  • 85
  • 1
  • 1
  • 12
  • Possible duplicate of [Access parent class instance attribute from child class instance?](https://stackoverflow.com/questions/10909032/access-parent-class-instance-attribute-from-child-class-instance) – Chris Sep 28 '17 at 13:05
  • But I am already doing what is explained in the above link. Still, it's not working. – Jaskaran Singh Sep 28 '17 at 13:08
  • I was briefly confused because you have mis-labelled your "child" and "parent" classes (a **child** class *inherits from* a **parent** class, so `Booking` is the child). – larsks Sep 28 '17 at 13:09
  • Also, this isn't valid Python code. You can't have a `while` statement in a class outside of a function. And where is the variable `z` coming from? – larsks Sep 28 '17 at 13:10
  • @larsks Thanks, corrected! – Jaskaran Singh Sep 28 '17 at 13:10
  • Why is the while loop referring to `self` if it's not in an instance method? Are you sure that this is the code causing the problem? (The line number in the error message would imply that this isn't your full code) – Izaak van Dongen Sep 28 '17 at 13:10
  • @larsks This was inside a function only, I edited the code now. Still, the same. – Jaskaran Singh Sep 28 '17 at 13:12
  • @IzaakvanDongen Yes, I am sure this the line causing problem and can you correct the code? – Jaskaran Singh Sep 28 '17 at 13:13
  • 3
    I feel like this is a misplaced use of object inheritance - a booking isn't a type of room so why does booking inherit from room? – Izaak van Dongen Sep 28 '17 at 13:13
  • 1
    When posting questions about your code, it really helps to make sure that you have posted a runnable example that clearly demonstrates the problem. See https://stackoverflow.com/help/mcve for some suggestions. – larsks Sep 28 '17 at 13:14
  • @IzaakvanDongen Because booking needs to access some variables from room, such as room number and room capacity – Jaskaran Singh Sep 28 '17 at 13:14
  • @JaskaranSingh That doesn't mean inheritance is appropriate. `addBooking` should simply be a method of `Room`. For that matter, `Room` doesn't appear to model a single room, but a *collection* of rooms. – chepner Sep 28 '17 at 13:22
  • 1
    Are you sure this is the exact code that produces your problem? My guess is that `Booking` has an `__init__` method that isn't explicitly calling `Room.__init__`. (Which I see is also mentioned in a deleted answer.) – chepner Sep 28 '17 at 13:23
  • **I have changed my code to a running one now. Added the exact code.** – Jaskaran Singh Sep 28 '17 at 13:29
  • @JaskaranSingh Generally by "running" we mean "I could copy/paste this into my text editor of choice and execute it and immediately see what your problem is". This isn't true of what you've got here, as you're not initializing or calling anything and your second "class" is just a function. – Izaak van Dongen Sep 28 '17 at 13:31
  • @IzaakvanDongen I am sorry, I am a beginner to Python and I didn't understand most of the things in the code that you answered below. But I really need to submit this today. Also, I changed the code now. – Jaskaran Singh Sep 28 '17 at 13:38

2 Answers2

0

I can't reproduce your problem. I had to modify your example code a bit because it was missing some variables, so it looks like:

class Room:                                                                     

    def __init__(self):                                                         
        self.roomno = 0                                                         
        self.rcap = 0                                                           
        self.rooms = {}                                                         
        self.nog = 10                                                            

    def addRoom(self):                                                          
        self.rcap = input("Please enter room capacity:\n")                      
        self.rooms[self.roomno] = self.rcap                                     

class Booking(Room):                                                            
    def addBooking(self):                                                       
        while int(self.nog) > int(self.rcap):                                   
            print("Guest count exceeds room capacity of: %d" % int(self.rcap))  

x = Booking()
x.addRoom()
x.addBooking()

If I run this, I get:

Please enter room capacity:
5
Guest count exceeds room capacity of: 5

Of course, the last line repeats forever because you have an infinite loop there, but there are no issues with variable access.

larsks
  • 277,717
  • 41
  • 399
  • 399
0

Inheritance should only be used if something is actually the same kind of object conceptually as something else. A booking is not a room, so inheritance makes no sense here. I also don't know what the deal is with Room.rooms, whether this is some kind of funky static variable or a misused instance variable - in any case, for code like this, Room should have to keep track of rooms - this should be done by another class (Hotel, maybe). A better model of rooms and bookings etc might look something like this:

class Hotel:
    def __init__(self):
        self.rooms = {}

    def add_room(self, room):
        self.rooms[room.number] = room

    @classmethod
    def from_rooms(cls, rooms):
        self = Hotel()
        for r in rooms:
            self.add_room(r)
        return self

    def __str__(self):
        return "Hotel with rooms:\n{}".format("\n".join(map(str, self.rooms.values())))

class Room:
    def __init__(self, number, capacity):
        self.number = number
        self.capacity = capacity

    def __str__(self):
        return "Room {} ({} people)".format(self.number, self.capacity)

class RoomFullError(Exception):
    pass

class Booking:
    def __init__(self, room, guests):
        if guests > room.capacity:
            raise RoomFullError("This room can only have {} guests, not {}".format(room.capacity, guests))
        else:
            self.room = room
            self.guests = guests

    def __str__(self):
        return "Booking for {} guests at room ({})".format(self.guests, self.room)

h = Hotel.from_rooms([Room("001", 3), Room("123", 10)])
h.add_room(Room("666", 1))
print(h)
print(h.rooms["001"])
b = Booking(h.rooms["001"], 2)
print(b)
Booking(h.rooms["123"], 500)

This will output:

Hotel with rooms:
Room 001 (3 people)
Room 123 (10 people)
Room 666 (1 people)
Room 001 (3 people)
Booking for 2 guests at room (Room 001 (3 people))
Traceback (most recent call last):
  File "code.py", line 46, in <module>
    Booking(h.rooms["123"], 500)
  File "code.py", line 32, in __init__
    raise RoomFullError("This room can only have {} guests, not {}".format(room.capacity, guests))
__main__.RoomFullError: This room can only have 10 guests, not 500

NB the Booking still has access to a Room without inheriting from it, just because it is passed a Room in its __init__.

This is just a rough outline of what you might do, as I don't know the full details of your project. You should probably have a method for Hotel that handles and stores bookings, or something. The important thing to take away is that nothing needs to inherit from anything here, and you should define separate classes that have instances of other classes as properties.

Izaak van Dongen
  • 2,450
  • 13
  • 23