Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Order system."""
- from typing import List, Dict
- class OrderItem:
- """Order Item requested by a customer."""
- def __init__(self, customer: str, name: str, quantity: int, one_item_volume: int):
- """
- Constructor that creates an order item.
- :param customer: requester name.
- :param name: the name of the item.
- :param quantity: quantity that shows how many such items customer needs.
- :param one_item_volume: the volume of one item.
- """
- self.customer = customer
- self.name = name
- self.quantity = quantity
- self.one_item_volume = one_item_volume
- @property
- def total_volume(self) -> int:
- """
- Calculate and return total volume of the current order item.
- :return: Total volume (cm^3), int.
- """
- return self.quantity * self.one_item_volume
- class Order:
- """Combination of order items of one customer."""
- def __init__(self, order_items: List[OrderItem]):
- """
- Constructor that creates an order.
- :param order_items: list of order items.
- """
- self.order_items = order_items
- self.destination = None
- # total_quantity - kõigi tellimuse ridade summaarne kogus
- @property
- def total_quantity(self) -> int:
- """
- Calculate and return the sum of quantities of all items in the order.
- :return: Total quantity as int.
- """
- total = 0
- for item in self.order_items:
- total += item.quantity
- return total
- @property
- def total_volume(self) -> int:
- """
- Calculate and return the total volume of all items in the order.
- :return: Total volume (cm^3) as int.
- """
- calculate = 0
- for x in self.order_items:
- calculate += x.total_volume
- return calculate
- class Container:
- """Container to transport orders."""
- def __init__(self, volume: int, orders: List[Order] = None):
- """Constructor that makes a container."""
- self.volume = volume # maht
- self.orders = orders # tellimused
- self.orders = orders if orders else []
- @property
- def volume_left(self):
- """Calculate how much space is unused.
- Order1 60 m3
- Order2 40 m3
- Order3 20 m3
- siis: volume - (60 + 40 + 20)
- orders on list orderitest
- """
- new = 0
- for i in self.orders:
- new += i.total_volume
- return self.volume - new
- class OrderAggregator:
- """Algorithm of aggregating orders."""
- def __init__(self):
- """Initialize order aggregator."""
- self.order_items: List[OrderItem] = []
- def add_item(self, item: OrderItem):
- """
- Add order item to the aggregator.
- :param item: Item to add.
- :return: None
- """
- self.order_items.append(item)
- def aggregate_order(self, customer: str, max_items_quantity: int, max_volume: int):
- """
- Create an order for customer which contains order lines added by add_item method.
- Iterate over added orders items and add them to order if they are for given customer
- and can fit to the order.
- :param customer: Customer's name to create an order for.
- :param max_items_quantity: Maximum amount on items in order.
- :param max_volume: Maximum volume of order. All items volumes must not exceed this value.
- :return: Order.
- """
- sum_of_q = 0
- sum_of_v = 0
- new_items = []
- items: List[OrderItem] = []
- # items_for_the_customer = filter(lambda item: item.customer == customer, self.order_items) # kui on tõene lisab sisse
- for order_item in self.order_items:
- delete = False
- if order_item.customer == customer:
- sum_of_q += order_item.quantity
- sum_of_v += order_item.total_volume
- if sum_of_q <= max_items_quantity and sum_of_v <= max_volume:
- items.append(order_item)
- delete = True
- else:
- sum_of_q -= order_item.quantity
- sum_of_v -= order_item.total_volume
- if not delete:
- new_items.append(order_item)
- self.order_items = new_items
- return Order(items)
- class ContainerAggregator:
- """Algorithm to prepare containers."""
- def __init__(self, container_volume: int):
- """
- Initialize Container Aggregator.
- :param container_volume: Volume of each container created by this aggregator.
- """
- self.container_volume = container_volume
- self.not_used_orders = []
- def prepare_containers(self, orders: tuple) -> dict:
- """
- Create containers and put orders to them.
- If order cannot be put to a container, it is added to self.not_used_orders list.
- :param orders: tuple of orders.
- :return: dict where keys are destinations and values are containers to that destination with orders.
- """
- all_conteiners: Dict[str, List[Container]] = {}
- print(orders)
- for i in orders: # i on tellimus
- in_box = False
- if i.total_volume <= self.container_volume: # konteinerisse mahub
- if not all_conteiners.get(i.destination, None): # kui destination on tühi tuleb luua uus list
- all_conteiners[i.destination] = [Container(self.container_volume, [i])]
- else: # kui destination on dictis juba olemas
- # loobin läbi kõik konteinerid
- for conteiner in all_conteiners[i.destination]:
- if conteiner.volume_left >= i.total_volume and in_box is False: # kui mahub tuleb lisada liste
- in_box = True
- conteiner.orders.append(i)
- if not in_box:
- all_conteiners[i.destination].append(Container(self.container_volume, [i]))
- else:
- self.not_used_orders.append(i)
- return all_conteiners
- if __name__ == '__main__':
- print("Order items")
- order_item1 = OrderItem("Apple", "iPhone 11", 100, 10)
- order_item2 = OrderItem("Samsung", "Samsung Galaxy Note 10", 80, 10)
- order_item3 = OrderItem("Mööbel 24", "Laud", 300, 200)
- order_item4 = OrderItem("Apple", "iPhone 11 Pro", 200, 10)
- order_item5 = OrderItem("Mööbel 24", "Diivan", 20, 200)
- order_item6 = OrderItem("Mööbel 24", "Midagi väga suurt", 20, 100)
- print(order_item3.total_volume) # 60000
- print("Order Aggregator")
- oa = OrderAggregator()
- oa.add_item(order_item1)
- oa.add_item(order_item2)
- oa.add_item(order_item3)
- oa.add_item(order_item4)
- oa.add_item(order_item5)
- oa.add_item(order_item6)
- print(f'Added {len(oa.order_items)}(6 is correct) order items')
- order1 = oa.aggregate_order("Apple", 350, 3000)
- order1.destination = "Tallinn"
- print(f'order1 has {len(order1.order_items)}(2 is correct) order items')
- order2 = oa.aggregate_order("Mööbel 24", 325, 64100)
- order2.destination = "Tallinn"
- print(f'order2 has {len(order2.order_items)}(2 is correct) order items')
- print(f'after orders creation, aggregator has only {len(oa.order_items)}(2 is correct) order items left.')
- print("Container Aggregator")
- ca = ContainerAggregator(70000)
- too_big_order = Order([OrderItem("Apple", "Apple Car", 10000, 300)])
- too_big_order.destination = "Somewhere"
- containers = ca.prepare_containers((order1, order2, too_big_order))
- print(f'prepare_containers produced containers to {len(containers)}(1 is correct) different destination(s)')
- try:
- containers_to_tallinn = containers['Tallinn']
- print(f'volume of the container to tallinn is {containers_to_tallinn[0].volume}(70000 is correct) cm^3')
- print(f'container to tallinn has {len(containers_to_tallinn[0].orders)}(2 is correct) orders')
- except KeyError:
- print('Container to Tallinn not found!')
- print(f'{len(ca.not_used_orders)}(1 is correct) cannot be added to containers')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement