Outlines a quick help guide for developing a basic hotel room booking system in Python, with a focus on incorporating a specific room amenity a hot tub. The tutorial leverages Python’s object oriented programming (OOP) capabilities to define Room objects with attributes like type, price, and available amenities (e.g., has_hot_tub).
- Data Structure: Using a dictionary or list to store and manage room inventory and booking status.
- Key Functions: Implementing functions to list available rooms, check amenities, handle customer details, and calculate total stay costs.
- Feature Integration: Demonstrates how to add a boolean or string attribute (
hot_tub) to room objects and create logic for filtering rooms based on this specific feature for a tailored guest experience.
What is “hotel with hot tub in room”
Choosing what you want to simulate:
Let’s define what we mean by “hotel with hot tub in room”. In our simulation:
- The hotel has multiple rooms. Some rooms are standard; some are “hot tub rooms”.
- A “hot tub room” means the room has an in-room hot tub facility (so possibly higher price, maybe maintenance flag).
- Customers can book a room for a number of nights.
- The system should check availability (i.e., that the room is free for those nights).
- The system should optionally add extra features for the hot tub room (e.g., extra nightly charge, or extra cleaning fee).
- The system should allow checkout, compute total charge, maybe mark the room as needing maintenance for the hot tub.
Deciding a simple architecture:
To keep it understandable (easy English, human tone) I’ll go with a small object-oriented design:
- A
Roombase class. - A
HotTubRoomsubclass that extendsRoomand adds hot tub specific attributes. - A
Bookingclass to represent a booking (room, customer name, start date, nights, total price). - A
Hotelclass to hold list of rooms, manage bookings, etc.
The competitor guides mostly used flat functions with dictionaries and JSON; this will make our code cleaner and more extendable. And we’ll show how to add the hot tub feature.
Setting Up Classes
Defining the Room class:
class Room:
def __init__(self, room_number, nightly_rate):
self.room_number = room_number
self.nightly_rate = nightly_rate
self.is_booked = False
self.current_booking = None
def book(self, booking):
if self.is_booked:
raise Exception(f"Room {self.room_number} is already booked.")
self.is_booked = True
self.current_booking = booking
def checkout(self):
self.is_booked = False
self.current_booking = None
Here we have a basic room: number, nightly rate, booked status, current booking. Very simple.
Defining the HotTubRoom subclass:
class HotTubRoom(Room):
def __init__(self, room_number, nightly_rate, hot_tub_fee):
super().__init__(room_number, nightly_rate)
self.hot_tub_fee = hot_tub_fee
self.hot_tub_needs_maintenance = False
def book(self, booking):
if self.hot_tub_needs_maintenance:
raise Exception(f"Hot tub in room {self.room_number} is under maintenance.")
super().book(booking)
def checkout(self):
# After checkout we might flag maintenance
self.hot_tub_needs_maintenance = True
super().checkout()
def calculate_rate(self, nights):
return self.nightly_rate * nights + self.hot_tub_fee * nights
Notice that the hot tub room adds: a hot tub fee, a maintenance flag, custom calculate_rate. This is new compared to competitor guides.
Defining the Booking class:
class Booking:
def __init__(self, customer_name, room, start_date, nights):
self.customer_name = customer_name
self.room = room
self.start_date = start_date # e.g., a datetime.date
self.nights = nights
self.total_price = self.room.nightly_rate * nights
if isinstance(self.room, HotTubRoom):
self.total_price = self.room.calculate_rate(nights)
We compute the total price differently if it’s a hot tub room.
Defining the Hotel class:
class Hotel:
def __init__(self, name):
self.name = name
self.rooms = []
self.bookings = []
def add_room(self, room):
self.rooms.append(room)
def find_available_room(self, nights, want_hot_tub=False):
for room in self.rooms:
if not room.is_booked:
if want_hot_tub and isinstance(room, HotTubRoom):
return room
if not want_hot_tub and not isinstance(room, HotTubRoom):
return room
return None
def make_booking(self, customer_name, nights, want_hot_tub=False):
room = self.find_available_room(nights, want_hot_tub)
if room is None:
raise Exception("No available room meets your request.")
booking = Booking(customer_name, room, date.today(), nights)
room.book(booking)
self.bookings.append(booking)
print(f"Booked room {room.room_number} for {customer_name}. Total price: {booking.total_price}")
return booking
def checkout(self, booking):
booking.room.checkout()
print(f"{booking.customer_name} checked out from room {booking.room.room_number}.")
This gives us a complete mini-system: we can add rooms (standard or hot tub), make bookings, checkout, etc.
Using the System and Adding Features
Example usage:
from datetime import date
hotel = Hotel("Seaside Resort")
# add rooms
hotel.add_room(Room(101, 100))
hotel.add_room(Room(102, 110))
hotel.add_room(HotTubRoom(201, 150, hot_tub_fee=30))
hotel.add_room(HotTubRoom(202, 160, hot_tub_fee=35))
# booking a regular room
b1 = hotel.make_booking("Alice", nights=2, want_hot_tub=False)
# booking a hot tub room
b2 = hotel.make_booking("Bob", nights=3, want_hot_tub=True)
# checkout
hotel.checkout(b1)
hotel.checkout(b2)
You’ll see Alice pays 2 nights * 100 = 200, Bob pays 3 nights * (150 + 30) = 540.
New feature: Mark the hot tub room ready after maintenance
A new bit of logic not found in many beginner tutorials: after checkout, you might want to reset the hot tub maintenance flag only after a cleaning cycle. For example:
def clean_hot_tub_room(hot_tub_room):
if hot_tub_room.hot_tub_needs_maintenance:
print(f"Cleaning hot tub in room {hot_tub_room.room_number}")
hot_tub_room.hot_tub_needs_maintenance = False
else:
print("No maintenance needed.")
This extra step ensures a hot tub room isn’t instantly re-bookable until cleaned adds realism.
Handling Availability Over Dates and Nights
One of the weak spots of many guides is date span checking. They just mark rooms as free/free without considering overlapping bookings. Let’s fix that.
Improved Room Class to Handle Bookings List:
Instead of just is_booked, we track booked periods.
class Room:
def __init__(self, room_number, nightly_rate):
self.room_number = room_number
self.nightly_rate = nightly_rate
self.booked_periods = [] # list of tuples: (start_date, end_date)
def is_available(self, start_date, nights):
end_date = start_date + timedelta(days=nights)
for (s, e) in self.booked_periods:
# if periods overlap:
if s < end_date and start_date < e:
return False
return True
def book_period(self, booking):
end_date = booking.start_date + timedelta(days=booking.nights)
self.booked_periods.append((booking.start_date, end_date))
Then in Hotel:
def find_available_room(self, start_date, nights, want_hot_tub=False):
for room in self.rooms:
if want_hot_tub and isinstance(room, HotTubRoom) and room.is_available(start_date, nights):
return room
if not want_hot_tub and not isinstance(room, HotTubRoom) and room.is_available(start_date, nights):
return room
return None
And our make_booking method updates accordingly.
Why this is better
Most competitor guides don’t handle date overlaps—for example, if someone books room 101 for nights 3–5, you need to block nights 3–4 and not let someone else book them. The above logic handles that.
Extra Services and Pricing Beyond Hot Tub
To push beyond what typical guides offer, let’s add more new features:
Optional mini-bar service
We can allow rooms to have optional add-ons. For example:
class Service:
def __init__(self, name, fee):
self.name = name
self.fee = fee
class Booking:
def __init__(self, customer_name, room, start_date, nights, services=None):
if services is None:
services = []
self.customer_name = customer_name
self.room = room
self.start_date = start_date
self.nights = nights
self.services = services
self.total_price = self.compute_price()
def compute_price(self):
base = self.room.nightly_rate * self.nights
if isinstance(self.room, HotTubRoom):
base += self.room.hot_tub_fee * self.nights
svc_fee = sum(s.fee for s in self.services)
return base + svc_fee
Now you can pass services like Service("Mini-bar", 20) or Service("Room Service Breakfast", 30).
Discount logic
Maybe if someone books a hot tub room for more than 5 nights, you give a discount:
if isinstance(self.room, HotTubRoom) and self.nights >= 5:
self.total_price *= 0.9 # 10% discount
This is new compared to many guides.
Waiting list / upgrade logic
If someone requests a hot tub room but none are available, maybe you can put them on a waiting list or offer a standard room with upgrade possibility. This is more advanced and not typically covered in simple tutorials.
User Interface: Simple Console Loop
To make this usable, you might buil a loop like:
while True:
print("1. Book room")
print("2. Checkout booking")
print("3. Clean hot tub room")
print("4. Exit")
choice = input("Choose an option: ")
if choice == '1':
name = input("Customer name: ")
nights = int(input("Nights: "))
want_hot = input("Want hot tub room? (y/n): ") == 'y'
try:
booking = hotel.make_booking(name, nights, want_hot)
except Exception as e:
print("Error:", e)
elif choice == '2':
name = input("Customer name for checkout: ")
# find booking by name
bk = next((b for b in hotel.bookings if b.customer_name == name), None)
if bk:
hotel.checkout(bk)
else:
print("Booking not found.")
elif choice == '3':
room_no = int(input("Room number to clean hot tub: "))
room = next((r for r in hotel.rooms if r.room_number == room_no and isinstance(r, HotTubRoom)), None)
if room:
clean_hot_tub_room(room)
else:
print("No hot tub room found with that number.")
elif choice == '4':
print("Goodbye!")
break
else:
print("Invalid choice.")
Conclusion
If you’ve followed along, you now know how to create a hotel with hot tub in room in Python you’ve seen code to build room classes, hot tub room subclass, booking logic, availability by dates, extra services, maintenance flags, interactive console loop. You’ve also seen how this post gives you more depth than many simpler tutorials out there.

