interregnum.methods.preferential.transferable_vote package

Preferential vote allocators using transferable vote.

class interregnum.methods.preferential.transferable_vote.InstantRunOffAllocator(tie_break='from_first_vote')

Bases: NonDeterministicAllocator[AnyName, TVResultData]

Transferable vote / Instant run-off voting.

The most voted candidate which reaches the absolute majority wins the seats. If any candidate has the majority of the votes, the less voted candidate is removed and the votes are assigned to the next preferences.

See https://en.wikipedia.org/wiki/Instant-runoff_voting

allocators collection keys:

  • instant_runoff

  • instant_run_off

  • alternative_voting

  • ranked_choice

  • ranked_choice_voting

  • transferable_voting

Create an Instant Run-off allocator.

Parameters:

tie_break (PartialTieBreak | str) – strategy for breaking candidates ties using partial scores.

calc(preferences, random_seed=None, candidate_list=None, total_votes=None, exclude_candidates=None)

Allocate seats to candidates.

Parameters:
  • preferences (Iterable[Preference[AnyName] | PrefDict[AnyName] | tuple[int | Fraction, Sequence[AnyName | Tuple[AnyName, ...] | list[AnyName]] | tuple[AnyName | Tuple[AnyName, ...] | list[AnyName], ...]]]) – list of grouped preference ballots

  • random_seed (int | Random | None) – used to break ties

  • candidate_list (Iterable[AnyName] | None) – full list of allowed candidates

  • total_votes (int | Fraction | None) – total number of votes used when calculating the majority quota (if empty, the number of ballots will be used.)

  • exclude_candidates (Iterable[AnyName] | None) – exclude the provided candidates from winning seats

Return type:

NonDeterministicResult[AnyName, TVResultData]

class interregnum.methods.preferential.transferable_vote.SingleTransferableVoteAllocator(quota_f, transfer_f, round_f, tie_break='from_first_vote')

Bases: NonDeterministicAllocator[AnyName, STVResultData]

Single Transferable Vote method.

  • Each candidate that surpasses the calculated quota wins a seat. Their unused votes are moved to the next preference.

  • If no candidate reaches the quota, the less voted candidate is removed and his/her votes are moved to the next preference.

The transfer of the surplus votes is calculated using different transfer strategies.

See https://en.wikipedia.org/wiki/Single_transferable_vote, [Gallagher:1992], [EireSTV], [AusProp], [Miragliotta2002].

allocators collection keys:

  • single_transferable_vote

Create a Single Transferable Vote allocator.

Parameters:
calc(preferences, seats, random_seed=None, candidate_list=None, total_votes=None, filter_f=None)

Allocate seats to candidates.

Parameters:
  • preferences (Iterable[Preference[AnyName] | PrefDict[AnyName] | tuple[int | Fraction, Sequence[AnyName | Tuple[AnyName, ...] | list[AnyName]] | tuple[AnyName | Tuple[AnyName, ...] | list[AnyName], ...]]]) – list of grouped preferences ballots

  • seats (int) – allocatable seats

  • random_seed (int | Random | None) – used to break ties

  • candidate_list (Iterable[AnyName] | None) – full list of allowed candidates

  • total_votes (int | Fraction | None) – total number of votes used to calculate quotas

  • filter_f (CandidateFilter[AnyName, Event] | None) – filter function to exclude candidates from getting seats

Return type:

NonDeterministicResult[AnyName, STVResultData]

Submodules

interregnum.methods.preferential.transferable_vote.instant_runoff module

Instant Run-off.

class interregnum.methods.preferential.transferable_vote.instant_runoff.InstantRunOffAllocator(tie_break='from_first_vote')

Bases: NonDeterministicAllocator[AnyName, TVResultData]

Transferable vote / Instant run-off voting.

The most voted candidate which reaches the absolute majority wins the seats. If any candidate has the majority of the votes, the less voted candidate is removed and the votes are assigned to the next preferences.

See https://en.wikipedia.org/wiki/Instant-runoff_voting

allocators collection keys:

  • instant_runoff

  • instant_run_off

  • alternative_voting

  • ranked_choice

  • ranked_choice_voting

  • transferable_voting

Create an Instant Run-off allocator.

Parameters:

tie_break (PartialTieBreak | str) – strategy for breaking candidates ties using partial scores.

calc(preferences, random_seed=None, candidate_list=None, total_votes=None, exclude_candidates=None)

Allocate seats to candidates.

