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"
        )
예제 #2
0
    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")
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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
예제 #6
0
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
예제 #7
0
 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
         ]
     )
예제 #8
0
    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")
예제 #11
0
    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")
예제 #12
0
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")
예제 #14
0
    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")
예제 #16
0
    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")
예제 #17
0
    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")
예제 #18
0
    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
예제 #19
0
    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.")
예제 #20
0
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
예제 #21
0
def addvote(num):
    ballots.append(
        Ballot(ranked_candidates=getCandidates(sheet.row_values(num))))
예제 #22
0
    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")
예제 #23
0
    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)}'
                )
예제 #24
0
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)')>]
예제 #25
0
        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)
예제 #26
0
    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")
예제 #27
0
    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")
예제 #28
0
    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)
예제 #29
0
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)