Components API

Quotas

Quota functions used in largest-remainder proportional voting systems.

Quotas can however be used as a component in many other voting systems, such as transferable vote or open list evaluators.

A quota function takes the total number of votes and the number of seats to allocate and returns the number of votes required to reach a seat. The unrounded quota functions return fractions to retain exact values.

All supported quota functions are assembled in the QUOTAS dictionary keyed by their name. get() retrieves from this dictionary by string key; construct() also accepts callables and passes them through.

votelib.component.quota.droop(votes, seats)

Droop quota, the most widely used one.

This it is the smallest integer quota guaranteeing the number of passing candidates will not be higher than the number of seats.

Return type

int

votelib.component.quota.hagenbach_bischoff(votes, seats)

Hagenbach-Bischoff quota.

This is the unrounded variant, giving the exact fraction.

Return type

Fraction

votelib.component.quota.hagenbach_bischoff_ceil(votes, seats)

Hagenbach-Bischoff quota, rounding up.

This is the rounded variant that is identical to the Droop quota in most cases.

Return type

int

votelib.component.quota.hagenbach_bischoff_rounded(votes, seats)

Hagenbach-Bischoff quota, rounding mathematically (round-to-even).

This is the rounded variant that is used in some rare cases, e.g. old Slovak regional apportionment of parliamentary seats. Half is rounded up.

Return type

int

votelib.component.quota.hare(votes, seats)

Hare quota, the most basic one.

This is the unrounded variant, giving the exact fraction.

Return type

Fraction

votelib.component.quota.hare_rounded(votes, seats)

Hare quota, the most basic one.

This is the rounded variant, which is used more often. Half is rounded up.

Return type

int

votelib.component.quota.imperiali(votes, seats)

Imperiali quota.

Imperiali quota can produce more candidates than seats to be filled in some cases; the results then usually need to be recalculated using a different quota.

Return type

Fraction

Divisors

Divisor functions used in highest-averages proportional voting systems.

This provides arguments for the votelib.evaluate.proportional.HighestAverages evaluator. However, divisors can be used as a component in many other voting systems, such as biproportional allocation.

A divisor function takes the order number (usually equal to the number of seats allocated so far) and returns the divisor by which to divide the number of votes for the given party or candidate. The party or candidate with the largest result then gets the next seat.

Some systems use a mathematically defined divisor but artificially change the result for parties with no seats so far (order == 0) to make it harder for parties to get their seats. Use modified_first_coef() for that.

All supported divisor functions are assembled in the DIVISORS dictionary keyed by their name. get() retrieves from this dictionary by string key; construct() also accepts callables and passes them through.

votelib.component.divisor.d_hondt(order)

D’Hondt divisor, the most commonly used divisor.

Forms a simple sequence 1, 2, 3… In the United States, this is known as the Jefferson divisor that was used for congressional apportionment 1792-1842.

Known to slightly favor larger parties.

Return type

int

votelib.component.divisor.danish(order)

Danish divisor.

Forms a sequence 1, 4, 7…

Extremely favors smaller parties.

Return type

int

votelib.component.divisor.huntington_hill(order)

Huntington-Hill divisor.

The divisors are defined by sqrt(n*(n+1)). This means the divisor is invalid for the zeroth order (passing a zero gives a divisor of zero, which raises an error in the subsequent division) and can thus only be used in cases where the first seat is already guaranteed (use the prev_gains argument for that).

Used for United States congressional apportionment as of 2020.

Return type

Decimal

votelib.component.divisor.imperiali(order)

Imperiali divisor. Not to be confused with the Imperiali quota.

Forms a sequence 1, 1.5, 2…

Known to favor large parties greatly.

Return type

Fraction

votelib.component.divisor.macau(order)

Macau modified D’Hondt divisor.

This uses order counts as exponents (1, 2, 4, 8…), and therefore favors smaller parties.

Return type

int

votelib.component.divisor.modified_first_coef(divisor_fx, first_coef=Decimal('1.4'))

Modify the divisor for the zeroth order to an apriori coefficient.

This can be used to raise the threshold for parties that have not yet obtained a seat. This is the case in the Czech regional election (Koudelka coefficient 1.42), Nepal, Norway, and Sweden.

Parameters
  • divisor_fx (Callable[[int], Number]) – The ordinary divisor function to be wrapped and used for the first order and subsequent ones.

  • first_coef (Decimal) – The coefficient to be used when order == 0.

Return type

Callable[[int], Number]

votelib.component.divisor.sainte_lague(order)

Sainte-Laguë (Webster, Schepers) divisor, a commonly used divisor.

Forms a sequence 1, 3, 5…

Known to favor mid-sized parties.

Return type

int

Pairwise win scorers

Functions to score magnitudes of wins between pairs of candidates.

These are used in some Condorcet methods to determine ranking priority.