Parameters:
  • preferences (Iterable[Preference[AnyName] | PrefDict[AnyName] | tuple[int | Fraction, Sequence[AnyName | Tuple[AnyName, ...] | list[AnyName]] | tuple[AnyName | Tuple[AnyName, ...] | list[AnyName], ...]]]) – list of grouped preference ballots

  • random_seed (int | Random | None) – used to break ties

  • candidate_list (Iterable[AnyName] | None) – full list of allowed candidates

  • total_votes (int | Fraction | None) – total number of votes used when calculating the majority quota (if empty, the number of ballots will be used.)

  • exclude_candidates (Iterable[AnyName] | None) – exclude the provided candidates from winning seats

Return type:

NonDeterministicResult[AnyName, TVResultData]

class interregnum.methods.preferential.transferable_vote.instant_runoff.TVResultData(log=<factory>, threshold=0, rounds=0)

Bases: EventLog

Transerable vote result data.

Parameters:
  • log (list[Event])

  • threshold (int | Fraction)

  • rounds (int)

rounds: int = 0
threshold: int | Fraction = 0
class interregnum.methods.preferential.transferable_vote.instant_runoff.TVTallyBoard(mode, batches=<factory>, history=<factory>, elected=<factory>, data=<factory>, *, random_seed)

Bases: NonDeterministicState, Generic[AnyName]

Data needed for the tally.

Parameters:
add_winner(winners, criterion)

Add winner to elected.

Parameters:
Return type:

None

break_tie(candidates, ascending=False)

Break candidates ties using partial score rankings.

Parameters:
Return type:

dict[str, list[Candidate[AnyName]]]

collect(preferences, candidate_list)

Collect preferences to the tally board.

Parameters:
Return type:

None

exclude(name)

Exclude candidate ‘name’ from the tally.

Parameters:

name (AnyName)

Return type:

None

get_eligible_candidates()

Get the list of eligible candidates, sorted by most voted to less voted.

Return type:

list[Candidate[AnyName]]

initial_exclusion(candidates)

Prepare initial exclusion list.

Parameters:

candidates (Iterable[AnyName] | None)

Return type:

None

remove_loser(losers, lowest)

Remove loser from eligible and transfer votes.

Parameters:
Return type:

list[Candidate[AnyName]]

transfer_votes(source)

Transfer votes from candidate source.

Parameters:

source (AnyName)

Return type:

None

batches: list[Preference[AnyName]]
data: TVResultData
elected: list[Candidate[AnyName]]
history: dict[AnyName, list[int | Fraction]]
mode: PartialTieBreak

interregnum.methods.preferential.transferable_vote.parcel module

A parcel of preferential votes.

class interregnum.methods.preferential.transferable_vote.parcel.CandidateParcels(votes=0, parcels=<factory>, state=CandidateState.ELIGIBLE)

Bases: Generic[AnyName]

List of a candidate’s parcels.

Parameters:
classmethod collect(batches, candidate_list)

Collect parcels for all the candidates.

Parameters:
Return type:

dict[AnotherName, CandidateParcels[AnotherName]]

elect()

Set state as elected.

Return type:

None

exclude()

Set state as excluded.

Return type:

None

is_eligible()

Return True if the candidate can win seats.

Return type:

bool

total_ballot_papers()

Return the score associated to the owned ballots.

Return type:

int | Fraction

parcels: list[Parcel[AnyName]]
state: CandidateState
votes: int | Fraction
class interregnum.methods.preferential.transferable_vote.parcel.CandidateState(*values)

Bases: Enum

A possible state for a Candidate.

ELECTED = 2

the candidate already won seats

ELIGIBLE = 1

the candidate can win seats

EXCLUDED = 3

the candidate has been discarded

class interregnum.methods.preferential.transferable_vote.parcel.Parcel(batches, votes=0, weight=<factory>, group_id=0)

Bases: Generic[AnyName]

A parcel of votes transferable to another candidate.

Parameters:
  • batches (list[interregnum.methods.types.preference.Preference[interregnum.methods.types.AnyName]]) – batches of transferred preferences

  • votes (int | fractions.Fraction) – representative votes for the new owner

  • weight (fractions.Fraction) – ratio of the votes transferred to the new owner

  • group_id (int) – round id for this parcel

group_by_next_preference(ignore)

Group batches by sources.

Parameters:

ignore (Container[AnyName]) – exclude candidates in this list

Return type:

dict[AnyName | None, list[Preference[AnyName]]]

total_ballot_papers()

Total number of ballot papers.

Return type:

int | Fraction

batches: list[Preference[AnyName]]
group_id: int
votes: int | Fraction
weight: Fraction

interregnum.methods.preferential.transferable_vote.single_transferable_vote module

Single transferable vote.

References


class interregnum.methods.preferential.transferable_vote.single_transferable_vote.STVResultData(log=<factory>, threshold=0, remaining_seats=0, rounds=0)

Bases: EventLog

Single transferable vote result data.

Parameters:
  • log (list[Event])

  • threshold (int | Fraction)

  • remaining_seats (int)

  • rounds (int)

remaining_seats: int = 0
rounds: int = 0
threshold: int | Fraction = 0
class interregnum.methods.preferential.transferable_vote.single_transferable_vote.SingleTransferableVoteAllocator(quota_f, transfer_f, round_f, tie_break='from_first_vote')

Bases: NonDeterministicAllocator[AnyName, STVResultData]

Single Transferable Vote method.

  • Each candidate that surpasses the calculated quota wins a seat. Their unused votes are moved to the next preference.

  • If no candidate reaches the quota, the less voted candidate is removed and his/her votes are moved to the next preference.

The transfer of the surplus votes is calculated using different transfer strategies.

See https://en.wikipedia.org/wiki/Single_transferable_vote, [Gallagher:1992], [EireSTV], [AusProp], [Miragliotta2002].

allocators collection keys:

  • single_transferable_vote

Create a Single Transferable Vote allocator.

Parameters:
calc(preferences, seats, random_seed=None, candidate_list=None, total_votes=None, filter_f=None)

Allocate seats to candidates.

Parameters:
  • preferences (Iterable[Preference[AnyName] | PrefDict[AnyName] | tuple[int | Fraction, Sequence[AnyName | Tuple[AnyName, ...] | list[AnyName]] | tuple[AnyName | Tuple[AnyName, ...] | list[AnyName], ...]]]) – list of grouped preferences ballots

  • seats (int) – allocatable seats

  • random_seed (int | Random | None) – used to break ties

  • candidate_list (Iterable[AnyName] | None) – full list of allowed candidates

  • total_votes (int | Fraction | None) – total number of votes used to calculate quotas

  • filter_f (CandidateFilter[AnyName, Event] | None) – filter function to exclude candidates from getting seats

Return type:

NonDeterministicResult[AnyName, STVResultData]

class interregnum.methods.preferential.transferable_vote.single_transferable_vote.TallyBoard(transfer_f, round_f, filter_f, table, mode, elected=<factory>, surplus=<factory>, history=<factory>, data=<factory>, *, random_seed)

Bases: NonDeterministicState, Generic[AnyName]

Data needed for the tally.

Parameters:
add_winner(winners)

Add winner to elected and transfer votes.

Parameters:

winners (list[Candidate[AnyName]])

Return type:

list[Candidate[AnyName]]

apply_surplus()

Get a pending surplus and transfer votes.

Return type:

list[Candidate[AnyName]]

apply_transfers(source, deltas)

Apply transfers for source.

Parameters:
Return type:

None

break_tie(candidates, limit, ascending=False)

Break tie.

Parameters:
Return type:

dict[str, list[Candidate[AnyName]]]

compute_transfers(source, surplus=None)

Compute vote transfers from candidate ‘source’.

If not surplus given, transfer all ‘source’ votes

Parameters:
  • source (AnyName)

  • surplus (int | Fraction | None)

Return type:

dict[AnyName | None, CandidateParcels[AnyName]]

filter_candidates(eligible)

Filter eligible candidates.

Parameters:

eligible (list[Candidate[AnyName]])

Return type:

list[Candidate[AnyName]]

get_eligible_candidates()

List of eligible candidates.

Elected and excluded candidates are not returned.

Return type:

list[Candidate[AnyName]]

remove_loser(losers, lowest)

Remove loser from eligible and transfer votes.

Parameters:
Return type:

list[Candidate[AnyName]]

data: STVResultData
elected: list[Candidate[AnyName]]
filter_f: CandidateFilter[AnyName, Event] | None
history: dict[AnyName, list[int | Fraction]]
mode: PartialTieBreak
round_f: Callable[[int | Fraction], int | Fraction]
surplus: list[tuple[AnyName, int | Fraction]]
table: dict[AnyName, CandidateParcels[AnyName]]
transfer_f: Callable[[Callable[[int | Fraction], int | Fraction], dict[AnyName, CandidateParcels[AnyName]], AnyName, int | Fraction | None], dict[AnyName | None, CandidateParcels[AnyName]]]

