class Item:
"""One piece of rental equipment."""
def __init__(self, item_id, kind, size, daily_cents):
self.item_id = item_id
self.kind = kind
self.size = size
self.daily_cents = daily_cents
self.available = True
class Customer:
"""A person who rents equipment."""
def __init__(self, name):
self.name = name
self.rentals = []
def total_owed(self):
"""Return the total cost of this customer's rentals, in cents."""
total = 0
for rental in self.rentals:
total += rental.cost()
return total
class Rental:
"""One item rented by one customer for a number of days."""
def __init__(self, item, customer, days):
self.item = item
self.customer = customer
self.days = days
def cost(self):
"""Return the cost in cents."""
return self.item.daily_cents * self.days
class Shop:
"""The rental shop: owns the inventory and records every rental."""
def __init__(self):
self._items = {} # item_id -> Item
self._rentals = []
def add_item(self, item):
self._items[item.item_id] = item
def available(self, kind):
"""Return the IDs of available items of one kind."""
ids = []
for item in self._items.values():
if item.kind == kind and item.available:
ids.append(item.item_id)
return ids
def rent(self, item_id, customer, days):
"""Rent an item to a customer; return the new Rental."""
item = self._items[item_id]
if not item.available:
raise ValueError(f"{item_id} is already rented")
item.available = False
rental = Rental(item, customer, days)
customer.rentals.append(rental)
self._rentals.append(rental)
return rental
shop = Shop()
shop.add_item(Item("S1", "skis", 160, 3500))
shop.add_item(Item("S2", "skis", 170, 3500))
shop.add_item(Item("H1", "helmet", "M", 800))
maya = Customer("Maya")
shop.rent("S1", maya, 3)
shop.rent("H1", maya, 3)
print(shop.available("skis"))
print(f"{maya.name} owes ${maya.total_owed() / 100:.2f}")
try:
shop.rent("S1", Customer("Leo"), 1)
except ValueError as err:
print("Sorry:", err)
rental.py: four classes that follow the UML diagram. In a real project each class could go in its own module.