# Path: foil/order.py
# def partition_ordered(sequence, key=None):
#     """Partition ordered sequence by key.
# 
#     Sequence is expected to already be ordered.
# 
#     Parameters
#     ----------
#     sequence: iterable data.
#     key: partition key function
# 
#     Yields
#     -------
#     iterable tuple(s) of partition key, data list pairs.
# 
#     Examples
#     --------
#     1. By object attributes.
# 
#     Partition sequence of objects by a height and weight attributes
#     into an ordered dict.
# 
#     >> attributes = ('height', 'weight')
#     >> OrderedDict(partition_ordered(sequence, attrgetter(*attributes)))
# 
#     2. By index items.
# 
#     Partition sequence by the first character index of each element.
# 
#     >> index = 0
#     >> sequence = ['112', '124', '289', '220', 'Z23']
#     >> list(partition_ordered(sequence, itemgetter(index)))
#     """
# 
#     yield from ((k, list(g)) for k, g in groupby(sequence, key=key))
# 
# def partition(predicate, iterable):
#     """Use a predicate to partition true and false entries.
# 
#     Reference
#     ---------
#     Python itertools documentation.
#     """
# 
#     t1, t2 = tee(iterable)
# 
#     return filterfalse(predicate, t1), filter(predicate, t2)


import unittest
from collections import namedtuple
from operator import attrgetter, itemgetter
from foil.order import partition_ordered, partition



MockTuple = namedtuple('MockTuple', ('a', 'b'))


def is_even(x):
    return True if x % 2 == 0 else False


class TestPartitionOrdered(unittest.TestCase):

    def test_partition_by_attribute(self):

        data = [{'a': 5, 'b': 8}, {'a': 5, 'b': 7}, {'a': 4, 'b': 4}]
        tups = [MockTuple(**d) for d in data]

        expected = [(5, [MockTuple(a=5, b=8), MockTuple(a=5, b=7)]),
                    (4, [MockTuple(a=4, b=4)])]
        result = list(partition_ordered(tups, key=attrgetter('a')))

        self.assertSequenceEqual(expected, result)

    def test_partition_by_item(self):
        data = ['123', '234', '221', '210', '780', '822']

        expected = [('1', ['123']),
                    ('2', ['234', '221', '210']),
                    ('7', ['780']),
                    ('8', ['822'])]

# Path: foil/order.py
# def partition_ordered(sequence, key=None):
#     """Partition ordered sequence by key.
# 
#     Sequence is expected to already be ordered.
# 
#     Parameters
#     ----------
#     sequence: iterable data.
#     key: partition key function
# 
#     Yields
#     -------
#     iterable tuple(s) of partition key, data list pairs.
# 
#     Examples
#     --------
#     1. By object attributes.
# 
#     Partition sequence of objects by a height and weight attributes
#     into an ordered dict.
# 
#     >> attributes = ('height', 'weight')
#     >> OrderedDict(partition_ordered(sequence, attrgetter(*attributes)))
# 
#     2. By index items.
# 
#     Partition sequence by the first character index of each element.
# 
#     >> index = 0
#     >> sequence = ['112', '124', '289', '220', 'Z23']
#     >> list(partition_ordered(sequence, itemgetter(index)))
#     """
# 
#     yield from ((k, list(g)) for k, g in groupby(sequence, key=key))
# 
# def partition(predicate, iterable):
#     """Use a predicate to partition true and false entries.
# 
#     Reference
#     ---------
#     Python itertools documentation.
#     """
# 
#     t1, t2 = tee(iterable)
# 
#     return filterfalse(predicate, t1), filter(predicate, t2)


# Path: tests/test_order.py
import unittest
from collections import namedtuple
from operator import attrgetter, itemgetter
from foil.order import partition_ordered, partition




MockTuple = namedtuple('MockTuple', ('a', 'b'))


def is_even(x):
    return True if x % 2 == 0 else False


class TestPartitionOrdered(unittest.TestCase):

    def test_partition_by_attribute(self):

        data = [{'a': 5, 'b': 8}, {'a': 5, 'b': 7}, {'a': 4, 'b': 4}]
        tups = [MockTuple(**d) for d in data]

        expected = [(5, [MockTuple(a=5, b=8), MockTuple(a=5, b=7)]),
                    (4, [MockTuple(a=4, b=4)])]
        result = list(partition_ordered(tups, key=attrgetter('a')))

        self.assertSequenceEqual(expected, result)

    def test_partition_by_item(self):
        data = ['123', '234', '221', '210', '780', '822']

        expected = [('1', ['123']),
                    ('2', ['234', '221', '210']),
                    ('7', ['780']),
                    ('8', ['822'])]

        result = list(partition_ordered(data, key=itemgetter(0)))