interregnum.methods.preferential.transferable_vote.transfer_functions module

Transfer functions for Single Transferable Vote.

References


interregnum.methods.preferential.transferable_vote.transfer_functions.gregory_transfer(round_f, table, source, surplus=None)

Gregory transfer method (“Last Parcel”).

Parameters:
  • round_f (Callable[[int | Fraction], int | Fraction]) – rounding function to convert from transfer values to votes

  • table (dict[AnyName, CandidateParcels[AnyName]]) – parcels for each candidate

  • source (AnyName) – candidate who will transfer his/her votes

  • surplus (int | Fraction | None) – surplus to transfer. If None, transfer value weight will be set to 1

Return type:

dict[AnyName | None, CandidateParcels[AnyName]]

See [EireSTV], [AusProp], [Miragliotta2002].

transfers collection keys:

  • gregory

  • last_parcel

interregnum.methods.preferential.transferable_vote.transfer_functions.inclusive_gregory_transfer(weighted, round_f, table, source, surplus=None)

Weighted and Unweighted Inclusive Gregory transfer method.

Parameters:
  • weighted (bool) – choose either weighted or unweighted variable

  • round_f (Callable[[int | Fraction], int | Fraction]) – rounding function to convert from transfer values to votes

  • table (dict[AnyName, CandidateParcels[AnyName]]) – parcels for each candidate

  • source (AnyName) – candidate who will transfer his/her votes

  • surplus (int | Fraction | None) – surplus to transfer. If None, transfer value weight will be set to 1

Return type:

dict[AnyName | None, CandidateParcels[AnyName]]

See [EireSTV], [AusProp], [Miragliotta2002].

transfers collection keys:

unweighted:

  • unweighted_gregory

  • inclusive_gregory

  • unweighted_gregory_transfer

weighted:

  • weighted_gregory

  • weighted_inclusive_gregory

interregnum.methods.preferential.transferable_vote.transfer_functions.unweighted_gregory_transfer(round_f, table, source, surplus=None)

Weighted and Unweighted Inclusive Gregory transfer method.

Parameters:
  • weighted – choose either weighted or unweighted variable

  • round_f (RoundingFunction) – rounding function to convert from transfer values to votes

  • table (dict[AnyName, CandidateParcels[AnyName]]) – parcels for each candidate

  • source (AnyName) – candidate who will transfer his/her votes

  • surplus (Score | None) – surplus to transfer. If None, transfer value weight will be set to 1

Return type:

dict[AnyName | None, CandidateParcels[AnyName]]

See [EireSTV], [AusProp], [Miragliotta2002].

transfers collection keys:

unweighted:

  • unweighted_gregory

  • inclusive_gregory

  • unweighted_gregory_transfer

weighted:

  • weighted_gregory

  • weighted_inclusive_gregory

interregnum.methods.preferential.transferable_vote.transfer_functions.weighted_gregory_transfer(round_f, table, source, surplus=None)

Weighted and Unweighted Inclusive Gregory transfer method.

Parameters:
  • weighted – choose either weighted or unweighted variable

  • round_f (RoundingFunction) – rounding function to convert from transfer values to votes

  • table (dict[AnyName, CandidateParcels[AnyName]]) – parcels for each candidate

  • source (AnyName) – candidate who will transfer his/her votes

  • surplus (Score | None) – surplus to transfer. If None, transfer value weight will be set to 1

Return type:

dict[AnyName | None, CandidateParcels[AnyName]]

See [EireSTV], [AusProp], [Miragliotta2002].

transfers collection keys:

unweighted:

  • unweighted_gregory

  • inclusive_gregory

  • unweighted_gregory_transfer

weighted:

  • weighted_gregory

  • weighted_inclusive_gregory

interregnum.methods.preferential.transferable_vote.transfer_functions.TTransferFunction

A transfer function

alias of Callable[[Callable[[int | Fraction], int | Fraction], dict[AnyName, CandidateParcels[AnyName]], AnyName, int | Fraction | None], dict[AnyName | None, CandidateParcels[AnyName]]]

interregnum.methods.preferential.transferable_vote.transfer_functions.transfers: FunctionCollection[Callable[[Callable[[int | Fraction], int | Fraction], dict[SortHash, CandidateParcels[SortHash]], SortHash, int | Fraction | None], dict[SortHash | None, CandidateParcels[SortHash]]]] = <interregnum.collections.FunctionCollection object>

Collection of transfers