"""print(event) calls event.__str__() """ from __future__ import annotations import datetime import random from entities import Order from food_delivery_system import FoodDeliverySystem class Event: timestamp: datetime.datetime def __init__(self, timestamp: datetime.datetime) -> None: self.timestamp = timestamp def handle_event(self, system: FoodDeliverySystem) -> list[Event]: # None (before) raise NotImplementedError class NewOrderEvent(Event): _order: Order def __init__(self, order: Order) -> None: self._order = order Event.__init__(self, order.start_time) # This initializes self.timestamp # This works, but is not the best practice # self.timestamp = order.start_time def handle_event(self, system: FoodDeliverySystem) -> list[Event]: success = system.place_order(self._order) if success: completion_time = self.timestamp + datetime.timedelta(minutes=10) return [CompleteOrderEvent(completion_time, self._order)] else: self._order.start_time = self.timestamp + datetime.timedelta(minutes=5) # Try again after 5m return [NewOrderEvent(self._order)] class CompleteOrderEvent(Event): _order: Order def __init__(self, timestamp: datetime.datetime, order: Order) -> None: Event.__init__(self, timestamp) self._order = order def handle_event(self, system: FoodDeliverySystem) -> list[Event]: system.complete_order(self._order, self.timestamp) return [] class GenerateOrdersEvent(Event): """ Private Instance Attributes: - _duration: the number of hours to generate orders for Private Representation Invariants: - self._duration > 0 """ _duration: int def __init__(self, timestamp: datetime.datetime, duration: int) -> None: """ Preconditions: - duration > 0 """ Event.__init__(self, timestamp) self._duration = duration def handle_event(self, system: FoodDeliverySystem) -> list[Event]: customers = system.get_customers() vendors = system.get_vendors() events = [] current_time = self.timestamp end_time = self.timestamp + datetime.timedelta(hours=self._duration) while current_time < end_time: customer = random.choice(customers) vendor = random.choice(vendors) food_items = {} new_order = Order(customer=customer, vendor=vendor, food_items=food_items, start_time=current_time) new_order_event = NewOrderEvent(new_order) events.append(new_order_event) current_time = current_time + datetime.timedelta(minutes=random.randint(1, 60)) return events