Beispiel #1
0
 def calculate_done(self):
     for item in self:
         if item.product_id.categ_id.parent_id.name == 'Producto Terminado':
             list_serial_pt = Enumerable(
                 self.workorder_ids[0].summary_out_serial_ids).where(
                     lambda x: x.product_id.id == item.product_id.id).count(
                     )
             for move in item.move_raw_ids.filtered(
                     lambda x: not x.needs_lots):
                 move.active_move_line_ids.sudo().unlink()
                 component_ids = Enumerable(item.bom_id.bom_line_ids).where(
                     lambda x: x.product_id.id == move.product_id.id)
                 self.env['stock.move.line'].create({
                     'product_id':
                     move.product_id.id,
                     'production_id':
                     item.id,
                     'qty_done':
                     list_serial_pt *
                     component_ids.first_or_default().product_qty,
                     'location_id':
                     item.location_src_id.id,
                     'product_uom_id':
                     move.product_id.uom_id.id,
                     'location_dest_id':
                     self.env['stock.location'].search(
                         [('usage', '=', 'production')], limit=1).id,
                     'move_id':
                     move.id,
                     'lot_produced_id':
                     item.finished_move_line_ids.filtered(
                         lambda x: x.product_id.id == item.product_id.id).
                     lot_id.id
                 })
Beispiel #2
0
 def DBSCANForMatches(self, matches, R, DENSITY):
     values = Enumerable(list())
     for match in matches:
         values.append(
             MinimumSetCoverAlgorithm.ComputeMatchValue(match))
     values = values.order_by(lambda v: v).to_list()
     return self.DBSCAN(values, R, DENSITY)
Beispiel #3
0
    def test_issue22(self):
        def my_iter():
            for i in range(10):
                yield i

        def low_iter():
            for i in range(5):
                yield i

        def high_iter():
            for k in range(5):
                yield k + 5

        data = my_iter()
        a = Enumerable(data)

        low = a.where(lambda x: x < 5)
        high = a.where(lambda x: x >= 5)

        self.assertListEqual(
            [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)], low.zip(high).to_list()
        )

        self.assertListEqual(
            [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)], list(zip(low, high))
        )
Beispiel #4
0
    def test_group_by(self):
        simple_grouped = self.simple.group_by(key_names=['id'])
        self.assertEqual(simple_grouped.count(), 3,
                         u"Three grouped elements in simple grouped")
        for g in simple_grouped:
            self.assertEqual(
                g.key.id, g.first(),
                u"Each id in simple grouped should match first value")

        complex_grouped = self.complex.group_by(key_names=['value'],
                                                key=lambda x: x['value'])
        self.assertEqual(complex_grouped.count(), 3,
                         u"Three grouped elements in complex grouped")
        for g in complex_grouped:
            self.assertEqual(
                g.key.value,
                g.select(lambda x: x['value']).first(),
                u"Each value in complex grouped should mach first value")

        locations_grouped = Enumerable(_locations) \
            .group_by(
            key_names=['country', 'city'],
            key=lambda x: [x[0], x[1]])
        self.assertEqual(locations_grouped.count(), 7,
                         u"Seven grouped elements in locations grouped")

        london = locations_grouped \
            .single(
                lambda c: c.key.city == 'London' and c.key.country == 'England'
            )
        self.assertEqual(london.sum(lambda c: c[3]), 240000,
                         u"Sum of London, England location does not equal")
Beispiel #5
0
    def test_issue22_join(self):
        class Val(object):
            def __init__(self, number, power):
                self.number = number
                self.power = power

            def __str__(self):
                return "VAL {0}: {1}".format(self.number, self.power)

        def powers_of_2():
            for i in range(2):
                yield Val(i, 2**i)

        def powers_of_10():
            for i in range(2):
                yield Val(i, 10**i)

        en2 = Enumerable(powers_of_2())
        en10 = Enumerable(powers_of_10())
        joined = en2.join(
            en10,
            lambda x: x.number,
            lambda y: y.number,
            lambda r: (r[0].power, r[1].power),
        )
        truth = zip([2**i for i in range(2)], [10**y for y in range(2)])
        self.assertListEqual(list(truth), joined.to_list())
Beispiel #6
0
    def test_issue_52_2(self):

        e1 = Enumerable([{
            "value": 1
        }, {
            "value": 2
        }, {
            "value": 3
        }, {
            "value": 0
        }])
        e2 = Enumerable([1, 2, 3, 1, 2, 1])
        res = e1.group_join(
            e2,
            outer_key=lambda x: x["value"],
            inner_key=lambda y: y,
            result_func=lambda r: (r[0], r[1].to_list()),
        )

        self.assertListEqual(
            [
                ({
                    "value": 1
                }, [1, 1, 1]),
                ({
                    "value": 2
                }, [2, 2]),
                ({
                    "value": 3
                }, [3]),
            ],
            res.to_list(),
        )
def get_credit_spreads_portfolio():
    """Find the current credit spreads in the portfolio"""
    # retrieve open option positions
    add_event_log('function[get_credit_spreads_portfolio] Entering')

    open_positions = rs.options.get_open_option_positions()
    add_event_log(
        'function[get_credit_spreads_portfolio] {0}'.format(open_positions))

    # list of CreditSpread objects
    credit_list: list = list()

    # two positions are required to make a credit spread if only one position remains there are no more spreads.
    while len(open_positions) > 1:
        # checks the update time stamp
        pairs = Enumerable(open_positions).where(lambda x: x['updated_at'][
            0:19:1] == open_positions[0]['updated_at'][0:19:1]).to_list()

        # pairs are updated at the same time. two positions updated within 1 second of each other belong together.
        if len(pairs) == 2:
            # get option specific details for the long and short positions
            long = rs.helper.request_get(
                Enumerable(pairs).where(lambda x: x['type'] == 'long').select(
                    lambda x: x['option'])[0])
            short = rs.helper.request_get(
                Enumerable(pairs).where(lambda x: x['type'] == 'short').select(
                    lambda x: x['option'])[0])

            # define the variables in the credit spread object
            symbol = long['chain_symbol']
            expiration_date: str = long['expiration_date']
            quantity = int(float(pairs[0]['quantity']))
            option_type: str = long['type']
            buy_strike: float = float(long['strike_price'])
            sell_strike: float = float(short['strike_price'])
            buy_price: float = abs(
                float(
                    Enumerable(pairs).where(lambda x: x['type'] == 'long').
                    select(lambda x: x['average_price'])[0]))
            sell_price: float = abs(
                float(
                    Enumerable(pairs).where(lambda x: x['type'] == 'short').
                    select(lambda x: x['average_price'])[0]))
            purchase_date = long['created_at'][0:10:1]
            # add Credit Spread object to the credit spread list
            my_spread = CreditSpread(symbol, expiration_date, quantity,
                                     buy_strike, sell_strike, buy_price,
                                     sell_price, option_type, purchase_date)

            credit_list.append(my_spread)

            # remove the current item from list to prevent duplicate Credit Spread objects
            open_positions.pop(0)
        else:
            # remove current item if the number is anything other than two
            open_positions.pop(0)

        # return the list of Credit Spread objects
    add_event_log('function[get_credit_spreads_portfolio] Exiting')
    return credit_list
