Search code examples
pythonpandasassign

Distribute a number of items in bins to a different number of orders


I am new to Python programming and I have a small problem that I am trying to solve. I'm trying to distribute some items in several bins to a set of orders.

import pandas as pd

a={'Bin 1': 12,
   'Bin 2': 1}

b={'Order 1': 5,
   'Order 2': 8}

bins = pd.DataFrame(a.items(), columns=['Bin', 'Items'])
orders =pd.DataFrame(b.items(), columns=['Order', 'Items'])

The distribution should occur as illustrated here: image

I want to generate a new dataset or list of instructions that describes what elements from which bin have been assigned to which order:

  1. From Bin 1, 5 element(s) have been assigned to Order 1. Bin 1 has 7 Items left. #if order is full, move to the next order
  2. From Bin 1, 7 element(s) have been assigned to Order 2. Bin 1 has 0 Items left. #move to next bin
  3. From Bin 2, 1 element(s) have been assigned to Order 2. Bin 2 has 0 Items left.

Practically I would like to end up with a dataframe like this: result

It's not a problem if there are items left after filling the last order or if the last order(s) are not fully fulfilled. What is important is that the list of instructions should work for any n number of bins or orders.

Thanks in advance for any suggestions or ideas on how to tackle this problem.


Solution

  • Here's a solution:

    bins={'Bin 1': 12,
       'Bin 2': 1}
    
    orders={'Order 1': 5,
       'Order 2': 8}
    
    while len(orders) and len(bins): 
        order_name = list(orders.keys())[0]
        bin_name = list(bins.keys())[0]
        m = min(bins[bin_name], orders[order_name])
        print(order_name, bin_name, m)
        bins[bin_name] -= m
        orders[order_name] -= m
        if orders[order_name] == 0: 
            del orders[order_name]
        if bins[bin_name] == 0:
            del bins[bin_name]
    

    The output for this case is:

    Order 1 Bin 1 5
    Order 2 Bin 1 7
    Order 2 Bin 2 1