"""Lecture 29 (Food Delivery System) """ import datetime from typing import Optional from entities import Courier, Customer, Order, Vendor class FoodDeliverySystem: """A system that maintains all entities (vendors, customers, couriers, and orders). Representation Invariants: - all(vendor == self._vendors[vendor].name for vendor in self._vendors) - all(customer == self._customers[customer].name for customer in self._customers) - all(courier == self._couriers[courier].name for courier in self._couriers) """ # Private Instance Attributes: # - _vendors: a mapping from vendor name to Vendor object. # This represents all the vendors in the system. # - _customers: a mapping from customer name to Customer object. # This represents all the customers in the system. # - _couriers: a mapping from courier name to Courier object. # This represents all the couriers in the system. # - _orders: a list of all orders (both open and completed orders). _vendors: dict[str, Vendor] _customers: dict[str, Customer] _couriers: dict[str, Courier] _orders: list[Order] def __init__(self) -> None: self._vendors = {} self._customers = {} self._couriers = {} self._orders = [] def add_vendor(self, vendor: Vendor) -> bool: if vendor.name in self._vendors: # Vendor with the same name already exists return False else: # Vendor doesn't already exist self._vendors[vendor.name] = vendor return True def add_customer(self, customer: Customer) -> bool: if customer.name in self._customers: return False else: self._customers[customer.name] = customer return True def add_courier(self, courier: Courier) -> bool: if courier.name in self._couriers: return False else: self._couriers[courier.name] = courier return True def place_order(self, order: Order) -> bool: courier = self._assign_courier(order) if courier is None: return False else: self._orders.append(order) return True def _assign_courier(self, order: Order) -> Optional[Courier]: for name in self._couriers: courier = self._couriers[name] if courier.current_order is None: order.courier = courier courier.current_order = order return courier return None def complete_order(self, order: Order, timestamp: datetime.datetime) -> None: """ Preconditions: - order in self._orders - order.end_time is None - order.start_time < timestamp """ order.courier.current_order = None order.end_time = timestamp ########################################################################### # Additional methods used for events ########################################################################### def get_vendors(self) -> list[Vendor]: """Return a list of all vendors registered with this system.""" return list(self._vendors.values()) def get_customers(self) -> list[Customer]: """Return a list of all customers registered with this system.""" return list(self._customers.values()) ########################################################################### # Additional methods used for example runners ########################################################################### def get_customer(self, name: str) -> Customer: """Return the customer with the given name. Preconditions: - a customer with the given name exists """ return self._customers[name] def get_vendor(self, name: str) -> Vendor: """Return the food vendor with the given name. Preconditions: - a vendor with the given name exists """ return self._vendors[name] def get_courier(self, name: str) -> Courier: """Return the courier with the given name. Preconditions: - a courier with the given name exists """ return self._couriers[name] if __name__ == '__main__': import doctest doctest.testmod(verbose=True)