Beispiel #8
0
 def test_except(self):
     self.assertRaises(TypeError, self.empty.except_, [])
     self.assertListEqual(
         self.empty.except_(self.empty).to_list(), [],
         u"Complement of two empty enumerables yields empty list")
     self.assertListEqual(
         self.empty.except_(self.simple).to_list(), [],
         u"Complement of empty and simple enumerables yields empty list")
     self.assertListEqual(
         self.simple.except_(self.empty).to_list(), _simple,
         u"Complement of simple and empty enumerables yields simple list")
     self.assertListEqual(
         self.simple.except_(self.simple).to_list(), [],
         u"Complement of simple and simple enumerables yields empty list")
     self.assertListEqual(
         self.simple.except_(Enumerable([2])).to_list(), [1, 3],
         u"Complement of simple and [2] yields [1,3]")
     self.assertListEqual(
         self.simple.except_(self.complex).to_list(), _simple,
         u"Complement of simple and complex yields simple")
     self.assertListEqual(
         self.complex.except_(self.simple).to_list(), _complex,
         u"Complement of complex and simple yields complex")
     self.assertListEqual(
         self.complex.except_(self.complex).to_list(), [],
         u"Complement of complex and complex yields empty")
     self.assertListEqual(
         self.complex.except_(Enumerable([{
             'value': 1
         }])).to_list(), [{
             'value': 2
         }, {
             'value': 3
         }], "Should yield [{'value': 2}, 'value': 3]")
Beispiel #9
0
def task_2_linq():
    cur = con.cursor()
    try:
        cur.execute('''
            select * from visits;
        ''')

        visits = Enumerable(cur.fetchall())
        con.commit()
        cur.close()

        non_exitors = (visits.group_by(
            key_names=['id_emp',
                       'visit_type'], key=lambda t: (t[0], t[4]))).select(
                           lambda a: {
                               'visit_type': a.key.visit_type,
                               'id_emp': a.key.id_emp,
                               'count': a.count()
                           }).where(lambda r: r['visit_type'] == 2 and r[
                               'count'] > 1).to_list()

        print(non_exitors)

    except:
        con.rollback()
Beispiel #10
0
 def test_intersect(self):
     self.assertRaises(TypeError, self.empty.intersect, [])
     self.assertListEqual(
         self.empty.intersect(self.empty).to_list(),
         [],
         u"Intersect of two empty enumerables yield empty list")
     self.assertListEqual(
         self.empty.intersect(self.simple).to_list(),
         [],
         u"Intersect of empty and simple enumerables yields empty list")
     self.assertListEqual(
         self.simple.intersect(self.simple).to_list(),
         _simple,
         u"Intersect of two simple enumerables yields simple list")
     self.assertListEqual(
         self.simple.intersect(Enumerable([2])).to_list(),
         [2],
         u"Intersect of simple enumerable and [2] yields [2]")
     self.assertListEqual(
         self.simple.intersect(self.complex).to_list(),
         [],
         u"Intersect of simple and complex enumerable yields empty list")
     self.assertListEqual(
         self.complex.intersect(self.complex).to_list(),
         _complex,
         u"Intersect of two complex enumeraable yields complex list")
     self.assertListEqual(
         self.complex.intersect(Enumerable([{'value': 1}])).to_list(),
         [{'value': 1}],
         "Should yield {'value': 1}")
Beispiel #11
0
 def test_select_many(self):
     self.assertListEqual([], Enumerable([[], [], []]).select_many().to_list())
     self.assertListEqual(
         [1, 2, 3, 4, 5, 6, 7, 8, 9],
         Enumerable([[1, 2, 3], [4, 5, 6], [7, 8, 9]]).select_many().to_list(),
     )
     self.assertEqual(
         9, Enumerable([[1, 2, 3], [4, 5, 6], [7, 8, 9]]).select_many().count()
     )
     self.assertListEqual(
         [1, 2, 3, 4, 5, 6, 7, 8, 9],
         Enumerable(
             [
                 {"key": 1, "values": [1, 2, 3]},
                 {"key": 2, "values": [4, 5, 6]},
                 {"key": 3, "values": [7, 8, 9]},
             ]
         )
         .select_many(lambda x: x["values"])
         .to_list(),
     )
     self.assertEqual(
         9,
         Enumerable(
             [
                 {"key": 1, "values": [1, 2, 3]},
                 {"key": 2, "values": [4, 5, 6]},
                 {"key": 3, "values": [7, 8, 9]},
             ]
         )
         .select_many(lambda x: x["values"])
         .count(),
     )
def save_to_json(final_list):
    posts = []
    for j in range(len(final_list[0])):
        posts.append({
            'id': final_list[0][j],
            'author': final_list[1][j],
            'text': final_list[2][j],
            'links': '\n'.join(final_list[3][j]),
            'images': '\n'.join(final_list[4][j])
        })
    with open('posts.json', 'a+') as f:
        f.seek(0, 2)
        if f.tell() == 0:
            json.dump(posts, f, indent=2, ensure_ascii=False)
        else:
            lst = load_from_json()
            collection = Enumerable(posts)
            result = collection.select(lambda x: check_equals(x, lst))
            result = result.to_list()
            result = [x for x in result if x]
            f.seek(f.tell()-1, 0)
            f.truncate()
            for i in range(len(result)):
                f.write(' ,\n')
                json.dump(result[i], f, indent=2, ensure_ascii=False)
            f.write('\n]')
    print('json файл сохранен')
Beispiel #13
0
    def equip_item(self, inventory_item_id):
        """Marks the item as equipped which will add to a character's stats
        
        Arguments:
            inventory_item_id {string} -- Identifies the item in the inventory
        """
        if self.inventory is None:
            self.inventory = []
        
        item = Enumerable(self.inventory).first_or_default(lambda x: x.inv_id == inventory_item_id)

        if item is None:
            raise Exception("The item does not exist in the inventory")
        
        if not self.can_use_2h and item.slot == 14:
            raise Exception("Cannot equip a two-handed weapon")
        # else:
        #     self.attack_speed = damage_base[self.player_class]['speed'] * 1.25

        if not self.can_dual_wield and item.slot == 13:
            raise Exception("Cannot equip a weapon in the off hand")

        existing_item = Enumerable(self.inventory).first_or_default(lambda x: x.slot == item.slot and x.equipped)
        
        if existing_item is not None:
            self.unequip_item(existing_item.inv_id)
            #existing_item.equipped = False

        item.equipped = True    
        self.calc_stats()
        self.updated_at = datetime.utcnow()
        super(CharacterModel, self).save()
Beispiel #14
0
 def test_then_by(self):
     locations = Enumerable(_locations)
     self.assertListEqual(
         locations.order_by(lambda l: l[0])
         .then_by(lambda l: l[1])
         .select(lambda l: u"{0}, {1}".format(l[1], l[0]))
         .to_list(),
         [
             u'Liverpool, England',
             u'Liverpool, England',
             u'London, England',
             u'London, England',
             u'London, England',
             u'Manchester, England',
             u'Manchester, England',
             u'Edinburgh, Scotland',
             u'Glasgow, Scotland',
             u'Glasgow, Scotland',
             u'Bangor, Wales',
             u'Cardiff, Wales',
             u'Cardiff, Wales'
         ],
         u"then_by locations ordering is not correct")
     self.assertRaises(
         NullArgumentError,
         locations.order_by(lambda l: l[0]).then_by,
         None)
