コード例 #1
0
 def testInitMissing(self):
     # confirm argument testing
     try:
         t = 'rack_no'
         _ = Bin(side='a', bin_no=1, item=1, count=10)
         raise ValueError('missing {} SBE exception'.format(t))
     except ValueError:
         print(t)
         sys.exit(-1)
     except Exception:
         pass
     try:
         t = 'bin_no'
         _ = Bin(rack_no=1, side='a', item=1, count=10)
         raise ValueError('missing {} SBE exception'.format(t))
     except ValueError:
         print(t)
         sys.exit(-1)
     except Exception:
         pass
     try:
         t = 'side'
         _ = Bin(rack_no=1, bin_no=1, item=1, count=10)
         raise ValueError('missing {} SBE exception'.format(t))
     except ValueError:
         print(t)
         sys.exit(-1)
     except Exception:
         pass
コード例 #2
0
 def testBinLocation(self):
     bl1 = Bin.Bin_Location(1, 'a', 1)
     bl2 = Bin.Bin_Location(1, 'a', 1)
     self.assertEqual(bl1, bl2, '{} SBE equal {}'.format(bl1, bl2))
     bl2 = Bin.Bin_Location(1, 'a', 2)
     self.assertNotEqual(bl1, bl2, '{} SBE not equal {}'.format(bl1, bl2))
     self.assertLess(bl1, bl2, '{} SBE LT {}'.format(bl1, bl2))
コード例 #3
0
    def update_bin(cls, location, item_no, qty):
        '''
        add or subtract qty in bin at location
        if item being updated != item in bin at location, bin.__item, bin.__count = item_no, qty
        
        Assumption:
            if called to update bin with new item, then all inbins with old item will be replaced everywhere. 
                Use Bin.__stock_bin to update individual bins but be sure to only update bin instances that live in Inventory
'''
        assert isinstance(
            location, Bin.Bin_Location
        ), 'location SBE instance of Bin.Bin_Location, is {}'.format(
            location.__class__)
        assert isinstance(qty, int), 'qty mst be int'
        assert isinstance(item_no,
                          int) and item_no > 0, 'item_no must be int > 0'

        b = Bin.get_bin_by_location(location)
        if b is None:
            b = Bin(rack_no=location.rack,
                    side=location.side,
                    bin_no=location.bin_no)
        if b.item != item_no:
            try:
                cls.__stock[item_no].discard(location)
            except:
                pass
        b.stock_bin(item_no, qty)
        cls.__stock[item_no].add(b.location)
        pass
コード例 #4
0
    def loc_to_loc_distance(self, from_loc, to_loc):
        '''Manhattan distance, not Euclidian
		call with two Bin class instances
'''
        assert isinstance(from_loc, Bin.Bin_Location) and isinstance(to_loc, Bin.Bin_Location),\
          'both arguments must be instance of Bin class'
        from_bin = Bin.get_bin_by_location(from_loc)
        to_bin = Bin.get_bin_by_location(to_loc)
        return bin_to_bin_distance(*sorted((from_bin, to_bin)))
コード例 #5
0
    def testGetBinByLocation(self):
        # confirm initialization of attributes
        b = Bin(rack_no=1, side='b', bin_no=5, item=2, count=10)
        location = b.location
        b = Bin.get_bin_by_location(location)
        self.assertEqual( (1, 'b', 5), (location.rack, location.side, location.bin_no),\
            'bin rack_no, side, bin_no SBE (1, "b", 5), is {}'\
            .format((location.rack, location.side, location.bin_no)))
        self.assertEqual((6, 2), (b.lat, b.long), \
            'bin lat/long SBE {}, is{}'.format((2, 0), (b.lat, b.long)))

        b = Bin(rack_no=1, side='a', bin_no=1, item=1, count=10)
        location = b.location
        b = Bin.get_bin_by_location(location)
        self.assertEqual((1, 'a', 1), (location.rack, location.side, location.bin_no),\
            'bin rack_no, side, bin_no SBE (1, "a", a), is {}'\
            .format((location.rack, location.side, location.bin_no)))
        self.assertEqual((2, 1), (b.lat, b.long), \
            'bin lat/long SBE {}, is{}'.format((2, 0), (b.lat, b.long)))

        b = Bin.get_bin_by_location(location)
        b.stock_bin(
            item_no=2,
            item_count=30)  # removes prior item (1) replacing with item 2
        self.assertEqual((2, 1, 1, 'a', 30), (b.item,
                                  b.bin_no, b.rack_no, b.bin_side,
                                  b.count),\
            'item and count SBE (1, 30), is {}'.format((b.item, b.count)))
