interregnum.methods.preferential package

Preferential vote allocators.

A preferential vote allocator needsan input preferences.

class interregnum.methods.preferential.BordaCountAllocator(rank_f, tie_counting=None, tie_break='from_first_vote')

Bases: MultiWinnerAdapter[AnyName, BordaResultData, list[Preference[AnyName]], Iterable[Preference[AnyName] | PrefDict[AnyName] | tuple[int | Fraction, Sequence[AnyName | Tuple[AnyName, …] | list[AnyName]] | tuple[AnyName | Tuple[AnyName, …] | list[AnyName], …]]]]

Borda count allocator.

See https://en.wikipedia.org/wiki/Borda_count

allocators keys:

  • borda

  • borda_count

Create a borda count allocator.

Parameters:

Examples

>>> # use the Nauru score
>>> # allow ballot ties (tie members will get the average score)
>>> # in case of a candidates tie, use partial votes to break it,
>>> # starting from the first position
>>> borda = BordaCountAllocator(
>>>     "nauru",
>>>     tie_counting="average",
>>>     tie_break="from_first_vote"
>>> )
calc(preferences, seats=1, random_seed=None, max_ballot_size=None, candidate_list=None, **kwargs)

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], ...]]]) – preferential votes

  • seats (int) – allocatable seats

  • max_ballot_size (int | None) – fixed ballot size (if empty, get the size of the larger ballot)

  • random_seed (int | Random | None) – used by tie-breakers

  • candidate_list (Iterable[AnyName] | None)

  • kwargs (Any)

Return type:

NonDeterministicResult[AnyName, BordaResultData]

class interregnum.methods.preferential.CondorcetCopelandAllocator(allow_ties=True, fill_truncated=False)

Bases: CondorcetAllocator[AnyName]

Copeland’s pairwise aggregation method.

See https://en.wikipedia.org/wiki/Copeland%27s_method

allocators collection keys:

  • copeland

  • condorcet_copeland

Create a Copeland allocator.

Parameters:
  • allow_ties (bool) – allow more than one candidate at the same preference position

  • fill_truncated (bool) – fill a truncated ballot with a tie of the remaining candidates

class interregnum.methods.preferential.CondorcetMinimaxAllocator(margin=False, allow_ties=True, fill_truncated=False)

Bases: CondorcetAllocator[AnyName]

Minimax / Simpson-Kramer method.

See https://en.wikipedia.org/wiki/Minimax_Condorcet

allocators collection keys:

  • minimax

  • condorcet_minimax

Create a Minimax allocator.

Parameters:
  • margin (bool) – If margin is True, use vote margins instead of difference of votes as the inner score.

  • allow_ties (bool) – allow more than one candidate at the same preference position

  • fill_truncated (bool) – fill a truncated ballot with a tie of the remaining candidates

Subpackages

Submodules

interregnum.methods.preferential.borda_count module

Borda Count methods for preferential votes.

References

TODO - references

class interregnum.methods.preferential.borda_count.BallotTieCounting(*values)

Bases: Enum

Ballot ties counting methods.

classmethod get_value(value)

Get a value from string or return the same value.

Parameters:

value (str | BallotTieCounting | None)

Return type:

BallotTieCounting

classmethod parse(text)

Parse from string.

Raises:

ValueError – When the text could not be parsed.

Parameters:

text (str | None)

Return type:

BallotTieCounting

AVERAGE = 4

set the averaged position scores to the tie

DOWN = 2

set the last position score to the tie

NONE = 1

do not allows ties

UP = 3

set the first position score to the tie

class interregnum.methods.preferential.borda_count.BordaCountAllocator(rank_f, tie_counting=None, tie_break='from_first_vote')

Bases: MultiWinnerAdapter[AnyName, BordaResultData, list[Preference[AnyName]], Iterable[Preference[AnyName] | PrefDict[AnyName] | tuple[int | Fraction, Sequence[AnyName | Tuple[AnyName, …] | list[AnyName]] | tuple[AnyName | Tuple[AnyName, …] | list[AnyName], …]]]]