Beispiel #15
0
 def test_then_by_descending(self):
     locations = Enumerable(_locations)
     self.assertListEqual(
         locations.order_by(lambda l: l[0])
         .then_by(lambda l: l[1])
         .then_by_descending(lambda l: l[3])
         .select(lambda l: u"{0}, {1}: {2}".format(
             l[1], l[0], l[3]
         ))
         .to_list(),
         [
             u'Liverpool, England: 29700',
             u'Liverpool, England: 25000',
             u'London, England: 90000',
             u'London, England: 80000',
             u'London, England: 70000',
             u'Manchester, England: 50000',
             u'Manchester, England: 45600',
             u'Edinburgh, Scotland: 20000',
             u'Glasgow, Scotland: 12500',
             u'Glasgow, Scotland: 12000',
             u'Bangor, Wales: 12800',
             u'Cardiff, Wales: 30000',
             u'Cardiff, Wales: 29700'
         ],
         u"then_by_descending ordering is not correct"
     )
Beispiel #16
0
 def test_then_by(self):
     locations = Enumerable(_locations)
     self.assertRaises(
         NullArgumentError, locations.order_by(lambda l: l[0]).then_by, None
     )
     self.assertListEqual(
         [
             u"Liverpool, England",
             u"Liverpool, England",
             u"London, England",
             u"London, England",
             u"London, England",
             u"Manchester, England",
             u"Manchester, England",
             u"Edinburgh, Scotland",
             u"Glasgow, Scotland",
             u"Glasgow, Scotland",
             u"Bangor, Wales",
             u"Cardiff, Wales",
             u"Cardiff, Wales",
         ],
         locations.order_by(lambda l: l[0])
         .then_by(lambda l: l[1])
         .select(lambda l: u"{0}, {1}".format(l[1], l[0]))
         .to_list(),
     )
Beispiel #17
0
 def test_marks_except(self):
     marks1 = Enumerable([{'course': 'Chemistry', 'mark': 90}, {'course': 'Biology', 'mark': 85}])
     marks2 = Enumerable([{'course': 'Chemistry', 'mark': 65}, {'course': 'Computer Science', 'mark': 96}])
     self.assertListEqual(
         marks1.except_(marks2, lambda c: c['course']).to_list(),
         [{'course': 'Biology', 'mark': 85}]
     )
Beispiel #18
0
 def test_union(self):
     self.assertListEqual([], self.empty.union(self.empty).to_list())
     self.assertListEqual(
         _simple,
         self.empty.union(self.simple).order_by(lambda x: x).to_list())
     self.assertListEqual(
         _simple,
         self.simple.union(self.empty).order_by(lambda x: x).to_list())
     self.assertListEqual(
         _complex,
         self.empty.union(
             self.complex).order_by(lambda x: x["value"]).to_list(),
     )
     self.assertListEqual(
         _complex,
         self.complex.union(
             self.empty).order_by(lambda x: x["value"]).to_list(),
     )
     self.assertListEqual(
         _simple + [4, 5],
         self.simple.union(Enumerable([4,
                                       5])).order_by(lambda x: x).to_list(),
     )
     self.assertListEqual(
         _simple + [4, 5],
         self.simple.union(Enumerable([1, 4,
                                       5])).order_by(lambda x: x).to_list(),
     )
     self.assertListEqual(
         _complex + [{
             "value": 4
         }, {
             "value": 5
         }],
         self.complex.union(
             Enumerable([{
                 "value": 4
             }, {
                 "value": 5
             }]),
             lambda x: x["value"]).order_by(lambda x: x["value"]).to_list(),
     )
     self.assertListEqual(
         _complex + [{
             "value": 4
         }, {
             "value": 5
         }],
         self.complex.union(
             Enumerable([{
                 "value": 1
             }, {
                 "value": 4
             }, {
                 "value": 5
             }]),
             lambda x: x["value"],
         ).order_by(lambda x: x["value"]).order_by(
             lambda x: x["value"]).to_list(),
     )
Beispiel #19
0
 def test_marks_except(self):
     marks1 = Enumerable([{
         "course": "Chemistry",
         "mark": 90
     }, {
         "course": "Biology",
         "mark": 85
     }])
     marks2 = Enumerable([
         {
             "course": "Chemistry",
             "mark": 65
         },
         {
             "course": "Computer Science",
             "mark": 96
         },
     ])
     self.assertListEqual(
         [{
             "course": "Biology",
             "mark": 85
         }],
         marks1.except_(marks2, lambda c: c["course"]).to_list(),
     )
def parseInference(query):
    config = Config()
    attCouples = Enumerable(
        query.split(';')).select(lambda x: x.split('=')).to_list()
    row = Enumerable(
        config.evidences()).select(lambda x: getVals(x, attCouples)).to_list()
    row.append(None)
    return Snapshot(row)
Beispiel #21
0
    def test_reverse(self):
        test = self.simple.reverse()
        self.assertListEqual(test.to_list(), [3, 2, 1])

        words = u"the quick brown fox jumps over the lazy dog".split(" ")
        self.assertListEqual(words, ["the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"])
        test = Enumerable(words).reverse()
        self.assertEqual(u" ".join(test.to_list()), u"dog lazy the over jumps fox brown quick the")
Beispiel #22
0
    def test_issue19(self):
        foo = Enumerable([1])
        bar = Enumerable([1])
        self.assertEqual(foo.intersect(bar).count(), 1)

        foo = Enumerable([1])
        bar = Enumerable([1]).distinct()
        self.assertEqual(foo.intersect(bar).count(), 1)
Beispiel #23
0
    def test_distinct(self):
        self.assertListEqual([], self.empty.distinct().to_list())
        six.assertCountEqual(
            self, _simple,
            self.simple.concat(self.simple).distinct().to_list())

        locations = Enumerable(_locations).distinct(lambda x: x[0])
        self.assertEqual(locations.count(), 3)
 def CreatePageDatabaseRelation(self, choosen_relations, page):
     choosen_relations = Enumerable(choosen_relations)
     field_column_relation = dict()
     for field in page.GetFields():
         field_column_relation[field] = choosen_relations.where(
             lambda fc: fc.field.Equals(field)).first()
     return PageDatabaseRelation(
         page, field_column_relation.values(),
         MinimumSetCoverAlgorithm().current_best_value)
Beispiel #25
0
    def test_all(self):
        test = Enumerable([1, 1, 1]).all(lambda x: x == 1)
        self.assertTrue(test)

        test = Enumerable([]).all(lambda x: x == 1)
        self.assertTrue(test)

        test = self.simple.all(lambda x: x == 1)
        self.assertFalse(test)
def search_links(post):
    post_links = post.find_all('a', {"target": "_blank"})
    if len(post_links) > 0:
        post_links_collection = Enumerable(post_links)
        links = post_links_collection.select(lambda x: 'https://vk.com'+x.attrs["href"])
        links = links.to_list()
        links = sorted(set(links))
        return links
    else:
        return ["Ссылки отсутсвуют."]
Beispiel #27
0
    def test_aggregate(self):
        words = u"the quick brown fox jumps over the lazy dog".split(" ")
        self.assertListEqual(words, ["the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"])
        test = Enumerable(words).aggregate(self.reverse)
        self.assertEqual(test, "dog lazy the over jumps fox brown quick the")

        self.assertRaises(NoElementsError, Enumerable().aggregate, [lambda x: x[0] + x[1], 0])

        test = self.simple.aggregate(self.sum, seed=0)
        self.assertEqual(test, 6)