コード例 #6
0
 def testAddItem(self):
     b = Bin(rack_no=1, side='b', bin_no=2)
     itm_no = 3
     qty = 30
     i = Inventory()
     i.clear()
     i.update_bin(location=b.location, item_no=itm_no, qty=qty)
     self.assertEqual(i.get_stock_qty(location=b.location), (itm_no, qty), \
             "item {} at {} SBE qty {}, is {}".format(itm_no, qty, b.location,
                                                      i.get_stock_qty(location=b.location)))
     b = Bin.get_bin_by_location(b.location)
     self.assertEqual(b.item, itm_no, \
                         'location ({} item/qty SBE {}, is {}'.format(b.location, (itm_no, qty),
                                                                      (b.item, b.count)))
コード例 #7
0
 def testClear(self):
     b = Bin(rack_no=1, side='a', bin_no=1)
     b.__count = 0
     i = Inventory()
     i.clear()
     Inventory.update_bin(location=b.location, item_no=1, qty=10)
     self.assertEqual(
         len(i.stock), 1,
         'SBE only 1 item in inventory stock, is {}'.format(len(i.stock)))
     i.clear()
     self.assertEqual(
         len(i.stock), 0,
         'SBE no1 items in inventory stock after clear, is {}'.format(
             len(i.stock)))
コード例 #8
0
 def testInit(self):
     b = Bin(rack_no=1, side='b', bin_no=3)
     self.assertEqual(b.rack_no, 1,
                      'rack_no SBE 1, is {}'.format(b.rack_no))
     self.assertEqual(b.bin_no, 3, 'bin_no SBE 3, is {}'.format(b.bin_no))
     self.assertEqual(b.bin_side, 'b',
                      'bin_no SBE "b", is {}'.format(b.bin_side))
     self.assertEqual(
         b.location, Bin.Bin_Location(1, 'b', 3),
         'bin_no SBE {}, is {}'.format(Bin.Bin_Location(1, 'b', 3),
                                       b.location))
     self.assertEqual(b.lat, 4, 'bin_no SBE 4, is {}'.format(b.lat))
     self.assertEqual(b.long, 2, 'bin_no SBE 2, is {}'.format(b.long))
     self.assertIsNone(b.item, 'item SBE None, is {}'.format(b.item))
     self.assertEqual(b.count, 0, 'bin_no SBE 0, is {}'.format(b.count))
コード例 #9
0
    def __init__(self, racks=None, bins=None):

        if type(self).__instance is None:
            # Initialization
            assert isinstance(racks, int) and racks > 0, \
                'number of racks must be int > 0'
            assert isinstance(bins, int) and bins > 0, \
                'number of bins must be int > 0'

            type(self).__instance = self

            dock_rack = round((racks / 2) + .1)  # friggin "Banker's rounding!
            self.__dock = Bin(rack_no=dock_rack, side='a', bin_no=0)
            self.__dock.nearest_cap = self.__dock
            self.__dock.nearest_cap_distance = 0
            self.__racks_bins = (racks, bins)
            self.__racks = [
                Rack(rack_no=x, bin_count=bins)
                for x in range(1, racks + 1, 1)
            ]
            self.__bins = [
                list(r.bins_a.values()) + list(r.bins_b.values())
                for r in self.__racks
            ][0]
        else:
            self.__dict__ = Warehouse.__instance.__dict__
コード例 #10
0
 def nearest_cap(self, b):
     (dist_bottom, dist_top) = (b.bin_no, self.bin_count - b.bin_no + 1)
     if dist_bottom > dist_top:
         bin_no = self.bin_count + 1
     else:
         bin_no = 0
     return Bin(rack_no=self.rack_no, side=b.bin_side, bin_no=bin_no)