Borda count allocator.

See https://en.wikipedia.org/wiki/Borda_count

allocators keys:

  • borda

  • borda_count

Create a borda count allocator.

Parameters:

Examples

>>> # use the Nauru score
>>> # allow ballot ties (tie members will get the average score)
>>> # in case of a candidates tie, use partial votes to break it,
>>> # starting from the first position
>>> borda = BordaCountAllocator(
>>>     "nauru",
>>>     tie_counting="average",
>>>     tie_break="from_first_vote"
>>> )
calc(preferences, seats=1, random_seed=None, max_ballot_size=None, candidate_list=None, **kwargs)

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], ...]]]) – preferential votes

  • seats (int) – allocatable seats

  • max_ballot_size (int | None) – fixed ballot size (if empty, get the size of the larger ballot)

  • random_seed (int | Random | None) – used by tie-breakers

  • candidate_list (Iterable[AnyName] | None)

  • kwargs (Any)

Return type:

NonDeterministicResult[AnyName, BordaResultData]

class interregnum.methods.preferential.borda_count.BordaCountState(data, mode, borda_score=None, *, random_seed)

Bases: MultiWinnerState[BordaResultData, AnyName]

A calculation state for Borda count.

Parameters:
break_tie(candidates, ascending)

Resolve tie affecting candidates.

return criterion, winner

Parameters:
Return type:

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

borda_score: BordaRanking[AnyName] | None = None
mode: PartialTieBreak
class interregnum.methods.preferential.borda_count.BordaRanking(preferences, rank_f, candidate_list=None, ballot_size=None, modified_borda=False, tie_counting=BallotTieCounting.NONE)

Bases: RankingList[AnyName]

A ranking list based on Borda counting.

Create a Borda ranking list.

Parameters:
  • preferences (Sequence[Preference[AnyName]]) – ballots

  • rank_f (RankFunction) – a ranking function

  • candidate_list (ipt.INames[AnyName] | None) – full list of contenders

  • ballot_size (int | None) – set a fixed ballot size

  • modified_borda (bool) – use dynamic ballot size (scores will be adjusted to each ballot size)

  • tie_counting (BallotTieCounting) – ballot tie counting mode

get_partials(name)

Get partial scores for a given ballot position.

Parameters:

name (AnyName)

Return type:

list[int | Fraction]

get_score(ballot_size, position, cardinality)

Return score, next position.

Parameters:
  • ballot_size (int)

  • position (int)

  • cardinality (int)

Return type:

tuple[int | Fraction, int]

class interregnum.methods.preferential.borda_count.BordaResultData(log=<factory>, threshold=0, remaining_seats=0, rounds=0, ballot_size=0)

Bases: MultiWinnerResultData

Additional result data.

Parameters:
  • log (list[Event])

  • threshold (int | Fraction)

  • remaining_seats (int)

  • rounds (int)

  • ballot_size (int)

ballot_size: int = 0

Number of preferences on the ballot

interregnum.methods.preferential.borda_count.check_ballots(tie_counting, ballots)

Check that the ballots are valid for the tie counting mode.

  • AVERAGE tie counting allows ties at any position.

  • UP and DOWN only allow terminal ties.

Parameters:
Return type:

None

interregnum.methods.preferential.borda_count.PartialScore

A score for a candidate after N steps

alias of SparseTable[AnyName, int, int | Fraction]

interregnum.methods.preferential.io module

Tools for reading and writing preferential votes.

class interregnum.methods.preferential.io.PreferenceDialect(preferent='>', equal='=', score=':', comment='#', preamble='!', _long_names=<factory>)

Bases: object

A dialect of a preference votes file format.

Structure

<preamble>
<preferences>

Preamble (optional)

  • A line in the preamble starts with !

  • A comment line starts with #

The preamble defines the escape characters:

!preference >
!equal =
!votes :

Then, it can define alias for candidates names:

!L=my long party name
!R=rival party

Preferences

Preferences can be associated to a number of votes or can represent individual ballots.

