Airline/Hotel reservation system in Python 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")
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:


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))
Make the dates actual datetime objects, not strings.


But I will leave it there for now.