list(map(parse, s.split('\t'))) for s in ballots_data.split('\n') if s ] print(ballots_marks) ballots_marks_temp = [[3, 1, 2], [3, 1, 2], [3, 2, 1]] def to_ballot(array): a = [x[0] for x in sorted(zip(candidates, array), key=lambda x: -x[1])] return {"ballot": [x for x in a]} def to_ballot_list(array): a = [x[0] for x in sorted(zip(candidates, array), key=lambda x: -x[1])] return {"ballot": [[x] for x in a]} from pyvotecore.schulze_method import SchulzeMethod from pyvotecore.schulze_stv import SchulzeSTV from pyvotecore.condorcet import CondorcetHelper #a = SchulzeMethod(list(map(to_ballot_list, ballots_marks)), ballot_notation = CondorcetHelper.BALLOT_NOTATION_GROUPING).as_dict() #print(a) #b = STV(list(map(to_ballot, ballots_marks)), required_winners=2).as_dict() #print(b) c = SchulzeSTV(list(map(to_ballot_list, ballots_marks)), required_winners=6, ballot_notation=SchulzeSTV.BALLOT_NOTATION_GROUPING).as_dict() print(c) d = STV(list(map(to_ballot, ballots_marks)), required_winners=6).as_dict() print(d)
def initiate_nextphase(consensus): logger = initiate_nextphase.get_logger() logger.info('Initiating Next Phase for: {0}'.format( consensus.content_object.summary)) consensus.phase.curphase = consensus.phase.curphase.nextphase consensus.phasename = consensus.phase.curphase.phasename mygroups = MyGroup.objects.filter(topic=consensus.content_object.parent) num_members = mygroups.count() if consensus.phase.curphase.nextphase == None: #get the group settings settings, is_new = GroupSettings.objects.get_or_create( topic=consensus.content_object.parent) #iterate decisions made consensus.content_object.parent.decisions += 1 consensus.content_object.parent.save() #if this question does not pass consensus we do not accept, however ignore reporting #this gives people an opportunity to not agree with the need for the question itself consensus.consensus_percent = get_consensus(consensus) consensus.reporting_percent = float( UpDownVote.objects.filter( parent=consensus).count()) / float(num_members) cons_passed = test_if_passes(consensus.consensus_percent, consensus.reporting_percent, settings, ignore_reporting=False) winner = [] passes = False #if we accept all winners no need for ranking if consensus.winners is not None: #get nominations and ranked votes nominations = Consensus.objects.filter( parent_pk=consensus.content_object.pk) #currently supports single winner, in the future we check here for multiple winner or single winner confirmed = ConfirmRankedVote.objects.filter(parent=consensus, confirm=True) ballot_dict = defaultdict(int) user_has_ranked = [] for conf in confirmed: user_has_ranked.append(conf.user) rv = tuple([ i.nom_cons.pk for i in RankedVote.objects.filter( user=conf.user, parent=consensus).order_by( 'ranked_vote') ]) ballot_dict[rv] += 1 #for those that didnt rank vote, we can sample from their updownvotes for user in [ i.user for i in UpDownVote.objects.filter(parent=consensus) ]: if user not in user_has_ranked: user_ranks = [] print nominations for nom in nominations: try: vote = UpDownVote.objects.get(parent=nom, user=user) user_ranks.append(vote) except: print 'novote: ' + str(nom) user_ranks = sorted(user_ranks, key=lambda x: x.vote) user_ranks.reverse() rv = tuple([i.parent.pk for i in user_ranks]) ballot_dict[rv] += 1 #load up the vote dict for python-vote-core blist = [] for k, v in ballot_dict.items(): ballot = [[i] for i in k] if ballot != []: blist.append({'count': v, 'ballot': ballot}) print 'calc schulze' #right now there is only single winner schulze, add mechanism in for multi later on noms_passed = False if blist != []: #scz = SchulzeMethod(blist, ballot_notation="grouping").as_dict() scz = SchulzeSTV(blist, required_winners=consensus.winners, ballot_notation="grouping").as_dict() print scz schulze_winners = scz['winners'] #make sure it passes consensus also for nom in nominations: nom.consensus_percent = get_consensus(nom) nom.reporting_percent = float( UpDownVote.objects.filter( parent=nom).count()) / float(num_members) nom.save() noms_passed = test_if_passes(nom.consensus_percent, nom.reporting_percent, settings, ignore_reporting=True) if noms_passed == True and nom.pk in schulze_winners: passes = True winner.append(nom.pk) print 'set winner via schulze and passing' #there was no ranked winner or the ranked winner failed to consense (weird side case), cycle through all and choose if passes == False: #if this is None, accept all winners if consensus.winners == None: num_winners = len(nominations) else: num_winners = consensus.winners consensii = [] for nom in nominations: val = (get_consensus(nom), nom) consensii.append(val) nom.consensus_percent = val[0] nom.reporting_percent = float( UpDownVote.objects.filter( parent=nom).count()) / float(num_members) nom.save() consensii = sorted(consensii, key=lambda x: x[0]) consensii.reverse() for nom_cons, nom in consensii[0:num_winners]: ##calculate reporting percentage, the best is the winner noms_passed = test_if_passes(nom_cons, nom.reporting_percent, settings, ignore_reporting=True) if noms_passed: winner.append(nom.pk) passes = True print 'noms passed ' + str(noms_passed) #if we still haven't if passes == True and cons_passed == True: consensus.phasename = 'pass' else: consensus.phasename = 'fail' #what to do if there is no winner? #decision failed, no one voted in time rd = RankedDecision(passed=passes and cons_passed, winner=winner, parent=consensus, consensus_percent=consensus.consensus_percent, reporting_percent=consensus.reporting_percent, submit_date=datetime.datetime.now(), algorithm='Schulze Method Single Winner') rd.save() consensus.phase.complete = True consensus.phase.active = False else: initiate_nextphase.apply_async(args=[consensus], eta=consensus.phase.decision_dt) consensus.phase.save() consensus.save() logger.info('Next Phase Transition {0} completed'.format( consensus.content_object.summary))
def test_part_2_of_5_example(self): # Generate data input = [ { "count": 60, "ballot": [["a"], ["b"], ["c"], ["d"], ["e"]] }, { "count": 45, "ballot": [["a"], ["c"], ["e"], ["b"], ["d"]] }, { "count": 30, "ballot": [["a"], ["d"], ["b"], ["e"], ["c"]] }, { "count": 15, "ballot": [["a"], ["e"], ["d"], ["c"], ["b"]] }, { "count": 12, "ballot": [["b"], ["a"], ["e"], ["d"], ["c"]] }, { "count": 48, "ballot": [["b"], ["c"], ["d"], ["e"], ["a"]] }, { "count": 39, "ballot": [["b"], ["d"], ["a"], ["c"], ["e"]] }, { "count": 21, "ballot": [["b"], ["e"], ["c"], ["a"], ["d"]] }, { "count": 27, "ballot": [["c"], ["a"], ["d"], ["b"], ["e"]] }, { "count": 9, "ballot": [["c"], ["b"], ["a"], ["e"], ["d"]] }, { "count": 51, "ballot": [["c"], ["d"], ["e"], ["a"], ["b"]] }, { "count": 33, "ballot": [["c"], ["e"], ["b"], ["d"], ["a"]] }, { "count": 42, "ballot": [["d"], ["a"], ["c"], ["e"], ["b"]] }, { "count": 18, "ballot": [["d"], ["b"], ["e"], ["c"], ["a"]] }, { "count": 6, "ballot": [["d"], ["c"], ["b"], ["a"], ["e"]] }, { "count": 54, "ballot": [["d"], ["e"], ["a"], ["b"], ["c"]] }, { "count": 57, "ballot": [["e"], ["a"], ["b"], ["c"], ["d"]] }, { "count": 36, "ballot": [["e"], ["b"], ["d"], ["a"], ["c"]] }, { "count": 24, "ballot": [["e"], ["c"], ["a"], ["d"], ["b"]] }, { "count": 3, "ballot": [["e"], ["d"], ["c"], ["b"], ["a"]] }, ] output = SchulzeSTV( input, required_winners=3, ballot_notation=SchulzeSTV.BALLOT_NOTATION_GROUPING).as_dict() # Run tests self.assertEqual(output['winners'], set(['a', 'd', 'e']))