50:A>B=C>L>R
C>B>A

A position with the equal character is representing a tie.

as_preamble(line)

Return the same line without the preamble prefix, or None.

Parameters:

line (str)

Return type:

str | None

check_name(name)

Check if a name does not have reserved chars.

Parameters:

name (str)

Return type:

str

is_comment(line)

Return True if line is a comment.

Parameters:

line (str)

Return type:

bool

position_to_str(position, short_names)

Convert a preference position (a candidate or a tuple of candidates) to string.

Parameters:
  • position (str | tuple[str, ...])

  • short_names (Mapping[str, str])

Return type:

str

read_preference(converter, line)

Read a preference line.

Each name will be converted using converter.

Parameters:
  • convert – a function that converts a string to a name

  • line (str) – text line with a preference

  • converter (Callable[[str], AnyName])

Return type:

tuple[int, Sequence[AnyName | Tuple[AnyName, …]]]

update_equivalence(line)

Update equvalence map with this line info.

<short name>=<long name>

Parameters:

line (str)

Return type:

None

update_escape(line)

Update dialect with the escape symbol defined in this line.

Raises:

ValueError – if the equivalence cannot be read

Parameters:

line (str)

Return type:

None

write_preamble(stream, short_names)

Write a preamble defining this dialect and names equivalences.

Parameters:
  • stream (IO[str]) – text stream

  • short_names (Mapping[str, str]) – long name -> short name mapping

Return type:

None

write_preferences(stream, compact, preferences)

Write preferences to a stream using this dialect.

Parameters:
  • compact (Iterable[str] | None) – list of names that will be compacted

  • preferences (Iterable[tuple[int, Sequence[str | tuple[str, ...]]]]) – list of preferences

  • stream (IO[str])

Return type:

None

comment: str

comment line prefix

equal: str

separator for ties

preamble: str

prefix for lines in the preamble

preferent: str

separator for preferences

score: str

separator between votes/scores and preferences

Parameters:
  • preferent (str)

  • equal (str)

  • score (str)

  • comment (str)

  • preamble (str)

  • _long_names (dict[str, str])

interregnum.methods.preferential.io.read_preferences(stream, converter)

Read a stream with preferences.

Parameters:
  • converter (Callable[[str], AnyName]) – convert names using this function

  • stream (IO[str])

Return type:

Iterator[tuple[int, Sequence[AnyName | Tuple[AnyName, …]]]]

interregnum.methods.preferential.ties module

Strategies for breaking candidates ties.

class interregnum.methods.preferential.ties.PartialTieBreak(*values)

Bases: Enum

Tie break strategies using partial votes.

classmethod get_value(value)

Convert a value to a PartialTieBreak enum.

Raises:

ValueError – If value could not be parsed

Parameters:

value (str | PartialTieBreak)

Return type:

PartialTieBreak

FROM_FIRST_VOTE = 1

explore partial scores from the first position to the last

FROM_LAST_VOTE = 2

explore partial scores from the last position to the first

RANDOM = 3

eplore partial scores randomly

interregnum.methods.preferential.types module

Preferential methods common code.

class interregnum.methods.preferential.types.PreferentialAllocator(required_input, optional_input)

Bases: Allocator[AnyName, Data]

A preferential allocator.

Allocator constructor.

Its calc() method requires required_input as arguments and admits optional_input.

Parameters:
  • required_input (Input) – Flags describing the types of inputs the method requires

  • optional_input (Input) – Flags describing the types of inputs the method optially admits

classmethod positional_votes(data, ballot_size=None, whitelist=None, shrink=True)

Return positional votes by candidate.

Parameters:
  • data (Iterable[Preference[AnotherName]])

  • ballot_size (int | None)

  • whitelist (frozenset[AnotherName] | None)

  • shrink (bool)

Return type:

tuple[dict[AnotherName, Sequence[int | Fraction]], int]

static get_max_ballot_size(data)

Return the size of the longest preference sequence.

Parameters:

data (Iterable[Preference[Any]])

Return type:

int