A python module for social choice
Creators: Annika Hennes & Ali Seyhun Saral
Warning: This package is at an early stage. Please use with caution.
The package can be installed via the package manager pip:
pip install choicepy
Available voting rules
- dictator rule
- plurality rule
- majority rule
- approval rule
- Condorcet rule
- Borda rule
First, generate a profile:
import choicepy my_profile = choicepy.Profile()
Voters are represented by their preferences over the candidates, i.e. an electorate is a list of lists. Every inner list represents a voter and the elements in this list are the candidates sorted according to the preference of the voter. We support the case where voters have strict and complete preferences over candidates.
Custom Voter preferences
You can set the voters using the method set_voters.
my_profile.set_voters([["a", "b", "c"], ["b", "c", "a"]]) print(my_profile.voters) print(my_profile.candidates)
[['a', 'b', 'c'], ['b', 'c', 'a']] ['a', 'b', 'c']
Generate Voters from uniform distribution
The voters can also be automatically generated according to a uniform distribution over all possible profiles on a given set of candidates. You need to specify the list of candidates and the number of voters first and then call the following method:
gen_uniform_voters(self, candidate_list, num_voters)
Generate Voters according to Mallows Phi-Model 
Mallows Phi-Model shows a situation in which the preference ordering of voters are based on a reference ordering. Likelihood of an ordering is determined by the distance of the orderding to the reference ordering.
gen_mallows_voters(self, candidate_list, num_voters, dispersion_parameter, transformation_parameter=0)
dispersion_paramater takes a value in the interval (0,1] and determines dispersed the preferences are..
The lower the value of
dispersion_parameter, the higher the probability that a voter has the reference ranking as
her own preference. As
dispersion_parameter approaches 0, the probability of seeing the reference ranking
approaches 1, for
dispersion_parameter = 1, the Mallows phi-model is equivalent to a uniform distribution over
After initializing the voters, the candidates do not need to be specified. They will be automatically read from the voters preferences.
The winning alternative is the top preference of one single designated voter.
dictator_index it can be specified which voter will be the designated one.
If this parameter is not set, a voter will be chosen uniformly at random.
The winning alternative is the one that the greatest fraction of voters ranked on top of their preferences. It does not need to be unique.
The winning alternative is the one that the majority of voters (i.e. at least 50%) ranked on top of their preferences. It does not need to be unique.
Every voter can either approve or disapprove any candidate. The winning alternative is then the candidate that is approved by most of the voters. Just as for the other rules, the voters preferences will be represented by ordered lists of alternatives. All candidates up to a certain index will be approved, the rest will be disapproved.
acceptable_rank you can specify the index up to which candidates are approved.
If this parameter is not set, an index will be generated uniformly at random
for every voter independently.
The winning alternative is the candidate that wins against every other candidate in pairwise comparisons.
Every preference of a voter is assigned a score. The winning alternative is the candidate with the highest sum of scores.
points_list specifies the scoring. It takes a list of length n, where n is the
number of alternatives. The elements in this list represent the numerical weights the preferences will get,
starting with the top-ranked alternative.
It can be either set manually by specifying a list of numerical values of length n or using the output of
the following method:
point_distribution can be set to one of the following strings
indicating the scoring method:
"borda_0"generates the scoring [n-1, n-2, ..., 1, 0] (this scoring is used by default).
"borda_1"generates the scoring [n, n-1, ..., 2, 1].
"dowdallgenerates the scoring [1, 1/2, 1/3, ..., 1/n].
If it is not set, the default scoring [n-1,n-2,...,0] is used, where n is the number of alternatives.
combines all the previous mentioned voting rules. The parameter
rule can be set to one of the
and it will just call the respective above mentioned voting rules with their default parameters (this concerns dictator-, approval- and Borda-rule).
import choicepy # Create a new profile my_profile = choicepy.Profile() # Generate voters from unform distribution my_profile.gen_uniform_voters(4,9) # Show profile print(my_profile) # 4 candidates, 9 voters # Profile: abcd:1 | abdc:1 | acbd:1 | adbc:1 | bacd:1 | bcad:1 | bdac:1 | cbad:1 | dcba:1 | # #          # d a b a c b a a b # c b a d b c c b d # b d c b a a b c a # a c d c d d d d c # Show Borda outcome my_profile.borda() # ['b'] # Show Plurality outcome my_profile.plurality() # ['a'] # Show Condorcet outcome my_profile.condorcet() # ['b'] # Show Approval voting outcome (voters approve first two candidates in their preference ordering) my_profile.approval(2) # ['b'] # Show Approval voting outcome (voters approve the first n of the candidates while n is determined randomly between 1 and number_of_candidates - 1) my_profile.approval() # ['a','b']
 : Mallows, Colin L. "Non-null ranking models. I." Biometrika 44.1/2 (1957): 114-130.