Sunday, July 29, 2012

I continued my attempt at improving at Python by checking with others who are willing to look over code and suggest improvements. They provided most of the code below.

One change  in their updated solution is to use lazy evaluation with yield and itemgetter. A nice change to the list comprehension allowed the removal of the len and range and just iterated over each player in the player list to make tuples. The names were clarified to playerRolls and playerGroups instead of referencing a data structure.  The flag to repeat rolls for ties with a while loop has been cleaned out in favor of recursion down each branch.

I modified the previous code by putting it in a function and adding a roll parameter to let me test their code. The pattern of ordering of player's rolling has been changed. It is like a depth first tree traversal now rather than breadth first.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from itertools import groupby
from operator import itemgetter
from random import randint
from collections import deque
 
def rank_players(playerList, roll):
    playerRolls = [(player, roll()) for player in playerList]
    playerGroups = groupby(
        sorted(playerRolls, key=itemgetter(1), reverse=True),
        itemgetter(1))
    for key, group in playerGroups:
        grouped_players = list(group)
        if len(grouped_players) > 1:
            print('tied, need to reroll',grouped_players)
            for player in rank_players(zip(*grouped_players)[0], roll):
                yield player
        else:
            print('rolled ',grouped_players[0])
            yield grouped_players[0]
 
rollData = deque([ 6, 4, 4, 4, 3, 3, 3, 2, 2, 2, 3, 3, 3, 4, 5, 6 ])
order = rank_players(['one','two','three','four'], lambda: rollData.popleft())
print(list(order))
 

No comments: