7
\$\begingroup\$

I am trying to teach myself OOP in Python. I am picking up some projects from GitHub and trying it out on my own. I wrote a Airline/Hotel Reservation System, where I want to maintain the customer name, ID and maintain a record for Airline or Hotel or Both. I am not sure if my design is correct. I want some input on how to improve the design for my code.

class Reservation:
   def __init__(self,passenger_id,passenger_fname,passenger_lname):
      self.passenger_id = passenger_id
      self.passenger_fname = passenger_fname
      self.passenger_lname = passenger_lname
      self.cost = 0
      self.reservation_id = []
      self.passenger_record = {'p_name'  : self.passenger_fname + self.passenger_lname,
                             'p_id'    : self.passenger_id,
                             'p_wallet': self.cost,
                             'p_reservation_id': self.reservation_id,
                            }
      self.airline_seats = { 'Business Class' : 50,
                           'First Class'    : 50,
                           'Premium Economy': 100,
                           'Regular Economy': 150 }
      self.airline_price = { 'Business Class' : 2500,
                           'First Class'    : 2000,
                           'Premium Economy': 1800,
                           'Regular Economy': 1500 }
      self.hotel_room = {'Penthouse'             : 10,
                       'King Deluxe Bedroom'    : 20,
                       'Queen Deluxe Bedroom'   : 20,
                       'Kind Standard Bedroom' : 30,
                       'Queen Standard Bedroom': 50 }
      self.hotel_price = {'Penthouse'            : 1000,
                        'King Deluxe Bedroom'    : 700,
                        'Queen Deluxe Bedroom'   : 600,
                        'Kind Standard Bedroom' : 450,
                        'Queen Standard Bedroom': 350 }
   def currentStatus(self,option):
       if option == "Airline":
           for key, value in self.airline_seats.items():
              print key, value
       elif option == "Hotel":
           for key,value in self.hotel_room.items():
              print key, value

   def Total(self):
       print self.passenger_record['p_wallet']

class Airline(Reservation):
   def __init__(self,passenger_id,passenger_fname,passenger_lname,airline_seat_section,
         airline_departure_date):
       Reservation.__init__(self,passenger_id,passenger_fname,passenger_lname)
       self.airline_seat_section = airline_seat_section
       self.airline_departure_date = airline_departure_date

   def CheckAvailability(self):
       if  (self.airline_seats.get(self.airline_seat_section) != 0):
            self.airline_seats[self.airline_seat_section] -= 1
            self.passenger_record['p_wallet'] +=        self.airline_price[self.airline_seat_section]
            print "\n\nReserved Airline Ticket\n\n"

class Hotel(Reservation):
    def __init__(self,passenger_id,passenger_fname,passenger_lname,hotel_room_selection,
             hotel_check_in_date,hotel_check_out_date):
        Reservation.__init__(self,passenger_id,passenger_fname,passenger_lname)
        self.hotel_room_selection = hotel_room_selection
        self.hotel_check_in_date = hotel_check_in_date
        self.hotel_check_out_date = hotel_check_out_date

    def CheckAvailability(self):
        if (self.hotel_room.get(self.hotel_room_selection) != 0):
            self.hotel_room[self.hotel_room_selection] -= 1
            self.passenger_record['p_wallet'] += self.hotel_price[self.hotel_room_selection]
            print "\n\nReserved Hotel Room\n\n"

A1 = Airline("1","Arun","Raman","Business Class","07-07-2014")
A1.CheckAvailability()
A1.currentStatus("Airline")
H1 = Hotel("1","Arun","Raman","Penthouse","07-07-2014","07-10-2014")
H1.CheckAvailability()
H1.currentStatus("Hotel")
\$\endgroup\$
6
\$\begingroup\$

One obvious issue is that all of the data for hotels and airlines is stored in the base Reservation class. You should move it to the relevant sub-classes, and I would store it as class attributes (shared by all instances) rather than instance attributes (unique to each instance), otherwise you won't be tracking the correct numbers of free rooms:

class Hotel(Reservation):

    HOTEL_ROOM = {'Penthouse': 10,
                  'King Deluxe Bedroom': 20,
                  'Queen Deluxe Bedroom': 20,
                  'King Standard Bedroom': 30,
                  'Queen Standard Bedroom': 50}

Also, as it stands, your code effectively makes the booking before it checks the availability. If you try to book something when it's already booked up, you should be raising an error. The customer is too closely tied to e.g. the Hotel - think about it in real terms, do you have the names of all of the customers when you build a new hotel?

A better option would be to create a new class structure:

  • Reservation
    • HotelReservation
    • AirlineReservation
  • Bookable
    • Hotel
    • Airline
  • Customer

All Bookables (which you could extend to e.g. CarHire in the future) would implement check_availability and make_reservation. To make it clear that the sub-classes should implement these, you can put a stub in the parent:

class Bookable(object):

    def check_availability(self, *details):
        raise NotImplementedError

    def make_reservation(self, *details):
        raise NotImplementedError

The sub-classes would then have information specific to that type (e.g. a Hotel would have rooms, an Airline seats, etc.) and their implementations of those methods would reflect that.

The Reservation would then connect the Customer to a Bookable (you might even find you don't need the sub-classes there - what's the difference between an airline reservation and a hotel reservation?) This would go both ways - a Hotel needs to know when to expect whom, and a Customer needs to know what they have booked.

Your code might now look like:

a1 = Airline("Qantas")
h1 = Hotel("Mayfair")
c1 = Customer("Arun", "Raman")

if a1.check_availability("Business Class", "07-07-2014"):
    r1 = a1.make_reservation(c1, "Business Class", "07-07-2014")

if h1.check_availability("Penthouse", "07-07-2014", "07-10-2014"):
    r2 = h1.make_reservation(c1, "Penthouse", "07-07-2014", "07-10-2014")

print(c1.bookings)

Looking at that, I'm thinking:

  1. Could we cut the repetition of booking details? Perhaps introduce a Booking class? (e.g. b1 = Booking(c1, details) then for h in hotels: if h.check_availability(b1): h.make_reservation(b1))
  2. Make the dates actual datetime objects, not strings.

But I will leave it there for now.

\$\endgroup\$
  • \$\begingroup\$ so the checkavailability and makeReservation showuld be part of the Booking class? if so how will the checkAvailability can see the information like Airline seats and Airline price, that are defined in the child class. Sorry if question is novice, coming from a C background, i can relate it to a function call !! Not able see in object point of view. I can see we are calling A1.checkAvailability(). So the object is for the airline class. but am not able to see how i would write this in Booking class !! \$\endgroup\$ – Arman May 6 '14 at 0:55
  • \$\begingroup\$ They should be implemented in the child classes of Booking; I have updated my answer to show what should be in Booking itself to reflect that. \$\endgroup\$ – jonrsharpe May 6 '14 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.