# Path: foil/filters.py
# class AttributeFilter:
#     """
#     Filter a sequence of objects/namedtuples by on attribute value predicates.
# 
#     Parameters
#     ----------
#     keys: group of attribute keys to use as filter set.
#     predicates: values of attribute set to use in filtering.
#     """
# 
#     slots = ('keys', 'predicates', 'indexer')
# 
#     def __init__(self, keys: Tuple[str], predicates: List[Tuple]):
#         self.keys = keys
#         self.predicates = set(predicates)
#         self.indexer = attrgetter(*keys)
# 
#     def including(self, sequence) -> Generator:
#         """Include the sequence elements matching the filter set."""
#         return (element for element in sequence
#                 if self.indexer(element) in self.predicates)
# 
#     def excluding(self, sequence) -> Generator:
#         """Exclude the sequence elements matching the filter set."""
#         return (element for element in sequence
#                 if self.indexer(element) not in self.predicates)
# 
# def create_key_filter(properties: Dict[str, list]) -> List[Tuple]:
#     """Generate combinations of key, value pairs for each key in properties.
# 
#     Examples
#     --------
#     properties = {'ent': ['geo_rev', 'supply_chain'], 'own', 'fi'}
#     >> create_key_filter(properties)
#       --> [('ent', 'geo_rev'), ('ent', 'supply_chain'), ('own', 'fi')]
#     """
# 
#     combinations = (product([k], v) for k, v in properties.items())
# 
#     return chain.from_iterable(combinations)
# 
# def create_indexer(indexes: list):
#     """Create indexer function to pluck values from list."""
# 
#     if len(indexes) == 1:
#         index = indexes[0]
#         return lambda x: (x[index],)
#     else:
#         return itemgetter(*indexes)


import unittest
from collections import namedtuple
from foil.filters import AttributeFilter, create_key_filter, create_indexer
        self.assertEqual(expected, result)

    def test_create_key_filter(self):
        properties = {'sports': ['baseball', 'basketball'],
                      'teams': ['bulls', 'knicks', 'lakers']}

        expected = set([('sports', 'baseball'),
                        ('sports', 'basketball'),
                        ('teams', 'bulls'),
                        ('teams', 'knicks'),
                        ('teams', 'lakers')])
        result = set(create_key_filter(properties))

        self.assertSetEqual(result, expected)


class TestCreateIndexer(unittest.TestCase):

    def setUp(self):
        self.record = [0, 10, 20]

    def test_single_indexer(self):
        indexer = create_indexer([1])

        expected = (10,)
        result = indexer(self.record)

        self.assertEqual(expected, result)

    def test_multi_indexer(self):

# Path: foil/filters.py
# class AttributeFilter:
#     """
#     Filter a sequence of objects/namedtuples by on attribute value predicates.
# 
#     Parameters
#     ----------
#     keys: group of attribute keys to use as filter set.
#     predicates: values of attribute set to use in filtering.
#     """
# 
#     slots = ('keys', 'predicates', 'indexer')
# 
#     def __init__(self, keys: Tuple[str], predicates: List[Tuple]):
#         self.keys = keys
#         self.predicates = set(predicates)
#         self.indexer = attrgetter(*keys)
# 
#     def including(self, sequence) -> Generator:
#         """Include the sequence elements matching the filter set."""
#         return (element for element in sequence
#                 if self.indexer(element) in self.predicates)
# 
#     def excluding(self, sequence) -> Generator:
#         """Exclude the sequence elements matching the filter set."""
#         return (element for element in sequence
#                 if self.indexer(element) not in self.predicates)
# 
# def create_key_filter(properties: Dict[str, list]) -> List[Tuple]:
#     """Generate combinations of key, value pairs for each key in properties.
# 
#     Examples
#     --------
#     properties = {'ent': ['geo_rev', 'supply_chain'], 'own', 'fi'}
#     >> create_key_filter(properties)
#       --> [('ent', 'geo_rev'), ('ent', 'supply_chain'), ('own', 'fi')]
#     """
# 
#     combinations = (product([k], v) for k, v in properties.items())
# 
#     return chain.from_iterable(combinations)
# 
# def create_indexer(indexes: list):
#     """Create indexer function to pluck values from list."""
# 
#     if len(indexes) == 1:
#         index = indexes[0]
#         return lambda x: (x[index],)
#     else:
#         return itemgetter(*indexes)


# Path: tests/test_filters.py
import unittest
from collections import namedtuple
from foil.filters import AttributeFilter, create_key_filter, create_indexer

        self.assertEqual(expected, result)

    def test_create_key_filter(self):
        properties = {'sports': ['baseball', 'basketball'],
                      'teams': ['bulls', 'knicks', 'lakers']}

        expected = set([('sports', 'baseball'),
                        ('sports', 'basketball'),
                        ('teams', 'bulls'),
                        ('teams', 'knicks'),
                        ('teams', 'lakers')])
        result = set(create_key_filter(properties))

        self.assertSetEqual(result, expected)


class TestCreateIndexer(unittest.TestCase):

    def setUp(self):
        self.record = [0, 10, 20]

    def test_single_indexer(self):
        indexer = create_indexer([1])

        expected = (10,)
        result = indexer(self.record)

        self.assertEqual(expected, result)

    def test_multi_indexer(self):

        indexer = create_indexer([2, 0])