コード例 #11
0
    def __init__(self, wh, order):
        '''
		Constructor
		'''
        assert isinstance(order, Order), 'order must be instance of Order'
        self.__order = order
        self.__order_lines = order.lines

        self.warehouse = wh  # pick up singleton

        self.__pick_bins = set()
        self.__pick_items = set()
        for line in self.order_lines:
            item_locations = self.warehouse.stock[line.item_no]
            if len(item_locations) == 0:
                # silently ignore items not in inventory
                # but monkey-patch note that item not in inventory
                line.status = 'not in inventory'
            else:
                self.__pick_items.add(line.item_no)
                for item_location in item_locations:
                    self.__pick_bins.add(
                        Bin.get_bin_by_location(item_location))

        self.__route = OrderedDict()
        self.__route_distance = 0

        self.__calc_route()
コード例 #12
0
 def testUpdateStock(self):
     r_no = 3
     i_no = 3
     location = Bin.Bin_Location(rack_no=r_no, side='a', bin_no=1)
     i = Inventory()
     i.clear()
     i.update_bin(item_no=i_no, location=location, qty=10)
     self.assertEqual(Inventory.__repr__(Inventory()), str(Inventory()),
                      '__repr__ != __string__')
     self.assertEqual(len(i.stock), 1, 'inventory SBE empty, found {} items'\
                                         .format(len(i.stock)))
コード例 #13
0
 def __repr__(self):
     if len(self.stock.values()) > 0:
         qty = sum([
             sum(
                 Bin.get_bin_by_location(loc).count
                 for loc in Inventory.__stock[itm])
             for itm in Inventory.__stock.keys()
         ])
     else:
         qty = 0
     return 'Inventory: {:,d} items, {:,d} total quantity'\
             .format(len(self.stock), qty)
コード例 #14
0
    def get_stock_qty(cls, item_no=None, location=None):
        '''
        First, if location is not None return bin.count @ location, otherwise check item_no is not None
        If item_no is not None, return quantity of item_no at all location.
        If both item_no and location are None or both are Not None, error
'''
        assert item_no is not None or location is not None, 'either item_no or location are not None'
        assert item_no is None or location is None, \
            'either item_no or location are not None, NOT both'
        if location is not None:
            b = Bin.get_bin_by_location(location)
            return (
                b.item, b.count
            )  # it is caller's responsibility to check b.item == item_no

        elif item_no is None or item_no not in cls.__stock:  # item_no is not None by assertion above
            return (item_no, 0)
        else:
            return (item_no,
                    sum([
                        Bin.get_bin_by_location(loc).count
                        for loc in cls.__stock[item_no]
                    ]))
コード例 #15
0
 def testDropBin(self):
     # del Bin.__bin_locations[location]
     Bin.clear()
     self.assertEqual(
         len(Bin.bin_locations), 0,
         'clear method should reset class list of prior Bin instances')
     bl1 = Bin(rack_no=1, side='a', bin_no=1)
     bl2 = Bin(rack_no=1, side='a', bin_no=2)
     self.assertEqual(len(Bin.bin_locations), 2,
                      'class list of Bin instances SBE len 2, is {}'\
                      .format(len(Bin.bin_locations)))
     Bin.drop_bin(bl1.location)
     self.assertEqual(len(Bin.bin_locations), 1,
                      'class list of Bin instances SBE len 1 after drop_bin, is {}'\
                      .format(len(Bin.bin_locations)))
     self.assertEqual(bl2, Bin.get_bin_by_location(bl2.location),
                      'bin at {} should still be in bin instance list after drop'\
                      .format(bl2.location))
コード例 #16
0
    def testBinsDistance(self):
        # print('testBinsDistance')
        b1 = Bin(rack_no=1, side='b', bin_no=1)
        b2 = Bin(rack_no=1, side='a', bin_no=5)
        pr = PickRoute(Test.wh, self.o)
        d = pr.bin_to_bin_distance(b1, b2)
        print('from {} to {} dist: {}'.format(b1.location, b2.location, d))
        #expected = 16
        #self.assertEqual(d, expected, '{} to {} SBE [], is {}'\
        #                    .format(b1.location, b2.location, expected, d))

        
        b1 = Bin(rack_no=1, side='b', bin_no=1)
        b2 = Bin(rack_no=2, side='a', bin_no=1)
        pr = PickRoute(Test.wh, self.o)
        d = pr.bin_to_bin_distance(b1, b2)
        print('from {} to {} dist: {}'.format(b1.location, b2.location, d))
        #expected = 16
        #self.assertEqual(d, expected, '{} to {} SBE [], is {}'\
        #                    .format(b1.location, b2.location, expected, d))

        
        b1 = Bin(rack_no=1, side='a', bin_no=4)
        b2 = Bin(rack_no=4, side='b', bin_no=5)
        pr = PickRoute(Test.wh, self.o)
        d = pr.bin_to_bin_distance(b1, b2)
        print('from {} to {} dist: {}'.format(b1.location, b2.location, d))
        #expected = 16
        #self.assertEqual(d, expected, '{} to {} SBE [], is {}'\
        #                    .format(b1.location, b2.location, expected, d))

        
        b1 = Bin(rack_no=3, side='a', bin_no=0)
        b2 = Bin(rack_no=4, side='b', bin_no=5)
        pr = PickRoute(Test.wh, self.o)
        d = pr.bin_to_bin_distance(b1, b2)
        print('from dock {} to {} dist: {}'.format(b1.location, b2.location, d))
