diff --git a/swh/core/tests/test_utils.py b/swh/core/tests/test_utils.py new file mode 100644 index 0000000..a2fe4a1 --- /dev/null +++ b/swh/core/tests/test_utils.py @@ -0,0 +1,33 @@ +# Copyright (C) 2015-2016 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import unittest + +from nose.tools import istest + +from swh.core import utils + + +class UtilsLib(unittest.TestCase): + + @istest + def grouper(self): + # given + actual_data = utils.grouper((i for i in range(0, 9)), 2) + + out = [] + for d in actual_data: + out.append(list(d)) # force generator resolution for checks + + self.assertEqual(out, [[0, 1], [2, 3], [4, 5], [6, 7], [8]]) + + # given + actual_data = utils.grouper((i for i in range(9, 0, -1)), 4) + + out = [] + for d in actual_data: + out.append(list(d)) # force generator resolution for checks + + self.assertEqual(out, [[9, 8, 7, 6], [5, 4, 3, 2], [1]]) diff --git a/swh/core/utils.py b/swh/core/utils.py new file mode 100644 index 0000000..4a225ef --- /dev/null +++ b/swh/core/utils.py @@ -0,0 +1,24 @@ +# Copyright (C) 2016 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + + +import itertools + + +def grouper(iterable, n): + """Collect data into fixed-length chunks or blocks. + + Args: + iterable: an iterable + n: size of block + fillvalue: value to use for the last block + + Returns: + fixed-length chunks of blocks as iterables + + """ + args = [iter(iterable)] * n + for _data in itertools.zip_longest(*args, fillvalue=None): + yield (d for d in _data if d is not None)