Beispiel #28
0
def find_dep_2():
    cursor = connection.cursor(cursor_factory=DictCursor)
    cursor.execute('select * from employee')
    employee = Enumerable(cursor.fetchall())
    cursor.close()

    dep = (employee.group_by(key_names=['department'], key = lambda x: x['department']))\
        .select(lambda g: {'department': g.key.department, 'cnt':g.count()}).where(lambda g: g['cnt'] > 10)\
        .to_list()
    print(dep)
Beispiel #29
0
    def test_select_many(self):
        empty = Enumerable([[], [], []])
        simple = Enumerable([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        __complex = Enumerable([
            {
                "key": 1,
                "values": [1, 2, 3]
            },
            {
                "key": 2,
                "values": [4, 5, 6]
            },
            {
                "key": 3,
                "values": [7, 8, 9]
            },
        ])

        self.assertListEqual([], empty.select_many().to_list())
        self.assertListEqual([1, 2, 3, 4, 5, 6, 7, 8, 9],
                             simple.select_many().to_list())
        self.assertListEqual(
            [1, 2, 3, 4, 5, 6, 7, 8, 9],
            __complex.select_many(lambda x: x["values"]).to_list(),
        )
Beispiel #30
0
 def test_multiple_concatenate(self):
     simple = Enumerable([1, 2, 3])
     simple.add(4)
     self.assertEqual(4, simple.count())
     simple.add(5)
     self.assertEqual(5, simple.count())
     self.assertEqual(5, simple.last())
Beispiel #31
0
    def update_character_hp(self, char_id, attack_amt):
        character = Enumerable(
            self.characters).first_or_default(lambda x: x.id == char_id)
        character.prev_hp = character.curr_hp

        if character.curr_hp - attack_amt <= 0:
            character.curr_hp = 0
            character.status = 'DEAD'
            self.is_active = False
        else:
            character.curr_hp -= attack_amt

        self.save()
    def test_group_by(self):
        simple_grouped = self.simple.group_by(key_names=['id'])
        self.assertEqual(
            simple_grouped.count(),
            3,
            u"Three grouped elements in simple grouped")
        for g in simple_grouped:
            self.assertEqual(
                g.key.id,
                g.first(),
                u"Each id in simple grouped should match first value")

        complex_grouped = self.complex.group_by(
            key_names=['value'],
            key=lambda x: x['value'])
        self.assertEqual(
            complex_grouped.count(),
            3,
            u"Three grouped elements in complex grouped")
        for g in complex_grouped:
            self.assertEqual(
                g.key.value,
                g.select(lambda x: x['value']).first(),
                u"Each value in complex grouped should mach first value")

        locations_grouped = Enumerable(_locations) \
            .group_by(
            key_names=['country', 'city'],
            key=lambda x: [x[0], x[1]])
        self.assertEqual(
            locations_grouped.count(),
            7,
            u"Seven grouped elements in locations grouped")

        london = locations_grouped \
            .single(
                lambda c: c.key.city == 'London' and c.key.country == 'England'
            )
        self.assertEqual(
            london.sum(lambda c: c[3]),
            240000,
            u"Sum of London, England location does not equal")
 def test_distinct(self):
     self.assertListEqual(
         self.empty.distinct().to_list(),
         [],
         u"Distinct empty enumerable yields empty list")
     self.assertListEqual(
         self.simple.concat(self.simple).distinct().to_list(),
         _simple,
         u"Distinct yields simple list")
     locations = Enumerable(_locations).distinct(lambda x: x[0])
     self.assertEqual(
         locations.count(),
         3,
         u"Three distinct countries in locations enumerable")
     self.assertListEqual(
         locations.to_list(),
         [
             ('England', 'London', 'Branch1', 90000),
             ('Scotland', 'Edinburgh', 'Branch1', 20000),
             ('Wales', 'Cardiff', 'Branch1', 29700)
         ],
         u"Distinct locations do not match")
    def test_select_many(self):
        empty = Enumerable([[], [], []])
        simple = Enumerable([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        __complex = Enumerable(
            [
                {'key': 1, 'values': [1, 2, 3]},
                {'key': 2, 'values': [4, 5, 6]},
                {'key': 3, 'values': [7, 8, 9]}
            ]
        )

        self.assertListEqual(
            empty.select_many().to_list(),
            [],
            u"Should yield empty list")
        self.assertListEqual(
            simple.select_many().to_list(),
            [1, 2, 3, 4, 5, 6, 7, 8, 9],
            u"Should yield simple enumerable with single list")
        self.assertListEqual(
            __complex.select_many(lambda x: x['values']).to_list(),
            simple.select_many().to_list(),
            u"Should yield simple enumerable with single list")
 def setUp(self):
     self.empty = Enumerable(_empty)
     self.simple = Enumerable(_simple)
     self.complex = Enumerable(_complex)
class TestFunctions(TestCase):
    def setUp(self):
        self.empty = Enumerable(_empty)
        self.simple = Enumerable(_simple)
        self.complex = Enumerable(_complex)

    def test_to_list(self):
        self.assertListEqual(
            self.empty.to_list(),
            _empty,
            u"Empty to_list not correct")
        self.assertListEqual(
            self.simple.to_list(),
            _simple,
            u"Simple to_list not correct")
        self.assertListEqual(
            self.complex.to_list(),
            _complex,
            u"Complex to_list not correct")

    def test_sum(self):
        self.assertEqual(
            self.empty.sum(),
            0,
            u"Sum of empty enumerable should be 0")
        self.assertEqual(
            self.simple.sum(),
            6,
            u"Sum of simple enumerable should be 6")
        self.assertEqual(
            self.complex.sum(lambda x: x['value']),
            6,
            u"Sum of complex enumerable should be 6")

    def test_count(self):
        self.assertEqual(
            self.empty.count(),
            0,
            u"Empty enumerable has 0 elements")
        self.assertEqual(
            self.simple.count(),
            3,
            u"Simple enumerable has 3 elements")
        self.assertEqual(
            self.complex.count(),
            3,
            u"Complex enumerable has 3 elements")

    def test_select(self):
        self.assertEqual(
            self.empty.select(lambda x: x['value']).count(),
            0,
            u"Empty enumerable should still have 0 elements")

        simple_select = self.simple.select(lambda x: {'value': x})
        self.assertDictEqual(
            simple_select.first(),
            {'value': 1},
            u"Transformed simple enumerable element is dictionary")
        self.assertEqual(
            simple_select.count(),
            3,
            u"Transformed simple enumerable has 3 elements")

        complex_select = self.complex.select(lambda x: x['value'])
        self.assertEqual(
            complex_select.count(),
            3, u"Transformed complex enumerable has 3 elements")
        self.assertIsInstance(
            complex_select.first(),
            int,
            u"Transformed complex enumerable element is integer"
        )

    def test_max_min(self):
        self.assertRaises(NoElementsError, self.empty.min)
        self.assertEqual(
            self.simple.min(),
            1,
            u"Minimum value of simple enumerable is 1")
        self.assertEqual(
            self.complex.min(lambda x: x['value']),
            1,
            u"Min value of complex enumerable is 1"
        )

        self.assertRaises(NoElementsError, self.empty.max)
        self.assertEqual(
            self.simple.max(),
            3,
            u"Max value of simple enumerable is 3")
        self.assertEqual(
            self.complex.max(lambda x: x['value']),
            3,
            u"Max value of complex enumerable is 3")

    def test_avg(self):
        avg = float(2)
        self.assertRaises(NoElementsError, self.empty.avg)
        self.assertEqual(
            self.simple.avg(),
            avg,
            u"Avg value of simple enumerable is {0:.5f}".format(avg))
        self.assertEqual(
            self.complex.avg(lambda x: x['value']),
            avg,
            u"Avg value of complex enumerable is {0:.5f}".format(avg))

    def test_first_last(self):
        self.assertRaises(NoElementsError, self.empty.first)
        self.assertEqual(
            self.empty.first_or_default(),
            None,
            u"First or default should be None")
        self.assertIsInstance(
            self.simple.first(),
            int,
            u"First element in simple enumerable is int")
        self.assertEqual(
            self.simple.first(),
            1,
            u"First element in simple enumerable is 1")
        self.assertEqual(
            self.simple.first(),
            self.simple.first_or_default(),
            u"First and first or default should equal")
        self.assertIsInstance(
            self.complex.first(),
            dict,
            u"First element in complex enumerable is dict")
        self.assertDictEqual(
            self.complex.first(),
            {'value': 1},
            u"First element in complex enumerable is not correct dict")
        self.assertDictEqual(
            self.complex.first(),
            self.complex.first_or_default(),
            u"First and first or default should equal")
        self.assertEqual(
            self.simple.first(),
            self.complex.select(lambda x: x['value']).first(),
            u"First values in simple and complex should equal")

        self.assertRaises(NoElementsError, self.empty.last)
        self.assertEqual(
            self.empty.last_or_default(),
            None,
            u"Last or default should be None")
        self.assertIsInstance(
            self.simple.last(),
            int,
            u"Last element in simple enumerable is int")
        self.assertEqual(
            self.simple.last(),
            3,
            u"Last element in simple enumerable is 3")
        self.assertEqual(
            self.simple.last(),
            self.simple.last_or_default(),
            u"Last and last or default should equal")
        self.assertIsInstance(
            self.complex.last(),
            dict,
            u"Last element in complex enumerable is dict")
        self.assertDictEqual(
            self.complex.last(),
            {'value': 3},
            u"Last element in complex enumerable is not correct dict")
        self.assertDictEqual(
            self.complex.last(),
            self.complex.last_or_default(),
            u"Last and last or default should equal")
        self.assertEqual(
            self.simple.last(),
            self.complex.select(lambda x: x['value']).last(),
            u"Last values in simple and complex should equal")

    def test_sort(self):
        self.assertRaises(NullArgumentError, self.simple.order_by, None)
        self.assertRaises(
            NullArgumentError,
            self.simple.order_by_descending,
            None)

        self.assertListEqual(
            self.simple.order_by(lambda x: x).to_list(),
            self.simple.to_list(),
            u"Simple enumerable sort ascending should yield same list")
        self.assertListEqual(
            self.simple.order_by_descending(lambda x: x).to_list(),
            sorted(self.simple, key=lambda x: x, reverse=True),
            u"Simple enumerable sort descending should yield reverse list")

        self.assertListEqual(
            self.complex.order_by(lambda x: x['value']).to_list(),
            self.complex.to_list(),
            u"Complex enumerable sort ascending should yield same list")
        self.assertListEqual(
            self.complex.order_by_descending(lambda x: x['value']).to_list(),
            sorted(self.complex, key=lambda x: x['value'], reverse=True),
            u"Complex enumerable sort descending should yield reverse list")

        self.assertListEqual(
            self.simple.order_by(lambda x: x).to_list(),
            self.complex.select(
                lambda x: x['value']
            ).order_by(lambda x: x).to_list(),
            u"Projection and sort ascending of complex should yield simple")

    def test_median(self):
        self.assertRaises(NoElementsError, self.empty.median)

        median = float(2)
        self.assertEqual(
            self.simple.median(),
            median,
            u"Median of simple enumerable should be {0:.5f}".format(median))
        self.assertEqual(
            self.complex.median(lambda x: x['value']),
            median,
            u"Median of complex enumerable should be {0:.5f}".format(median))

    def test_skip_take(self):
        self.assertListEqual(
            self.empty.skip(2).to_list(),
            [],
            u"Skip 2 of empty list should yield empty list")
        self.assertListEqual(
            self.empty.take(2).to_list(),
            [],
            u"Take 2 of empty list should yield empty list")
        self.assertListEqual(
            self.simple.skip(3).to_list(),
            [],
            u"Skip 3 of simple enumerable should yield empty list")
        self.assertListEqual(
            self.simple.take(4).to_list(),
            _simple,
            u"Take 4 of simple enumerable should yield simple list")

        self.assertEqual(
            self.simple.skip(1).take(1).first(),
            2,
            u"Skip 1 and take 1 of simple should yield 2")
        self.assertEqual(
            self.complex.select(lambda x: x['value']).skip(1).take(1).first(),
            2,
            u"Skip 1 and take 1 of complex with projection should yield 2")

    def test_filter(self):
        self.assertListEqual(
            self.empty.where(lambda x: x == 0).to_list(),
            [],
            u"Filter on empty list should yield empty list")
        self.assertListEqual(
            self.simple.where(lambda x: x == 2).to_list(),
            [2],
            u"Filter where element equals 2 should yield list with 1 element")
        self.assertListEqual(
            self.complex.where(lambda x: x['value'] == 2).to_list(),
            [{'value': 2}],
            u"Filter where element value is 2 should give list with 1 element")
        self.assertListEqual(
            self.complex.where(lambda x: x['value'] == 2)
                .select(lambda x: x['value'])
                .to_list(),
            self.simple.where(lambda x: x == 2).to_list(),
            u"Should equal filter of simple enumerable")
        self.assertListEqual(
            self.simple.where(lambda x: x == 0).to_list(),
            self.empty.to_list(),
            u"Should yield an empty list")

    def test_single_single_or_default(self):
        self.assertRaises(NullArgumentError, self.empty.single, None)

        self.assertRaises(
            NoMatchingElement,
            self.empty.single,
            lambda x: x == 0)
        self.assertRaises(
            NoMatchingElement,
            self.simple.single,
            lambda x: x == 0)
        self.assertRaises(
            NoMatchingElement,
            self.complex.single,
            lambda x: x['value'] == 0)
        self.assertRaises(
            MoreThanOneMatchingElement,
            self.simple.single,
            lambda x: x > 0)
        self.assertRaises(
            MoreThanOneMatchingElement,
            self.complex.single,
            lambda x: x['value'] > 0)
        self.assertRaises(
            MoreThanOneMatchingElement,
            self.simple.single_or_default,
            lambda x: x > 0)
        self.assertRaises(
            MoreThanOneMatchingElement,
            self.complex.single_or_default,
            lambda x: x['value'] > 0)

        simple_single = self.simple.single(lambda x: x == 2)
        self.assertIsInstance(
            simple_single,
            int,
            u"Should yield int")
        self.assertEqual(
            simple_single,
            2,
            u"Should yield 2")

        complex_single = self.complex.single(lambda x: x['value'] == 2)
        self.assertIsInstance(
            complex_single,
            dict,
            "Should yield dict")
        self.assertDictEqual(
            complex_single,
            {'value': 2},
            u"Yield '{'value':2}'")
        self.assertEqual(
            simple_single,
            self.complex.select(lambda x: x['value']).single(lambda x: x == 2),
            u"Projection and single on complex should yield single on simple")

        self.assertEqual(
            self.empty.single_or_default(lambda x: x == 0),
            None,
            u"Single or default on empty list should yield None")
        self.assertEqual(
            self.simple.single_or_default(lambda x: x == 0),
            None,
            u"Should yield None")
        self.assertEqual(
            self.complex.single_or_default(lambda x: x['value'] == 0),
            None,
            u"Should yield None")

    def test_select_many(self):
        empty = Enumerable([[], [], []])
        simple = Enumerable([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        __complex = Enumerable(
            [
                {'key': 1, 'values': [1, 2, 3]},
                {'key': 2, 'values': [4, 5, 6]},
                {'key': 3, 'values': [7, 8, 9]}
            ]
        )

        self.assertListEqual(
            empty.select_many().to_list(),
            [],
            u"Should yield empty list")
        self.assertListEqual(
            simple.select_many().to_list(),
            [1, 2, 3, 4, 5, 6, 7, 8, 9],
            u"Should yield simple enumerable with single list")
        self.assertListEqual(
            __complex.select_many(lambda x: x['values']).to_list(),
            simple.select_many().to_list(),
            u"Should yield simple enumerable with single list")

    def test_concat(self):
        self.assertListEqual(
            self.empty.concat(self.empty).to_list(),
            [],
            u"Concatenation of 2 empty lists gives empty list")
        self.assertListEqual(
            self.empty.concat(self.simple).to_list(),
            _simple,
            u"Concatenation of empty to simple yields simple")
        self.assertListEqual(
            self.simple.concat(self.empty).to_list(),
            _simple,
            u"Concatenation of simple to empty yields simple")

    def test_group_by(self):
        simple_grouped = self.simple.group_by(key_names=['id'])
        self.assertEqual(
            simple_grouped.count(),
            3,
            u"Three grouped elements in simple grouped")
        for g in simple_grouped:
            self.assertEqual(
                g.key.id,
                g.first(),
                u"Each id in simple grouped should match first value")

        complex_grouped = self.complex.group_by(
            key_names=['value'],
            key=lambda x: x['value'])
        self.assertEqual(
            complex_grouped.count(),
            3,
            u"Three grouped elements in complex grouped")
        for g in complex_grouped:
            self.assertEqual(
                g.key.value,
                g.select(lambda x: x['value']).first(),
                u"Each value in complex grouped should mach first value")

        locations_grouped = Enumerable(_locations) \
            .group_by(
            key_names=['country', 'city'],
            key=lambda x: [x[0], x[1]])
        self.assertEqual(
            locations_grouped.count(),
            7,
            u"Seven grouped elements in locations grouped")

        london = locations_grouped \
            .single(
                lambda c: c.key.city == 'London' and c.key.country == 'England'
            )
        self.assertEqual(
            london.sum(lambda c: c[3]),
            240000,
            u"Sum of London, England location does not equal")

    def test_distinct(self):
        self.assertListEqual(
            self.empty.distinct().to_list(),
            [],
            u"Distinct empty enumerable yields empty list")
        self.assertListEqual(
            self.simple.concat(self.simple).distinct().to_list(),
            _simple,
            u"Distinct yields simple list")
        locations = Enumerable(_locations).distinct(lambda x: x[0])
        self.assertEqual(
            locations.count(),
            3,
            u"Three distinct countries in locations enumerable")
        self.assertListEqual(
            locations.to_list(),
            [
                ('England', 'London', 'Branch1', 90000),
                ('Scotland', 'Edinburgh', 'Branch1', 20000),
                ('Wales', 'Cardiff', 'Branch1', 29700)
            ],
            u"Distinct locations do not match")

    def test_default_if_empty(self):
        self.assertListEqual(
            self.empty.default_if_empty().to_list(),
            [None],
            u"Should yield None singleton")
        self.assertListEqual(
            self.simple.default_if_empty().to_list(),
            _simple,
            u"Default if empty of simple enumerable should yield simple list")
        self.assertListEqual(
            self.complex.default_if_empty().to_list(),
            _complex,
            u"Should yield complex list")

    def test_any(self):
        self.assertRaises(NullArgumentError, self.simple.any, None)
        self.assertFalse(
            self.empty.any(lambda x: x == 1),
            u"Empty enumerable does not contain any elements that equal 1")
        self.assertTrue(
            self.simple.any(lambda x: x == 1),
            u"Simple enumerable does contain elements that equal 1")
        self.assertFalse(
            self.complex.any(lambda x: x['value'] < 1),
            u"Complex enumerable does not contain any elements with value < 1")
        self.assertTrue(
            self.complex.any(lambda x: x['value'] >= 1),
            u"Complex enumerable does contain elements with value >= 1")

    def test_contains(self):
        self.assertFalse(
            self.empty.contains(1),
            u"Empty enumerable should not contain 1 as element")
        self.assertTrue(
            self.simple.contains(1),
            u"Simple enumerable should contain 1 as element")
        self.assertTrue(
            self.complex.select(lambda x: x['value']).contains(1),
            u"Complex enumerable should contain 1 as an element value")

    def test_intersect(self):
        self.assertRaises(TypeError, self.empty.intersect, [])
        self.assertListEqual(
            self.empty.intersect(self.empty).to_list(),
            [],
            u"Intersect of two empty enumerables yield empty list")
        self.assertListEqual(
            self.empty.intersect(self.simple).to_list(),
            [],
            u"Intersect of empty and simple enumerables yields empty list")
        self.assertListEqual(
            self.simple.intersect(self.simple).to_list(),
            _simple,
            u"Intersect of two simple enumerables yields simple list")
        self.assertListEqual(
            self.simple.intersect(Enumerable([2])).to_list(),
            [2],
            u"Intersect of simple enumerable and [2] yields [2]")
        self.assertListEqual(
            self.simple.intersect(self.complex).to_list(),
            [],
            u"Intersect of simple and complex enumerable yields empty list")
        self.assertListEqual(
            self.complex.intersect(self.complex).to_list(),
            _complex,
            u"Intersect of two complex enumeraable yields complex list")
        self.assertListEqual(
            self.complex.intersect(Enumerable([{'value': 1}])).to_list(),
            [{'value': 1}],
            "Should yield {'value': 1}")

    def test_except(self):
        self.assertRaises(TypeError, self.empty.except_, [])
        self.assertListEqual(
            self.empty.except_(self.empty).to_list(),
            [],
            u"Complement of two empty enumerables yields empty list")
        self.assertListEqual(
            self.empty.except_(self.simple).to_list(),
            [],
            u"Complement of empty and simple enumerables yields empty list")
        self.assertListEqual(
            self.simple.except_(self.empty).to_list(),
            _simple,
            u"Complement of simple and empty enumerables yields simple list")
        self.assertListEqual(
            self.simple.except_(self.simple).to_list(),
            [],
            u"Complement of simple and simple enumerables yields empty list")
        self.assertListEqual(
            self.simple.except_(Enumerable([2])).to_list(),
            [1, 3],
            u"Complement of simple and [2] yields [1,3]")
        self.assertListEqual(
            self.simple.except_(self.complex).to_list(),
            _simple,
            u"Complement of simple and complex yields simple")
        self.assertListEqual(
            self.complex.except_(self.simple).to_list(),
            _complex,
            u"Complement of complex and simple yields complex")
        self.assertListEqual(
            self.complex.except_(self.complex).to_list(),
            [],
            u"Complement of complex and complex yields empty")
        self.assertListEqual(
            self.complex.except_(Enumerable([{'value': 1}])).to_list(),
            [{'value': 2}, {'value': 3}],
            "Should yield [{'value': 2}, 'value': 3]")

    def test_marks_intersect(self):
        marks1 = Enumerable([{'course': 'Chemistry', 'mark': 90}, {'course': 'Biology', 'mark': 85}])
        marks2 = Enumerable([{'course': 'Chemistry', 'mark': 65}, {'course': 'Computer Science', 'mark': 96}])
        self.assertListEqual(
            marks1.intersect(marks2, lambda c: c['course']).to_list(),
            [{'course': 'Chemistry', 'mark': 90}]
        )

    def test_marks_except(self):
        marks1 = Enumerable([{'course': 'Chemistry', 'mark': 90}, {'course': 'Biology', 'mark': 85}])
        marks2 = Enumerable([{'course': 'Chemistry', 'mark': 65}, {'course': 'Computer Science', 'mark': 96}])
        self.assertListEqual(
            marks1.except_(marks2, lambda c: c['course']).to_list(),
            [{'course': 'Biology', 'mark': 85}]
        )

    def test_union(self):
        self.assertListEqual(
            self.empty.union(self.empty).to_list(),
            [],
            u"Union of two empty enumerables yields empty list")
        self.assertListEqual(
            self.empty.union(self.simple).to_list(),
            _simple,
            u"Union of empty and simple yield simple")
        self.assertListEqual(
            self.simple.union(self.empty).to_list(),
            _simple,
            u"Union of simple and empty yield simple")
        self.assertListEqual(
            self.empty.union(self.complex).to_list(),
            _complex,
            u"Union of empty and complex yield complex")
        self.assertListEqual(
            self.complex.union(self.empty).to_list(),
            _complex,
            u"Union of complex and empty yield complex")

        simple_extended = _simple + [4, 5]
        self.assertListEqual(
            self.simple.union(Enumerable([4, 5])).to_list(),
            simple_extended,
            u"Union of simple and [4,5] yield simple + [4,5]")
        self.assertListEqual(
            self.simple.union(Enumerable([1, 4, 5]))
                .order_by(lambda x: x).to_list(),
            simple_extended,
            u"Union of simple and [1,4,5] yield simple + [4,5]")

        complex_extended = _complex + [{'value': 4}, {'value': 5}]
        self.assertListEqual(
            self.complex.union(
                Enumerable([{'value': 4}, {'value': 5}]),
                lambda x: x['value']).to_list(),
            complex_extended,
            u"Should yield complex + [{'value': 4}, {'value': 5}]")
        self.assertListEqual(
            self.complex.union(
                Enumerable([{'value': 1}, {'value': 4}, {'value': 5}]),
                lambda x: x['value']).order_by(lambda x: x['value']).to_list(),
            complex_extended,
            u"Should yield complex + [{'value': 4}, {'value': 5}]")

    def test_join(self):
        self.assertRaises(TypeError, self.empty.join, [])
        self.assertListEqual(
            self.empty.join(self.empty).to_list(),
            [],
            u"Joining 2 empty lists should yield empty list")
        self.assertListEqual(
            self.empty.join(self.simple).to_list(),
            [],
            u"Joining empty to simple yields empty list")
        self.assertListEqual(
            self.empty.join(self.complex).to_list(),
            [],
            u"Joining complex to simple yields empty list")

        self.assertListEqual(
            self.simple.join(self.empty).to_list(),
            [],
            u"Joining simple to empty yields empty list")
        self.assertListEqual(
            self.simple.join(self.simple)
                .order_by(lambda x: (x[0], x[1])).to_list(),
            [(1, 1), (2, 2), (3, 3)],
            u"Joining simple to simple yields [(1,1), (2,2), (3,3)]")
        self.assertListEqual(
            self.simple.join(
                self.complex,
                inner_key=lambda x: x['value'],
                result_func=lambda x: (x[0], x[1]['value'])).order_by(
                lambda x: (x[0], x[1])
            ).to_list(),
            [(1, 1), (2, 2), (3, 3)],
            u"Should yield [(1,1), (2,2), (3,3)]")

        self.assertListEqual(
            self.complex.join(
                self.complex,
                result_func=lambda x: (x[0]['value'], x[1]['value'])).order_by(
                    lambda x: (x[0], x[1])).to_list(),
            [(1, 1), (2, 2), (3, 3)],
            u"Should yield [(1,1), (2,2), (3,3)]")

    def test_group_join(self):
        self.assertRaises(TypeError, self.empty.group_join, [])
        self.assertListEqual(
            self.empty.group_join(self.empty).to_list(),
            [],
            u"Group join 2 empty yields empty")

        simple_empty_gj = self.simple.group_join(self.empty)
        self.assertEqual(
            simple_empty_gj.count(),
            3,
            u"Should have 3 elements")
        for i, e in enumerate(simple_empty_gj):
            self.assertEqual(
                e[0],
                i + 1,
                u"number property should be {0}".format(i + 1))
            self.assertEqual(
                e[1].count(),
                0,
                u"Should have 0 elements")
            self.assertEqual(
                e[1].first_or_default(),
                None,
                u"Value of first element should be None")

        simple_gj = self.simple.group_join(
            self.simple,
            result_func=lambda x: {
                'number': x[0],
                'collection': x[1]
            })
        for i, e in enumerate(simple_gj):
            self.assertEqual(
                e['number'],
                i + 1,
                u"number property should be {0}".format(i + 1))
            self.assertEqual(
                e['collection'].count(),
                1,
                u"Should only have one element")
            self.assertEqual(
                e['collection'].first(),
                i + 1,
                u"Value of first element should equal {0}".format(i + 1))

        complex_simple_gj = self.complex.group_join(
            self.simple,
            outer_key=lambda x: x['value'])
        for i, e in enumerate(complex_simple_gj):
            self.assertEqual(
                e[0]['value'],
                i + 1,
                u"value property of each element should be {0}".format(i + 1))
            self.assertEqual(
                e[1].count(),
                1,
                u"Should only have one element")
            self.assertEqual(
                e[1].first(),
                i + 1,
                u"Value of first element should equal {0}".format(i + 1))

        simple_gj = self.simple.group_join(
            Enumerable([2, 3]),
            result_func=lambda x: {
                'number': x[0],
                'collection': x[1]
            }).to_list()
        self.assertEqual(
            len(simple_gj),
            3,
            u"Should be 3 elements")
        for i, e in enumerate(simple_gj):
            self.assertEqual(
                e['number'],
                i + 1,
                u"number property should be {0}".format(i + 1))
            self.assertEqual(
                e['collection'].count(),
                0 if i == 0 else 1,
                u"should have {0} element(s)".format(0 if i == 0 else 1))
            self.assertListEqual(
                e['collection'].to_list(),
                [] if i == 0 else [i + 1],
                u"Collection should equal {0}".format(
                    [] if i == 0 else [i + 1])
            )

    def test_then_by(self):
        locations = Enumerable(_locations)
        self.assertListEqual(
            locations.order_by(lambda l: l[0])
            .then_by(lambda l: l[1])
            .select(lambda l: u"{0}, {1}".format(l[1], l[0]))
            .to_list(),
            [
                u'Liverpool, England',
                u'Liverpool, England',
                u'London, England',
                u'London, England',
                u'London, England',
                u'Manchester, England',
                u'Manchester, England',
                u'Edinburgh, Scotland',
                u'Glasgow, Scotland',
                u'Glasgow, Scotland',
                u'Bangor, Wales',
                u'Cardiff, Wales',
                u'Cardiff, Wales'
            ],
            u"then_by locations ordering is not correct")
        self.assertRaises(
            NullArgumentError,
            locations.order_by(lambda l: l[0]).then_by,
            None)

    def test_then_by_descending(self):
        locations = Enumerable(_locations)
        self.assertListEqual(
            locations.order_by(lambda l: l[0])
            .then_by(lambda l: l[1])
            .then_by_descending(lambda l: l[3])
            .select(lambda l: u"{0}, {1}: {2}".format(
                l[1], l[0], l[3]
            ))
            .to_list(),
            [
                u'Liverpool, England: 29700',
                u'Liverpool, England: 25000',
                u'London, England: 90000',
                u'London, England: 80000',
                u'London, England: 70000',
                u'Manchester, England: 50000',
                u'Manchester, England: 45600',
                u'Edinburgh, Scotland: 20000',
                u'Glasgow, Scotland: 12500',
                u'Glasgow, Scotland: 12000',
                u'Bangor, Wales: 12800',
                u'Cardiff, Wales: 30000',
                u'Cardiff, Wales: 29700'
            ],
            u"then_by_descending ordering is not correct"
        )

    def reverse(self, result, element):
        return element + " " + result

    def sum(self, result, element):
        return result + element

    def test_aggregate(self):
        words = u"the quick brown fox jumps over the lazy dog".split(" ")
        self.assertListEqual(words, ["the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"])
        test = Enumerable(words).aggregate(self.reverse)
        self.assertEqual(test, "dog lazy the over jumps fox brown quick the")

        self.assertRaises(NoElementsError, Enumerable().aggregate, [lambda x: x[0] + x[1], 0])

        test = self.simple.aggregate(self.sum, seed=0)
        self.assertEqual(test, 6)

    def test_all(self):
        test = Enumerable([1, 1, 1]).all(lambda x: x == 1)
        self.assertTrue(test)

        test = Enumerable([]).all(lambda x: x == 1)
        self.assertTrue(test)

        test = self.simple.all(lambda x: x == 1)
        self.assertFalse(test)

    def test_append(self):
        test = self.simple.append(4)
        self.assertEqual(test.count(), 4)
        self.assertEqual(test.element_at(3), 4)

    def test_prepend(self):
        test = self.simple.prepend(4)
        self.assertEqual(test.count(), 4)
        self.assertEqual(test.element_at(0), 4)

    def test_empty(self):
        test = Enumerable.empty()
        self.assertIsInstance(test, Enumerable)
        self.assertEqual(test.count(), 0)

    def test_range(self):
        test = Enumerable.range(1, 3)
        self.assertEqual(test.count(), 3)
        self.assertListEqual(self.simple.to_list(), test.to_list())

    def test_repeat(self):
        test = Enumerable.repeat(u'Z', 10)
        self.assertEqual(test.count(), 10)
        self.assertEqual(u"".join(test.to_list()), u'ZZZZZZZZZZ')

    def test_reverse(self):
        test = self.simple.reverse()
        self.assertListEqual(test.to_list(), [3, 2, 1])

        words = u"the quick brown fox jumps over the lazy dog".split(" ")
        self.assertListEqual(words, ["the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"])
        test = Enumerable(words).reverse()
        self.assertEqual(u" ".join(test.to_list()), u"dog lazy the over jumps fox brown quick the")

    def test_skip_last(self):
        test = Enumerable([1, 2, 3, 4, 5]).skip_last(2)
        self.assertListEqual(test.to_list(), [1, 2, 3])

        test = Enumerable(["one", "two", "three", "four", "five"]).skip(1).skip_last(1)
        self.assertListEqual(test.to_list(), ["two", "three", "four"])

    def test_skip_while(self):
        test = Enumerable([1, 4, 6, 4, 1]).skip_while(lambda x: x < 5)
        self.assertListEqual(test.to_list(), [6, 4, 1])

        test = Enumerable([]).skip_while(lambda x: x < 5)
        self.assertListEqual(test.to_list(), [])

    def test_take_last(self):
        test = Enumerable([1, 2, 3, 4, 5]).take_last(2)
        self.assertListEqual(test.to_list(), [4, 5])

        test = Enumerable(["one", "two", "three", "four", "five"]).take(3).take_last(1)
        self.assertListEqual(test.to_list(), ["three"])

    def test_take_while(self):
        test = Enumerable([1, 4, 6, 4, 1]).take_while(lambda x: x < 5)
        self.assertListEqual(test.to_list(), [1, 4])

        test = Enumerable([]).skip_while(lambda x: x < 5)
        self.assertListEqual(test.to_list(), [])

    def test_zip(self):
        test = Enumerable(["A", "B", "C", "D"]).zip(Enumerable(["x", "y"]), lambda t: "{0}{1}".format(t[0], t[1]))
        self.assertListEqual(test.to_list(), ["Ax", "By"])
    def test_take_while(self):
        test = Enumerable([1, 4, 6, 4, 1]).take_while(lambda x: x < 5)
        self.assertListEqual(test.to_list(), [1, 4])

        test = Enumerable([]).skip_while(lambda x: x < 5)
        self.assertListEqual(test.to_list(), [])
 def test_zip(self):
     test = Enumerable(["A", "B", "C", "D"]).zip(Enumerable(["x", "y"]), lambda t: "{0}{1}".format(t[0], t[1]))
     self.assertListEqual(test.to_list(), ["Ax", "By"])
    def test_take_last(self):
        test = Enumerable([1, 2, 3, 4, 5]).take_last(2)
        self.assertListEqual(test.to_list(), [4, 5])

        test = Enumerable(["one", "two", "three", "four", "five"]).take(3).take_last(1)
        self.assertListEqual(test.to_list(), ["three"])
    def test_skip_last(self):
        test = Enumerable([1, 2, 3, 4, 5]).skip_last(2)
        self.assertListEqual(test.to_list(), [1, 2, 3])

        test = Enumerable(["one", "two", "three", "four", "five"]).skip(1).skip_last(1)
        self.assertListEqual(test.to_list(), ["two", "three", "four"])
 def test_empty(self):
     test = Enumerable.empty()
     self.assertIsInstance(test, Enumerable)
     self.assertEqual(test.count(), 0)
 def test_repeat(self):
     test = Enumerable.repeat(u'Z', 10)
     self.assertEqual(test.count(), 10)
     self.assertEqual(u"".join(test.to_list()), u'ZZZZZZZZZZ')
 def test_range(self):
     test = Enumerable.range(1, 3)
     self.assertEqual(test.count(), 3)
     self.assertListEqual(self.simple.to_list(), test.to_list())