コード例 #17
0
    def __init__(self, rack_no, bin_count):
        assert isinstance(rack_no, int) and rack_no > 0,\
         'rack_no must be int > 0'
        assert isinstance(bin_count, int) and bin_count > 0,\
         'bin_count must be int > 0'
        self.__rack_no = rack_no
        self.__bin_count = bin_count
        self.__top_cap_lat = bin_count + 2  # always with fixed # of bins
        self.__bottom_cap_lat = 1  # always
        self.__bins_a = dict()  # access via bin_no
        self.__bins_b = dict()  # access via bin_no

        for bin_no in range(1, bin_count + 1, 1):
            b = Bin(rack_no=self.rack_no, side='a', bin_no=bin_no)
            b.nearest_cap = self.nearest_cap(b)
            b.nearest_cap_distance = int(
                abs(b.lat_long - b.nearest_cap.lat_long).sum())
            self.__bins_a[bin_no] = b

            b = Bin(rack_no=self.rack_no, side='b', bin_no=bin_no)
            b.nearest_cap = self.nearest_cap(b)
            b.nearest_cap_distance = int(
                abs(b.lat_long - b.nearest_cap.lat_long).sum())
            self.__bins_b[bin_no] = b
コード例 #18
0
    def testUpdateStockSeparateSides(self):
        b = Bin(rack_no=1, side='a', bin_no=1)
        b.__count = 0
        i = Inventory()
        i.clear()
        Inventory.update_bin(location=b.location, item_no=1, qty=10)
        self.assertEqual(Inventory.__repr__(Inventory()), str(Inventory()),
                         '__repr__ != __string__')
        self.assertEqual(
            len(i.stock), 1,
            'inventory SBE empty, found {} items'.format(len(i.stock)))
        self.assertEqual(Bin.get_bin_by_location(b.location).count, 10, 'location ({} item SBE 10, is {}'\
                            .format(b.location, Bin.get_bin_by_location(b.location)))

        b = Bin(rack_no=1, side='b', bin_no=2)
        location = b.location
        i.update_bin(location=location, item_no=1, qty=20)
        (itm, q) = i.get_stock_qty(location=location)
        self.assertEqual(
            itm, 1, 'item at location {} SBE 1, is {}'.format(location, itm))
        self.assertEqual(
            q, 20, "item {} at {} SBE qty 20, is {}".format(1, location, q))
コード例 #19
0
    def testExceptions(self):
        b = Bin(rack_no=1, side='a', bin_no=1, item=1, count=10)

        try:
            b.rack_no = 2
            raise ValueError('trying to set rack_no should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.bin_no = 2
            raise ValueError('trying to set bin_no should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.bin_side = 'b'
            raise ValueError('trying to set bin_side should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.location = (1, 'a', 1)
            raise ValueError('trying to set location should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.lat = (1, 'a', 1)
            raise ValueError('trying to set lat should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.long = (1, 'a', 1)
            raise ValueError('trying to set long should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.item = (1, 'a', 1)
            raise ValueError('trying to set item should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass

        try:
            b.count = (1, 'a', 1)
            raise ValueError('trying to set count should raise exception')
        except ValueError as ve:
            print(ve)
            sys.exit(-1)
        except:
            pass
コード例 #20
0
 def get_location_bin(cls, location):
     assert isinstance(
         location, Bin.Bin_Location
     ), 'location must be an Bin.Bin_Location, is {}'.format(location)
     b = Bin.get_bin_by_location(location)
     return b