示例#1
0
def section_find_winner(section):
    win_threshold = Voter.count_eligible() * section.majority_for_change
    
    first_votes = {}
    for c in section.change_set.all():
        first_votes[c] = Vote.do_count(section.id, c.id, 1)

    while True:                
        lowest_count, lowest_c = None, None
        tuple_list = list(first_votes.items())
        tuple_list.sort(key=lambda x: x[1])
        
        highest_count = tuple_list[len(tuple_list)-1][1]
        if highest_count >= win_threshold:
            top = [t[0] for t in tuple_list if t[1] == highest_count]
            return section_tie_break(section, top)
        
        lowest_count = tuple_list[0][1]
        elim_cands = [t[0] for t in tuple_list if t[1] == lowest_count]
        lowest_c, _ = section_tie_break(section, elim_cands, find_worst=True)
                    
        # re-assign votes for lowest_c to next pref - TODO: optimize!
        for orig_vote in Vote.objects.filter(section=section, change=lowest_c):
            alternates = Vote.objects.filter(voter=orig_vote.voter, section=section, priority__gt=orig_vote.priority)
            if len(alternates) > 0:
                alt = alternates[0].change
                if alt not in first_votes:
                    first_votes[alt] = 0
                first_votes[alt] += 1
        
        # eliminate lowest_c
        del first_votes[lowest_c]
        
        if len(first_votes) == 0:
            return (None, None)
示例#2
0
def section_tie_break(section, change_list, find_worst=False):
    if len(change_list) == 0:
        raise Exception('av tie break given empty change_list')
    #print('section tie break: ' + ' '.join([c.name for c in change_list]))
    
    change_tuples = []
    for change in change_list:
        prefs = Vote.do_count(section.id, change.id)
        change_tuples.append((change, prefs))
        
    #print('section tie break: ' + str(change_tuples))
    return tie_break(change_tuples, find_worst)