Skip to content

Commit ee46ade

Browse files
committed
-
1 parent d3e5ceb commit ee46ade

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

source_py3/python_toolbox/sequence_tools/misc.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ def partitions(sequence, partition_size=None, n_partitions=None,
7979
By default, if there's a remainder, the last partition will be smaller than
8080
the others. (e.g. a sequence of 7 items, when partitioned into pairs, will
8181
have 3 pairs and then a partition with only 1 element.) Specify
82-
`larger_on_remainder=True` to make the last partition, in case there is
83-
one, be a bigger partition. (e.g. a sequence of a 7 items divided into
82+
`larger_on_remainder=True` to make the last partition be a bigger partition
83+
in case there's a remainder. (e.g. a sequence of a 7 items divided into
8484
pairs would result in 2 pairs and one triplet.)
8585
8686
If you want the remainder partition to be of equal size with the other
@@ -96,6 +96,8 @@ def partitions(sequence, partition_size=None, n_partitions=None,
9696
9797
'''
9898

99+
sequence = ensure_iterable_is_sequence(sequence)
100+
99101
sequence_length = len(sequence)
100102

101103
### Validating input: #####################################################
@@ -109,24 +111,32 @@ def partitions(sequence, partition_size=None, n_partitions=None,
109111

110112
if not allow_remainder and remainder_length > 0:
111113
raise Exception("You set `allow_remainder=False`, but there's a "
112-
"reminder of %s left." % remainder_length)
114+
"remainder of %s left." % remainder_length)
113115
# #
114116
### Finished validating input. ############################################
115117

116118
if partition_size is None:
117-
if larger_on_remainder:
118-
partition_size = sequence_length // n_partitions # (Floor div)
119-
else:
120-
partition_size = math_tools.ceil_div(sequence_length, n_partitions)
119+
120+
floored_partition_size, modulo = divmod(sequence_length,
121+
n_partitions)
122+
if modulo:
123+
if larger_on_remainder:
124+
partition_size = floored_partition_size
125+
n_partitions += 1
126+
# Extra partition will be joined into previous partition
127+
else:
128+
partition_size = floored_partition_size + 1
129+
else: # modulo == 0
130+
partition_size = floored_partition_size
121131
if n_partitions is None:
122132
n_partitions = math_tools.ceil_div(sequence_length, partition_size)
123133

124-
enlarged_length = partition_size * n_partitions
125-
134+
naive_length = partition_size * n_partitions
135+
126136
blocks = [sequence[i : i + partition_size] for i in
127-
range(0, enlarged_length, partition_size)]
137+
range(0, naive_length, partition_size)]
128138

129-
if enlarged_length > sequence_length: # We have a remainder
139+
if naive_length != sequence_length:
130140
assert blocks
131141
if larger_on_remainder:
132142
if len(blocks) >= 2:
@@ -136,7 +146,7 @@ def partitions(sequence, partition_size=None, n_partitions=None,
136146
elif fill_value != NO_FILL_VALUE: # (We use elif because fill is never
137147
# done if `larger_on_remainder=True`.)
138148
filler = itertools.repeat(fill_value,
139-
enlarged_length - sequence_length)
149+
naive_length - sequence_length)
140150
blocks[-1].extend(filler)
141151

142152
return blocks

source_py3/test_python_toolbox/test_sequence_tools/test_partitions.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ def test_larger_on_remainder():
7575
fill_value='gurr') == \
7676
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
7777
assert partitions(tuple(r), 4, larger_on_remainder=True) == \
78-
partitions(tuple(r), n_partitions=3, larger_on_remainder=True) == \
7978
[(0, 1, 2, 3), (4, 5, 6, 7, 8)]
79+
assert partitions(tuple(r), n_partitions=3, larger_on_remainder=True) == \
80+
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
8081

8182
assert partitions([1], 1, larger_on_remainder=True) == \
8283
partitions([1], 2, larger_on_remainder=True) == \
@@ -85,9 +86,12 @@ def test_larger_on_remainder():
8586
partitions([1], 4, larger_on_remainder=True) == \
8687
partitions([1], 1000, larger_on_remainder=True) == \
8788
partitions([1], 1000, larger_on_remainder=True, fill_value='meow') == \
88-
partitions([1], 1000, larger_on_remainder=True, allow_remainder=False,
89-
fill_value='meow') == \
9089
[[1]]
90+
91+
with cute_testing.RaiseAssertor(text='remainder of 1'):
92+
partitions([1], 1000, larger_on_remainder=True, allow_remainder=False,
93+
fill_value='meow')
94+
9195

9296

9397
def test_fill_value():
@@ -96,6 +100,4 @@ def test_fill_value():
96100

97101
assert partitions(r, 3) == [[0, 1, 2], [3, 4]]
98102
assert partitions(r, 3, fill_value=None) == [[0, 1, 2], [3, 4, None]]
99-
with cute_testing.RaiseAssertor(text='fill_value'):
100-
partitions(r, 2, fill_value=None, allow_remainder=False)
101103
assert partitions([], 3, fill_value=None) == []

0 commit comments

Comments
 (0)