votelib.component.pairwin_scorer.margins(counts)

Margins pairwise win scorer. Takes the difference from reverse option.

Also called margin of victory or defeat strength. Assigns the number of votes ranking the pair in the given order minus the number of votes doing the reverse as the win strength (which is thus negative for pairwise losses).

Parameters

counts (Dict[Tuple[Union[str, CandidateObject], Union[str, CandidateObject]], Number]) – Condorcet votes (counts of pairwise preferences).

Return type

Dict[Tuple[Union[str, CandidateObject], Union[str, CandidateObject]], Number]

votelib.component.pairwin_scorer.pairwise_opposition(counts)

Pairwise opposition win scorer. Returns the win counts unchanged.

This gives the number of votes ranking the pair in the given order directly as the measure of pairwise win, regardless of the number of votes preferring the opposite pairwise ranking.

Parameters

counts (Dict[Tuple[Union[str, CandidateObject], Union[str, CandidateObject]], Number]) – Condorcet votes (counts of pairwise preferences).

Return type

Dict[Tuple[Union[str, CandidateObject], Union[str, CandidateObject]], Number]

votelib.component.pairwin_scorer.winning_votes(counts)

Winning votes pairwise win scorer. Counts wins fully, zero otherwise.

This is the most common pairwise win scorer. When the number of votes for the pair ranked in one direction is larger than the other direction, assigns all those votes as the pairwise win strength.

Parameters

counts (Dict[Tuple[Union[str, CandidateObject], Union[str, CandidateObject]], Number]) – Condorcet votes (counts of pairwise preferences).

Return type

Dict[Tuple[Union[str, CandidateObject], Union[str, CandidateObject]], Number]

Rank scorers

Objects to assign scores to ranks in ranked voting systems such as Borda.

A rank scorer returns a list of numerical scores to be assigned to ranks given by voters. This is the essence of Borda count system, and rank scorers capture most of the variations there are in that system.

class votelib.component.rankscore.Borda(base=1)

Borda rank scorer, corresponding to the original Borda count variant.

Assigns the base score to the candidate ranked last, and one point more for each higher rank.

This rank scorer needs to be initialized by the set_n_candidates() before calling scores().

Parameters

base (int) – The score to assign to the candidate ranked last. For the truly original Borda, this equals to 1; some variants set it to zero, and thus set the score for the first rank to the number of candidates minus one.

scores(n_ranked)

Return the scores for the first n_ranked ranks.

This gives (number of candidates + base - 1 - rank) for ranks running from 0 (best rank) to n_ranked.

Parameters

n_ranked (int) – Number of ranks to be returned. Equal to the length of the output list.

Raises

RuntimeError – If the scorer has not been initialized first by calling set_n_candidates().

Return type

List[int]

set_n_candidates(n_candidates)

Set the total number of candidates that could be ranked.

This helps to account for rankings that do not rank all candidates.

Parameters

n_candidates (int) – The total number of candidates that could be ranked on any ballot (i.e. the number of candidates participating in the election in the particular constituency).

Return type

None

class votelib.component.rankscore.Dowdall

Dowdall (Nauru) rank scorer.

Assigns the numbers of the harmonic series (1, 1/2, 1/3…) to progressively lower ranks.

scores(n_ranked)

Return the scores for the first n_ranked ranks.

This gives 1 / (rank + 1) for ranks running from 0 (best rank) to n_ranked.

Parameters

n_ranked (int) – Number of ranks to be returned. Equal to the length of the output list.

Return type

List[Fraction]

class votelib.component.rankscore.FixedTop(top)

A rank scorer with fixed score for the top rank.

Assigns scores progressively decreased by one until hitting zero.

Parameters

top (int) – The score for the top (best) ranked candidate on the ballot.

scores(n_ranked)

Return the scores for the first n_ranked ranks.

This gives max(top - rank, 0) for ranks running from 0 (best rank) to n_ranked.

Parameters

n_ranked (int) – Number of ranks to be returned. Equal to the length of the output list.

Return type

List[int]

class votelib.component.rankscore.Geometric(base=2)

A geometric progression rank scorer.

Assigns the numbers of a chosen inverse geometric progression (e.g. 1, 1/2, 1/4… for 2) to progressively lower ranks.

Parameters

base (int) – Base of the geometric progression.

scores(n_ranked)

Return the scores for the first n_ranked ranks.

This gives 1 / (2 ** rank) for ranks running from 0 (best rank) to n_ranked.

Parameters

n_ranked (int) – Number of ranks to be returned. Equal to the length of the output list.

Return type

List[Fraction]

class votelib.component.rankscore.ModifiedBorda

Modified Borda count rank scorer.

In this system, the score for the highest rank is not constant (as is the case for the vanilla Borda count), but is equal to the number of ranked candidates; therefore, it encourages voters to rank many candidates.

