def test_equal_number_of_votes(self): trump = Candidate("Donald Trump") hillary = Candidate("Hillary Clinton") mary = Candidate("Uniting Mary") candidates = [trump, hillary, mary] ballots = [ Ballot(ranked_candidates=[trump, mary, hillary]), Ballot(ranked_candidates=[trump, mary, hillary]), Ballot(ranked_candidates=[mary, trump, hillary]), Ballot(ranked_candidates=[hillary, trump, mary]), Ballot(ranked_candidates=[hillary, mary, trump]) ] # You can use your own Candidate and Ballot objects as long as they implement the same properties and methods election_result = pyrankvote.instant_runoff_voting(candidates, ballots) ranking_first_round = election_result.rounds[0].candidate_results blank_votes = election_result.rounds[0].number_of_blank_votes self.assertEqual(3, len(ranking_first_round), "Function should return a list with one item") self.assertListEqual([trump, hillary, mary], [ candidate_result.candidate for candidate_result in ranking_first_round ], "Winners should be Per") self.assertEqual( 0.0, blank_votes, "Should be zero blank votes as all ballots have ranked all candidates" )
def test_simple_pbv(self): stay = Candidate("Stay") soft = Candidate("Soft Brexit") hard = Candidate("Hard Brexit") candidates = [stay, soft, hard] ballots = [ Ballot(ranked_candidates=[soft, stay]), Ballot(ranked_candidates=[stay, soft]), Ballot(ranked_candidates=[stay, soft]), Ballot(ranked_candidates=[hard, soft]), Ballot(ranked_candidates=[hard, stay, soft]), ] election_result = pyrankvote.preferential_block_voting( candidates, ballots, number_of_seats=1) winners = election_result.get_winners() self.assertEqual(1, len(winners), "Function should return a list with one item") winner = winners[0] self.assertEqual(stay, winner, "Winner should be Soft")
def test_transfere_votes(self): candidates, _ = self.get_candidates_and_ballots() stay, soft, hard = candidates ballots = [ Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[stay, hard, soft]), Ballot(ranked_candidates=[soft, stay, hard]), ] manager = self.get_election_manager(candidates, ballots) stay_vc, soft_vc, hard_vc = [ manager._candidate_vote_counts[stay], manager._candidate_vote_counts[soft], manager._candidate_vote_counts[hard] ] self.assertAlmostEqual(stay_vc.number_of_votes, 3.0) self.assertAlmostEqual(soft_vc.number_of_votes, 1.0) self.assertAlmostEqual(hard_vc.number_of_votes, 0.0) with self.assertRaises(RuntimeError): manager.transfer_votes(stay, 0.5) manager.elect_candidate(stay) manager.transfer_votes(stay, 0.5) self.assertAlmostEqual(stay_vc.number_of_votes, 3.0 - 0.5) self.assertAlmostEqual(soft_vc.number_of_votes, 1.0 + 2 * 0.5 / 3) self.assertAlmostEqual(hard_vc.number_of_votes, 0.0 + 1 * 0.5 / 3)
def test_case2(self): per = Candidate("Per") paal = Candidate("Pål") maria = Candidate("Maria") ingrid = Candidate("Ingrid") candidates = [per, paal, maria, ingrid] # Quote = 3.33 with 10 votes and 2 seat ballots = [ Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[maria, ingrid]), Ballot(ranked_candidates=[ingrid, maria]), Ballot(ranked_candidates=[ingrid, maria]), ] # 1. round: Per: 7, Ingrid: 2, Maria: 1, Pål: 0 # --> Per is elected and 3.67 votes are transferred to Pål # Final round: Per: 3.33, Pål: 3.67, Ingrid: 2, Maria: 1 # --> Paal is elected. Since all seats filled, Ingrid and Maria are rejected. election_result = pyrankvote.single_transferable_vote( candidates, ballots, number_of_seats=2) winners = election_result.get_winners() self.assertEqual(2, len(winners), "Function should return a list with two items") self.assertListEqual([per, paal], winners, "Winners should be Per and Pål") round = 0 votes_round = [ candidate_vc.number_of_votes for candidate_vc in election_result.rounds[round].candidate_results ] assert_list_almost_equal(self, votes_round, [7, 2, 1, 0], 0.02) round = 1 votes_round = [ candidate_vc.number_of_votes for candidate_vc in election_result.rounds[round].candidate_results ] assert_list_almost_equal(self, votes_round, [3.33, 3.67, 2, 1], 0.02)
def get_candidates_and_ballots(self): stay = Candidate("Stay") soft = Candidate("Soft Brexit") hard = Candidate("Hard Brexit") candidates = [stay, soft, hard] ballots = [ Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[hard, soft, stay]), Ballot(ranked_candidates=[soft, stay, hard]), ] return candidates, ballots
def ballotify(ballotList, candidates): ballots = list() for l in ballotList: sinBal = list(map(lambda x: next(filter(lambda c: str(c) == x, candidates)), l)) ballots.append(Ballot(sinBal)) print(sinBal) return ballots
def get_ballot(self, vetoes=None): return Ballot( [ vote.candidate for vote in self.movierankedvote_set.order_by("rank").all() if vote.candidate_id not in vetoes ] )
def test_reject_candidate(self): candidates, _ = self.get_candidates_and_ballots() stay, soft, hard = candidates ballots = [ Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[hard, soft, stay]), Ballot(ranked_candidates=[soft, stay, hard]), ] manager = self.get_election_manager(candidates, ballots) stay_vc, soft_vc, hard_vc = [ manager._candidate_vote_counts[stay], manager._candidate_vote_counts[soft], manager._candidate_vote_counts[hard] ] self.assertListEqual([], manager._elected_candidates) self.assertListEqual([], manager._rejected_candidates) self.assertEqual(stay_vc.status, helpers.CandidateStatus.Hopeful) self.assertEqual(soft_vc.status, helpers.CandidateStatus.Hopeful) self.assertEqual(hard_vc.status, helpers.CandidateStatus.Hopeful) manager.reject_candidate(stay) self.assertListEqual([stay_vc], manager._rejected_candidates) self.assertNotIn(stay_vc, manager._candidates_in_race) self.assertEqual(stay_vc.status, helpers.CandidateStatus.Rejected) self.assertEqual(soft_vc.status, helpers.CandidateStatus.Hopeful) self.assertEqual(hard_vc.status, helpers.CandidateStatus.Hopeful) manager.reject_candidate(soft) self.assertListEqual( [stay_vc, soft_vc], manager._rejected_candidates, "Stay should be before soft first since it is was rejected first.") self.assertListEqual([hard_vc], manager._candidates_in_race) self.assertNotIn(stay_vc, manager._candidates_in_race) self.assertEqual(stay_vc.status, helpers.CandidateStatus.Rejected) self.assertEqual(soft_vc.status, helpers.CandidateStatus.Rejected) self.assertEqual(hard_vc.status, helpers.CandidateStatus.Hopeful)
def initialize_ballot_objs(df): """ :goal: initialize Ballot() objects from PyRankVote library :param df: :return: """ ballot_objects = [] for index, value in enumerate(df['candidate_list']): ballot = Ballot(ranked_candidates=value) ballot_objects.append(ballot) return ballot_objects
def test_simple_case(self): per = Candidate("Per") paal = Candidate("Pål") askeladden = Candidate("Askeladden") candidates = [per, paal, askeladden] ballots = [ Ballot(ranked_candidates=[askeladden, per]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[paal, per]), Ballot(ranked_candidates=[paal, per, askeladden]) ] election_result = pyrankvote.instant_runoff_voting(candidates, ballots) winners = election_result.get_winners() stay = Candidate("Stay") soft = Candidate("Soft Brexit") hard = Candidate("Hard Brexit") candidates = [stay, soft, hard] ballots = [ Ballot(ranked_candidates=[soft, stay]), Ballot(ranked_candidates=[stay, soft]), Ballot(ranked_candidates=[stay, soft]), Ballot(ranked_candidates=[hard, soft]), Ballot(ranked_candidates=[hard, stay, soft]), ] election_result = pyrankvote.instant_runoff_voting(candidates, ballots) winners = election_result.get_winners() self.assertEqual(1, len(winners), "Function should return a list with one item") winner = winners[0] self.assertEqual(stay, winner, "Winner should be Soft")
def test_simple_pbv_with_second_selection_if_equal(self): stay = Candidate("Stay") soft = Candidate("Soft Brexit") hard = Candidate("Hard Brexit") candidates = [stay, soft, hard] ballots = [ Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[hard, soft, stay]), Ballot(ranked_candidates=[soft, stay, hard]), ] election_result = pyrankvote.preferential_block_voting( candidates, ballots, number_of_seats=2) winners = election_result.get_winners() self.assertEqual(2, len(winners), "Function should return a list with two items") self.assertIn(soft, winners, "Soft should be one of the winners") self.assertIn(stay, winners, "Stay should be one of the winners")
def parse_ballots_csv_file(file_name): file_path = os.path.join(TEST_DATA_PATH, file_name) with open(file_path) as f: csv_file_without_header = list(csv.reader(f))[1:] parsed_csv_file = [ (ballot_id, rank, candidate_name) for ballot_id, rank, candidate_name in csv_file_without_header ] #sorted_csv_file = sorted(parsed_csv_file, key=itemgetter(0,1)) sorted_csv_file = parsed_csv_file candidates = {} ballots = [] last_ballot_id = 0 ranked_candidates = [] for ballot_id, rank, candidate_name in sorted_csv_file: if ballot_id != last_ballot_id and last_ballot_id != 0: ballot = Ballot(ranked_candidates) ballots.append(ballot) ranked_candidates = [] last_ballot_id = ballot_id if candidate_name == "$UNDERVOTE": continue if candidate_name == "$OVERVOTE": continue if candidate_name in candidates: candidate = candidates[candidate_name] else: candidate = Candidate(name=candidate_name) candidates[candidate_name] = candidate ranked_candidates.append(candidate) ballot = Ballot(ranked_candidates) ballots.append(ballot) return list(candidates.values()), ballots
def test_simple_case2(self): per = Candidate("Per") paal = Candidate("Pål") askeladden = Candidate("Askeladden") candidates = [per, paal, askeladden] ballots = [ Ballot(ranked_candidates=[askeladden, per]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[paal, per]), Ballot(ranked_candidates=[paal, per, askeladden]), ] election_result = pyrankvote.instant_runoff_voting(candidates, ballots) winners = election_result.get_winners() self.assertEqual(1, len(winners), "Function should return a list with one item") self.assertListEqual([per], winners, "Winners should be Per")
def test_simple_pbv2(self): per = Candidate("Per") paal = Candidate("Pål") askeladden = Candidate("Askeladden") candidates = [per, paal, askeladden] ballots = [ Ballot(ranked_candidates=[askeladden, per]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[paal, per]), Ballot(ranked_candidates=[paal, per, askeladden]), ] election_result = pyrankvote.preferential_block_voting( candidates, ballots, number_of_seats=1) winners = election_result.get_winners() self.assertEqual(1, len(winners), "Function should return a list with one item") self.assertListEqual([per], winners, "Winners should be Per")
def test_case3(self): trump = Candidate("Donald Trump") hillary = Candidate("Hillary Clinton") mary = Candidate("Uniting Mary") candidates = [trump, hillary, mary] ballots = [ Ballot(ranked_candidates=[trump, mary, hillary]), Ballot(ranked_candidates=[trump, mary, hillary]), Ballot(ranked_candidates=[hillary, mary, trump]), Ballot(ranked_candidates=[hillary, mary, trump]), Ballot(ranked_candidates=[hillary, mary]) ] # You can use your own Candidate and Ballot objects as long as they implement the same properties and methods election_result = pyrankvote.instant_runoff_voting(candidates, ballots) winners = election_result.get_winners() self.assertEqual(1, len(winners), "Function should return a list with one item") self.assertListEqual([hillary], winners, "Winners should be Per")
def test_simple_pbv(self): per = Candidate("Per") paal = Candidate("Pål") askeladden = Candidate("Askeladden") candidates = [per, paal, askeladden] ballots = [ Ballot(ranked_candidates=[askeladden, per]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[paal, per]), Ballot(ranked_candidates=[paal, per, askeladden]), ] election_result = pyrankvote.preferential_block_voting( candidates, ballots, number_of_seats=2) winners = election_result.get_winners() self.assertEqual(2, len(winners), "Function should return a list with two items") self.assertIn(per, winners, "Per should be one of the winners") self.assertIn(paal, winners, "Pål should be one of the winners")
def test_case1_simple(self): per = Candidate("Per") paal = Candidate("Pål") askeladden = Candidate("Askeladden") candidates = [per, paal, askeladden] ballots = [ Ballot(ranked_candidates=[askeladden, per]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[paal, per]), Ballot(ranked_candidates=[paal, per, askeladden]), ] election_result = pyrankvote.single_transferable_vote( candidates, ballots, number_of_seats=2) winners = election_result.get_winners() self.assertEqual(2, len(winners), "Function should return a list with two items") self.assertListEqual([per, paal], winners, "Winners should be Per and Pål")
def get_election_res(pred_df, id_orig, n_ans): df = pred_df[pred_df.id.str.startswith(id_orig)] candidates = [Candidate(el) for el in df.answers.unique()] ballots = [ Ballot(ranked_candidates=[ Candidate(vote) for vote in df[df.id == id_].answers ]) for id_ in df.id.unique() ] if len(candidates) <= n_ans: return list(df.answers) if args['voting'] == 'pbv': election_result = pyrankvote.preferential_block_voting( candidates, ballots, min(n_ans, len(candidates))) else: election_result = pyrankvote.single_transferable_vote( candidates, ballots, min(n_ans, len(candidates))) return election_result
def test_candidates_have_most_second_votes(self): stay = Candidate("Stay") soft = Candidate("Soft Brexit") hard = Candidate("Hard Brexit") extra = Candidate("Extra") candidates = [stay, soft, hard, extra] ballots = [ Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[stay, soft, hard]), Ballot(ranked_candidates=[stay, soft]), Ballot(ranked_candidates=[extra, hard, stay]), Ballot(ranked_candidates=[soft, stay, hard]), Ballot(ranked_candidates=[soft, stay, hard]), Ballot(ranked_candidates=[soft, stay, hard]), ] manager = self.get_election_manager(candidates, ballots) stay_vc, soft_vc, hard_vc, extra_vc = [ manager._candidate_vote_counts[stay], manager._candidate_vote_counts[soft], manager._candidate_vote_counts[hard], manager._candidate_vote_counts[extra] ] is_stay_ranked_first = manager._candidate1_has_most_second_choices( stay_vc, extra_vc, 1) self.assertEqual(is_stay_ranked_first, True, "Stay should rank before extra") is_hard_ranked_first = manager._candidate1_has_most_second_choices( hard_vc, extra_vc, 1) self.assertEqual( is_hard_ranked_first, True, "Hard, should rank before extra, because hard has more 2nd alternative votes" ) is_stay_ranked_first = manager._candidate1_has_most_second_choices( stay_vc, soft_vc, 1) self.assertEqual( is_stay_ranked_first, True, "Stay should rank before soft, even though they have equal number of votes, and equal number of " "second votes, because stay has more 3rd alternative votes.")
def make_ballots(df, candidate_names, voters_list, top_N): frame = inspect.currentframe().f_code.co_name # make an empty list of ballots ballots = [] # # make a list of voters (should match the input spreadsheet) # voters_list = ['voter1', 'voter2', 'voter3'] utils.print_message(frame, "Making ballots.") for voter in voters_list: # get the list of rankings for the current voter ranks = df[voter].to_list() # candidates not rated end up with an empty entry in the list = '' # we can't use that for comparison, so let's set unrated candidates to a # low preference - say 99, then use map to convert everything # to a list of ints ranks = list(map(int, [99 if r == '' else r for r in ranks])) # create an empty ballot and fill it with candidate names for this voter # b = [] b = [name for _, name in sorted(zip(ranks, candidate_names))] # we allow only the top N candidates b = b[:top_N] if VERBOSE: utils.print_message( frame, "{1}'s top-{2} ballot from most to least preferred = {0}". format(b, voter, top_N)) # add this ballot to the list of ballots ballots.append(Ballot(ranked_candidates=[Candidate(x) for x in b])) # show the ballots if VERBOSE: print("list of all ballots: {0}".format(ballots)) return ballots
def addvote(num): ballots.append( Ballot(ranked_candidates=getCandidates(sheet.row_values(num))))
def test_case3(self): per = Candidate("Per") paal = Candidate("Pål") maria = Candidate("Maria") ingrid = Candidate("Ingrid") candidates = [per, paal, maria, ingrid] # Quote = 4.67 with 11 votes and 2 seat ballots = [ Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[per, paal]), Ballot(ranked_candidates=[maria, ingrid]), Ballot(ranked_candidates=[ingrid, maria]), Ballot(ranked_candidates=[ingrid, maria]), ] # 1. round: Per: 7, Ingrid: 2, Maria: 1, Pål: 0 # --> Per is elected and 3.33 votes are transfered to Pål # 2. round: Pål: 3.33, Ingrid: 2, Maria: 1 # --> Maria is excluded and her one vote is transfered to Ingrid # 3. round: Pål: 3.33, Ingrid: 3 # --> Pål is elected election_result = pyrankvote.single_transferable_vote( candidates, ballots, number_of_seats=2) winners = election_result.get_winners() self.assertEqual(2, len(winners), "Function should return a list with two items") self.assertListEqual([per, paal], winners, "Winners should be Per and Pål")
async def submit(self, context, code): # Only work for users who got sent messages author = context.author.id if author not in helpers.voting_messages: return if code.upper() != helpers.VOTING_CODE: await context.send( 'The code you have supplied is incorrect, ' 'you must use the one given out in the election call, your vote was not cast' ) return valid = await self.validate(context) if not valid: await context.send( 'Your vote was not cast, please correct your ballot and resubmit' ) return async with helpers.voted_lock: if author in helpers.voted: await context.send( 'You have already cast your vote and it cannot be changed') return async with helpers.votes_lock.reader_lock: async with helpers.current_live_post_lock.reader_lock: if helpers.current_live_post[0] == 'POST': ballot_list = [''] * len( helpers.standing[helpers.current_live_post[1]]) # Create ballot for candidate, message_id in helpers.voting_messages[ author]: message = await context.author.fetch_message( message_id) if message.reactions: reaction = message.reactions[0].emoji ballot_list[helpers.EMOJI_LOOKUP[ reaction]] = helpers.standing[ helpers. current_live_post[1]][candidate][0] helpers.votes.append( Ballot(ranked_candidates=[ ballot for ballot in ballot_list if str(ballot) != '' ])) else: # Create ballot for option, message_id in helpers.voting_messages[ author]: message = await context.author.fetch_message( message_id) if message.reactions: helpers.votes.append( Ballot(ranked_candidates=[option])) break else: helpers.votes.append(Ballot(ranked_candidates=[])) helpers.voted.append(author) await context.send('Your vote was successfully cast') helpers.log( f'Votes cast: {len(helpers.votes)} - Votes not yet cast: {len(helpers.registered_members)-len(helpers.votes)}' )
import pyrankvote from pyrankvote import Candidate, Ballot # ONE SEAT ELECTION: INSTANT RUNOFF VOTING bush = Candidate("George W. Bush (Republican)") gore = Candidate("Al Gore (Democratic)") nader = Candidate("Ralph Nader (Green)") candidates = [bush, gore, nader] # Bush have most first choice votes, but because Ralph Nader-voters want # Al Gore if Nader is not elected, the elected candidate is Al Gore ballots = [ Ballot(ranked_candidates=[bush, nader, gore]), Ballot(ranked_candidates=[bush, nader, gore]), Ballot(ranked_candidates=[bush, nader]), Ballot(ranked_candidates=[bush, nader]), Ballot(ranked_candidates=[nader, gore, bush]), Ballot(ranked_candidates=[nader, gore]), Ballot(ranked_candidates=[gore, nader, bush]), Ballot(ranked_candidates=[gore, nader]), Ballot(ranked_candidates=[gore, nader]) ] # You can use your own Candidate and Ballot objects as long as they implement the same properties and methods election_result = pyrankvote.instant_runoff_voting(candidates, ballots) winners = election_result.get_winners() # Returns: [<Candidate('Al Gore (Democratic)')>]
reader = csv.reader(f) first_row = True for row in reader: if first_row: first_row = False continue # Skip timestamp and user. ballots.append(row[2:]) # Create Candidate objects for every proposal. proposals = {} for ballot in ballots: for proposal in ballot: if proposal not in proposals: proposals[proposal] = Candidate(proposal) # Create Ballot objects for every ballot. processed_ballots = [] for ballot in ballots: ranked = [] for proposal in ballot: ranked.append(proposals[proposal]) processed_ballots.append(Ballot(ranked_candidates=ranked)) # Print election results. election_result = pyrankvote.single_transferable_vote( proposals.values(), processed_ballots, number_of_seats=NUMBER_OF_WINNERS) print(election_result)
def test_example(self): popular_moderate = Candidate("William, popular moderate") moderate2 = Candidate("John, moderate") moderate3 = Candidate("Charles, moderate") far_left = Candidate("Thomas, far-left") candidates = [popular_moderate, moderate2, moderate3, far_left] ballots = [ Ballot(ranked_candidates=[ popular_moderate, moderate2, moderate3, far_left ]), Ballot(ranked_candidates=[ popular_moderate, moderate2, moderate3, far_left ]), Ballot(ranked_candidates=[ popular_moderate, moderate3, moderate2, far_left ]), Ballot(ranked_candidates=[ popular_moderate, moderate3, moderate2, far_left ]), Ballot(ranked_candidates=[ moderate2, popular_moderate, moderate3, far_left ]), Ballot(ranked_candidates=[ moderate2, popular_moderate, moderate3, far_left ]), Ballot(ranked_candidates=[ far_left, popular_moderate, moderate2, moderate3 ]), Ballot(ranked_candidates=[ far_left, popular_moderate, moderate2, moderate3 ]), Ballot(ranked_candidates=[ far_left, moderate2, popular_moderate, moderate3 ]), Ballot(ranked_candidates=[ far_left, moderate2, popular_moderate, moderate3 ]), ] election_result = pyrankvote.preferential_block_voting( candidates, ballots, number_of_seats=2) round_nr = 0 candidates_results_in_round = election_result.rounds[ round_nr].candidate_results ranking_in_round = [ candidate_result.candidate for candidate_result in candidates_results_in_round ] correct_ranking_in_round = [ popular_moderate, moderate2, far_left, moderate3 ] self.assertEqual(4, len(ranking_in_round), "All four candidates should be in the result list") self.assertListEqual(correct_ranking_in_round, ranking_in_round) votes_in_round = [ candidate_result.number_of_votes for candidate_result in candidates_results_in_round ] correct_votes_in_round = [8, 6, 4, 2] assert_list_almost_equal(self, correct_votes_in_round, votes_in_round) status_in_round = [ candidate_result.status for candidate_result in candidates_results_in_round ] correct_status_in_round = [ CandidateStatus.Elected, CandidateStatus.Elected, CandidateStatus.Rejected, CandidateStatus.Rejected ] self.assertListEqual(correct_status_in_round, status_in_round) winners = election_result.get_winners() self.assertEqual(2, len(winners), "Function should return a list with two items") self.assertIn(popular_moderate, winners, "William should be a winner") self.assertIn(moderate2, winners, "John should be a winner")
def test_example(self): popular_moderate = Candidate("William, popular moderate") moderate2 = Candidate("John, moderate") moderate3 = Candidate("Charles, moderate") far_left = Candidate("Thomas, far-left") candidates = [popular_moderate, moderate2, moderate3, far_left] ballots = [ Ballot(ranked_candidates=[ popular_moderate, moderate2, moderate3, far_left ]), Ballot(ranked_candidates=[ popular_moderate, moderate2, moderate3, far_left ]), Ballot(ranked_candidates=[ popular_moderate, moderate3, moderate2, far_left ]), Ballot(ranked_candidates=[ popular_moderate, moderate3, moderate2, far_left ]), Ballot(ranked_candidates=[ moderate2, popular_moderate, moderate3, far_left ]), Ballot(ranked_candidates=[ moderate2, popular_moderate, moderate3, far_left ]), Ballot(ranked_candidates=[ far_left, popular_moderate, moderate2, moderate3 ]), Ballot(ranked_candidates=[ far_left, popular_moderate, moderate2, moderate3 ]), Ballot(ranked_candidates=[ far_left, moderate2, popular_moderate, moderate3 ]), Ballot(ranked_candidates=[ far_left, moderate2, popular_moderate, moderate3 ]), ] election_result = pyrankvote.single_transferable_vote( candidates, ballots, number_of_seats=2) round_nr = 0 candidates_results_in_round = election_result.rounds[ round_nr].candidate_results ranking_in_round = [ candidate_result.candidate for candidate_result in candidates_results_in_round ] votes_in_round = [ candidate_result.number_of_votes for candidate_result in candidates_results_in_round ] self.assertEqual(4, len(ranking_in_round), "All four candidates should be list.") self.assertListEqual( [popular_moderate, far_left, moderate2, moderate3], ranking_in_round) assert_list_almost_equal(self, [4, 4, 2, 0], votes_in_round) self.assertEqual(1, len(election_result.rounds), "Should be only one round") winners = election_result.get_winners() self.assertEqual(2, len(winners), "Should be two winners") self.assertIn(popular_moderate, winners, "William should be a winner") self.assertIn(far_left, winners, "John should be a winner")
NaNs = ( ranked_vote != ranked_vote ) # True where there are NaNs (candidates that didn't get a ranking) ranked_vote[NaNs] = len( candidates ) + 1 # If the voter didn't rank this candidate, they are disregarded (placed last, so the next line will cut them out) # Create a sorted list of Candidate objects based on this voter's rankings candidate_indices = np.argsort(ranked_vote)[:( len(candidates) - sum(NaNs) )] # Returns indices of candidates in sorted order, removing candidates that this voter didn't rank ranked_candidates = candidates[ candidate_indices] # Candidate objects corresponding to the sorted indices # Create ballot! ballot = Ballot(ranked_candidates=ranked_candidates) ballots.append(ballot) # print ("Vote is {}".format(ballot)) ## Run single transferable vote election ## # Note that in case of first-choice tie, the library uses second-choice for tiebreaks. election = pyrankvote.single_transferable_vote(candidates, ballots, number_of_seats=args.n_seats) print(election) with open(args.output, 'w') as f: f.write(str(election)) print('Saved to file ' + args.output)
def generate_ballot(candidates=List[Candidate], weights=List[float]) -> Ballot: ballot = np.random.choice(candidates, p=weights, replace=False, size=VOTES) return Ballot(ranked_candidates=ballot)