Skip to content

Commit

Permalink
Merge pull request #12 from wjones1/feature/lambda-key
Browse files Browse the repository at this point in the history
Add key argument to imitate built-in max(), min() API
  • Loading branch information
benmaier committed Jul 1, 2020
2 parents 6f02918 + 8da1dbc commit d1bfd45
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 20 deletions.
25 changes: 25 additions & 0 deletions binpacking/tests/constant_bin_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,28 @@ def test_only_zero_weights():
values = [0, 0, 0]
bins = to_constant_bin_number(values, 4)
assert bins == [[0, 0, 0], [], [], []]

def test_weight_pos():
values = [
[1, 'x'],
[2, 'y'],
[1, 'z'],
]
bins = to_constant_bin_number(values, 2, weight_pos=0)
for bin_ in bins:
for item in bin_:
assert isinstance(item[0], int)
assert isinstance(item[1], str)

def test_key_func():
values = [
{'x': 'a', 'y': 1},
{'x': 'b', 'y': 5},
{'x': 'b', 'y': 3},
]
bins = to_constant_bin_number(values, 2, key=lambda x: x['y'])

for bin_ in bins:
for item in bin_:
assert 'x' in item
assert 'y' in item
27 changes: 26 additions & 1 deletion binpacking/tests/constant_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,29 @@
def test_exact_fit():
values = [1, 2, 1]
bins = to_constant_volume(values, 2)
assert len(bins) == 2
assert len(bins) == 2

def test_weight_pos():
values = [
[1, 'x'],
[2, 'y'],
[1, 'z'],
]
bins = to_constant_volume(values, 2, weight_pos=0)
for bin_ in bins:
for item in bin_:
assert isinstance(item[0], int)
assert isinstance(item[1], str)

def test_key_func():
values = [
{'x': 'a', 'y': 1},
{'x': 'b', 'y': 5},
{'x': 'b', 'y': 3},
]
bins = to_constant_volume(values, 2, key=lambda x: x['y'])

for bin_ in bins:
for item in bin_:
assert 'x' in item
assert 'y' in item
25 changes: 15 additions & 10 deletions binpacking/to_constant_bin_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def csv_to_constant_bin_number(filepath,weight_column,N_bin,has_header=False,del
save_csvs(bins,filepath,header,delim=delim,quotechar=quotechar)


def to_constant_bin_number(d,N_bin,weight_pos=None,lower_bound=None,upper_bound=None):
def to_constant_bin_number(d,N_bin,weight_pos=None,key=None,lower_bound=None,upper_bound=None):
'''
Distributes a list of weights, a dictionary of weights or a list of tuples containing weights
to a fixed number of bins while trying to keep the weight distribution constant.
Expand All @@ -27,6 +27,7 @@ def to_constant_bin_number(d,N_bin,weight_pos=None,lower_bound=None,upper_bound=
optional:
~~~ weight_pos: int -- if d is a list of tuples, this integer number gives the position of the weight in a tuple
~~~ key: function -- if d is a list, this key functions grabs the weight for an item
~~~ lower_bound: weights under this bound are not considered
~~~ upper_bound: weights exceeding this bound are not considered
'''
Expand All @@ -44,17 +45,21 @@ def to_constant_bin_number(d,N_bin,weight_pos=None,lower_bound=None,upper_bound=
raise Exception("lower_bound is greater or equal to upper_bound")

isdict = isinstance(d,dict)
is_tuple_list = not isdict and hasattr(d[0],'__len__')

if is_tuple_list:
if isinstance(d, list) and hasattr(d[0], '__len__'):
if weight_pos is not None:

new_dict = { i: tup for i,tup in enumerate(d) }
d = { i: tup[weight_pos] for i,tup in enumerate(d) }
isdict = True
else:
raise Exception("no weight axis provided for tuple list")

key = lambda x: x[weight_pos]
if key is None:
raise ValueError("Must provide weight_pos or key for tuple list")

if isinstance(d, list) and key:
new_dict = {i: val for i, val in enumerate(d)}
print(new_dict)
d = {i: key(val) for i, val in enumerate(d)}
isdict = True
is_tuple_list = True
else:
is_tuple_list = False

if isdict:

Expand Down
24 changes: 15 additions & 9 deletions binpacking/to_constant_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def csv_to_constant_volume(filepath,weight_column,V_max,has_header=False,delim='
save_csvs(bins,filepath,header,delim=delim,quotechar=quotechar)


def to_constant_volume(d,V_max,weight_pos=None,lower_bound=None,upper_bound=None):
def to_constant_volume(d,V_max,weight_pos=None,key=None,lower_bound=None,upper_bound=None):
'''
Distributes a list of weights, a dictionary of weights or a list of tuples containing weights
to a minimal number of bins which have a fixed volume.
Expand All @@ -27,6 +27,7 @@ def to_constant_volume(d,V_max,weight_pos=None,lower_bound=None,upper_bound=None
optional:
~~~ weight_pos: int -- if d is a list of tuples, this integer number gives the position of the weight in a tuple
~~~ key: function -- if d is a list, this key functions grabs the weight for an item
~~~ lower_bound: weights under this bound are not considered
~~~ upper_bound: weights exceeding this bound are not considered
'''
Expand All @@ -44,16 +45,21 @@ def to_constant_volume(d,V_max,weight_pos=None,lower_bound=None,upper_bound=None
raise Exception("lower_bound is greater or equal to upper_bound")

isdict = isinstance(d,dict)
is_tuple_list = (not isdict) and (hasattr(d[0],'__len__'))

if is_tuple_list:
if isinstance(d, list) and hasattr(d[0], '__len__'):
if weight_pos is not None:

new_dict = { i: tup for i,tup in enumerate(d) }
d = { i: tup[weight_pos] for i,tup in enumerate(d) }
isdict = True
else:
raise Exception("no weight axis provided for tuple list")
key = lambda x: x[weight_pos]
if key is None:
raise ValueError("Must provide weight_pos or key for tuple list")

if isinstance(d, list) and key:
new_dict = {i: val for i, val in enumerate(d)}
print(new_dict)
d = {i: key(val) for i, val in enumerate(d)}
isdict = True
is_tuple_list = True
else:
is_tuple_list = False

if isdict:

Expand Down

0 comments on commit d1bfd45

Please sign in to comment.