Package: votelib
Votelib: Evaluation of voting systems in PythonVotelib is a package to evaluate results of elections under various systems.
It aims to provide reliable implementations of many voting systems so that
they may be evaluated as they are used in real-world conditions and compared.
The primary focus is on political decision making, but the library is not
limited to evaluating political decisions only.Votelib does not aim to be an end-to-end tool for managing elections; it
does not (and will not) provide user interfaces or concern itself with other
parts of the election process than determining the result from the votes cast.
It also does not directly address theoretical analysis of different voting
systems (in terms of automatic proofs of satisfied criteria) - it is rather
meant for practical use and experiments.Votelib aims to enrich the public debate around voting systems by providing an
impartial and solid basis for their comparison; the project does not (and
will not) lend itself to the agenda of promoting any particular system (but the
license allows you touseit to do so, of course).Votelib is implemented in pure Python without any third-party dependencies
and is licensed permissively under an MIT license.InstallationVotelib supports Python 3.7+. You can get Votelib from PyPI by usingpip install votelibFor restricted settings, you can also download the contents of itsrepositoryand copy thevotelibfolder into a desired location. No actual installation
is necessary because Votelib does not have any dependencies beyond Python.ContentsAt the heart of Votelib lieevaluators, objects that determine election
results from the votes cast, defined in the submodules of theevaluatesubpackage. The supported evaluators cover most of the systems
used around the world, such as the following:Selection evaluators: select one or more elected candidates from a set.
Each candidate can be elected at most once. This encompasses both
single-winner elections (with number of seats set to 1) and multi-winner
elections.Plurality (first-past-the-post)Transferable vote methods: PR-STV, instant runoff voting and other
variants with different transfer methodsCondorcet methods: Schulze, Copeland, Minimax, Kemeny-Young,
Ranked pairs, Smith and Schwartz setsMajority JudgmentBorda count and its variantsScore voting (ordinary and STAR)Approval methods (AV, PAV, SPAV, SAV)Preference addition (Bucklin, Oklahoma)Sortition (random selection)Open list (preferential votes) evaluationDistribution evaluators: allocate seats to candidates (each candidate -
usually a political party - might get more than one seat). These systems
are often calledproportional, but their result might be very far from
that.Largest remainder (all quota variants - Hare, Droop, Hagenbach-Bischoff,
Imperiali and their variants)Highest averages (all divisor variants - D'Hondt, Sainte-Laguë/Webster,
Imperiali, Huntington-Hill, Macau)Biproportional apportionment, allowing to satisfy proportionality in
both party and district seatsThe following classes of votes are supported:Simple (single candidate) votingApproval votingRanked votingScore voting (also called range or cardinal voting)
These vote classes can be converted to each other by objects in theconvertmodule, where you can also find utilities to facilitate district-wise
elections.Thecandidateandvoteallow for validity checking of candidate nominations
and cast ballots respectively.The whole library is designed for numerical stability and tries to avoid
inexact arithmetics; if you detect any such behavior, please report it.UsageVotelib is meant as a library to be imported from other Python code.
The objects in the various submodules of Votelib can be easily combined and
chained to model the election system of choice. Examples can be found in the
documentation. A simple example is evaluating theIrish presidential election
of 1990, which
uses a single transferable vote method:votes = {
    ('Mary Robinson',): 612265,
    ('Brian Lenihan',): 694484,
    ('Austin Currie', 'Brian Lenihan'): 36789,
    ('Austin Currie', 'Mary Robinson'): 205565,
    ('Austin Currie',): 25548,
}
evaluator = votelib.evaluate.sequential.TransferableVoteSelector(
    quota_function='droop',
    transferer='Hare'
)
assert evaluator.evaluate(votes) == ['Mary Robinson']The library covers many more systems like this! Find more in theReadTheDocs documentation.ContributorsFeedback, additions, suggestions, issues and pull requests are welcome and much
appreciated onGitHub. See the issues
list there for some suggestions.How to add features:Fork it (https://github.com/simberaj/pysynth/fork)Create your feature branch (git checkout -b feature/feature-name)Commit your changes (git commit -am "feature-name added")Push to the branch (git push origin feature/feature-name)Create a new pull requestDevelopment requirespytestfor testing andsphinxto generate
documentation. Tests can be run using simplepytest testsIntended development directions(Seeissuesfor more.)More extensive example and test coverage, documentation with literature
referencesSupport more systems (such as more STV variants, Quota Borda, or more
Condorcet methods)License and author infoVotelib is developed by Jan Šimberasimbera.jan@gmail.com.Votelib is available under the MIT license. SeeLICENSE.txtfor more details.