scores(n_ranked)

Return the scores for the first n_ranked ranks.

This gives n_ranked - rank for ranks running from 0 (best rank) to n_ranked.

Parameters

n_ranked (int) – Number of ranks to be returned. Equal to the length of the output list.

Return type

List[int]

class votelib.component.rankscore.RankScorer

An abstract base class for rank scorers.

Rank scorers must provide a scores() method that returns a list of scores based on the number of ranks given. They may also provide a set_n_candidates() method that sets the total number of candidates participating in the election, which might be relevant for computing the rank scores. If this method is defined, it must be called before the scores() method is called first.

class votelib.component.rankscore.SequenceBased(sequence)

A rank scorer with a predetermined sequence of scores.

This is used in many competitions (Eurovision, Formula One, etc.)

Assigns scores according to the given sequence until hitting zero, and zero scores afterwards.

Parameters

sequence (List[Number]) – The scores for the top candidates on the ballot.

scores(n_ranked)

Return the scores for the first n_ranked ranks.

This gives values from the initial sequence, then zeros.

Parameters

n_ranked (int) – Number of ranks to be returned. Equal to the length of the output list.

Return type

List[Number]

votelib.component.rankscore.select_padded(sequence, n, pad_with=0)

Select n leading elements from sequence, padding with pad_with.

Padding with pad_with is used when sequence is not long enough to select n elements.

Return type

List[Any]

Vote transferers for STV

Objects to transfer votes between candidates for transferable vote systems.

Transfers of votes from eliminated and elected candidates to candidates staying in the contest are an essential part of any transferable vote system, such as the one of votelib.evaluate.sequential.TransferableVoteSelector. There are many variants how to achieve this, some are implemented here.

NOTE: The VoteTransferer interface is provisional and may be changed in the future, chiefly to accommodate a wider range of transfer methods (Meek, Wright…)

class votelib.component.transfer.Gregory

Gregory (fractional) vote transferer.

The variant used is the Weighted Inclusive Gregory Method (WIGM) used e.g. in Scottish local government elections.

When a candidate is elected by quota, the fraction corresponding to the quota divided by total votes for the candidate is used to multiply (lower) each vote allocated to that candidate; the votes are then transferred to next candidates on the ballots.

In case of shared ranks, the votes are evenly distributed between the candidates sharing the rank.

The implementation produces exact fractional votes. Rounding rules are not implemented yet.

subtract(allocation, elected)

Remove votes from elected candidates according to the quota.

Parameters
  • allocation (Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]) – Current allocation of ranked votes to candidates. The votes allocated to elected candidates will be lowered by the amount corresponding to the quota for their election.

  • elected (Dict[Union[str, CandidateObject], int]) – Elected candidates, mapped to the quota with which they were elected (or multiples thereof, if they were awarded multiple seats). These quotas should be removed from the candidates’ votes (because so many votes were used).

Return type

Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]

transfer(allocation, candidates)

Transfer votes from eliminated or fully elected candidates.

Parameters
  • allocation (Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]) – Current allocation of ranked votes to candidates. The votes allocated to specified candidates will be reallocated to other candidates that are present in the allocation, or reassigned to the None key as exhausted ballots.

  • candidates (List[Union[str, CandidateObject]]) – Candidates to be removed from the allocation.

Return type

Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]

class votelib.component.transfer.Hare(seed=None)

Hare (random ballot selection) vote transferer.

This is the variant used (AFAIK) in Irish lower house legislative elections (Dáil Éireann).

When a candidate is elected by quota, the number of ballots corresponding to the quota is randomly selected and discarded, the rest is fully transferred to their next preferences.

In case of shared ranks, the votes are randomly distributed between the candidates sharing the rank.

Parameters

seed (Optional[int]) – Seed for the random generator.

subtract(allocation, elected)

Remove votes from elected candidates according to the quota.

Parameters
  • allocation (Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]) – Current allocation of ranked votes to candidates. The votes allocated to elected candidates will be lowered by the amount corresponding to the quota for their election.

  • elected (Dict[Union[str, CandidateObject], int]) – Elected candidates, mapped to the quota with which they were elected (or multiples thereof, if they were awarded multiple seats). These quotas should be removed from the candidates’ votes (because so many votes were used).

Return type

Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]

transfer(allocation, candidates)

Transfer votes from eliminated or fully elected candidates.

Parameters
  • allocation (Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]) – Current allocation of ranked votes to candidates. The votes allocated to specified candidates will be reallocated to other candidates that are present in the allocation, or reassigned to the None key as exhausted ballots.

  • candidates (List[Union[str, CandidateObject]]) – Candidates to be removed from the allocation.

Return type

Dict[Union[str, CandidateObject, None], Dict[Tuple[Union[str, CandidateObject, FrozenSet[Union[str, CandidateObject]]], …], Number]]