interregnum.methods.adapters package

Adapters are allocators that modifies the behaviour of base methods.

Submodules

interregnum.methods.adapters.initialseats module

Allocator adapter that admits initial seats.

class interregnum.methods.adapters.initialseats.InitialSeatsAdapter(allocator_f, min_seats, resume_allocation=True, skip_initial_seats=False)

Bases: Allocator[AnyName, Any], Generic[AnyName, Data]

Adapter that admits initial seats.

Create an initial seats adapter.

Each non-excluded candidate will win at least min_seats.

If resume_allocation, the allocation method will resume the process from the state provided from the already allocated seats (allocator_f must not ignore seats).

Otherwise, the allocation is done as if no initial seats were present, and then the initial seats will be added to the final result.

Parameters:
  • allocator_f (tp.Allocator[tp.AnyName, tp.Data])

  • min_seats (int)

  • resume_allocation (bool)

  • skip_initial_seats (bool)

calc(initial_seats=None, exclude_candidates=None, candidate_list=None, skip_initial_seats=None, **method_args)

Allocate seats to candidates.

The number of declared seats wil be pased to the allocator in addition to the allocated initial seats.

Parameters:
  • initial_seats (Iterable[tuple[AnyName, int]] | None) – each candidate will start with the maximum of initial_seats or min_seats

  • exclude_candidates (Iterable[AnyName] | None) – candidates in this list will not receive seats

  • candidate_list (Iterable[AnyName] | None) – explicit list of candidates to take into account

  • skip_initial_seats (bool | None)

  • method_args (Any)

Return type:

Result[AnyName, Data] | Result[AnyName, InitialSeatsResultData[AnyName, Data]]

class interregnum.methods.adapters.initialseats.InitialSeatsResultData(log=<factory>, initial_seats=<factory>, step=None)

Bases: EventLog, Generic[AnyName, Data]

Initial seats adapter result data.

Parameters:
initial_seats: Sequence[_NamedSeat[AnyName]]
step: Result[AnyName, Data] | None = None

interregnum.methods.adapters.maxseats module

Allocation with max seats constraints.

class interregnum.methods.adapters.maxseats.MaxSeatsAdapter(allocator_f)

Bases: Allocator[AnyName, Any], Generic[AnyName, Data]

Adapt an allocator ensuring all max seats constraints are met.

If the inner allocator does not support filter_f or exclude_candidates, the original allocation will be returned.

Create an adapter using allocator_f as inner allocator.

Parameters:

allocator_f (Allocator[AnyName, Data])

calc(seats, constraints, **params)

Allocate seats to candidates.

Parameters:
  • seats (int) – seats to allocate

  • total_votes – total number of votes

  • constraints (Sequence[tuple[int, Sequence[AnyName]]]) – list of max seats rules

  • params (Any)

Return type:

Result[AnyName, Data] | Result[AnyName, EventLog]

class interregnum.methods.adapters.maxseats.MaxSeatsReachedEvent(candidates, max_seats)

Bases: Event, Generic[AnyName]

Event: max seats reached.

Parameters:
EVENT: ClassVar[str] = 'max seats reached'

Event type

candidates: Sequence[Candidate[AnyName]]

candidates affected by the restriction

max_seats: int

restriction max seats

class interregnum.methods.adapters.maxseats.MaxSeatsResultData(log=<factory>, remaining_seats=0, remaining_votes=0, steps=<factory>)

Bases: EventLog, Generic[AnyName]

Result data for MaxSeatsAdapter.

Parameters:
remaining_seats: int = 0
remaining_votes: int | Fraction = 0
steps: Sequence[Result[AnyName, EventLog]]
class interregnum.methods.adapters.maxseats.MaxSeatsState(rules, elected=<factory>, excluded=<factory>, initial_seats=<factory>, reusable=<factory>, steps=<factory>)

Bases: CalculationState, Generic[AnyName]

A calculation state for max seats adapter.

Parameters:
elect_candidate(candidate)

Set a candidate as elected.

Parameters:

candidate (Candidate[AnyName])

Return type:

None

excluded_candidates()

Compute a list of excluded candidates.

A candidate is excluded if it’s already elected or in an explicit exclusion list.

Return type:

list[AnyName]

rule_1(triggered, name)

Treat rules with only 1 element.

Rules

x <= N

Triggers

x = N -> accept and remove from reusable x > N -> trim and remove from reusable

Parameters:
Return type:

Iterator[Event]

rule_n_exact(triggered, alliance)

Treat rules with more than one candidate and no seats surplus.

Rules

x + y + z <= N no other dependent rule

Triggers

x + y + z = N -> accept and remove from reusable

Parameters:
Return type:

Iterator[Event]

rule_n_surplus(adapter, triggered, alliance, params)

Treat rules with more than one candidate and seats surplus.

Rules

x + y + z <= N x <= A (A <= N) y <= B (B <= N) z <= C (C <= N)

Triggers

x + y + z >= N -> distribute for (x, y, z) and N seats

Parameters:
Return type:

Iterator[Event]

triggered_rules()

Return rules triggered for the new distribution.

Return type:

dict[tuple[AnyName, …], list[TriggeredRule]]

update(allocation)

Update seats from the last general allocation.

Parameters:

allocation (Iterable[Candidate[AnyName]])

Return type:

None

validate_seats(affected)

Validate seats for non-affected candidates.

Parameters:

affected (set[AnyName])

Return type:

None

elected: list[Candidate[AnyName]]
excluded: list[AnyName]
initial_seats: dict[AnyName, int]

valid seats already assigned to candidates

reusable: dict[AnyName, Candidate[AnyName]]

provisional seats for non-elected candidates

rules: RuleSet[AnyName]
steps: list[Result[AnyName, Any]]
class interregnum.methods.adapters.maxseats.MaxVotesFilter(rules)

Bases: CandidateFilter[AnyName, MaxSeatsReachedEvent[AnyName]]

Candidate filter which excludes candidates that do not meet max seats constraints.

List of max seats rules.

Parameters:

rules (Sequence[tuple[int, Sequence[AnyName]]])

exclusion_list()

Return the current excluded candidates.

Return type:

Collection[AnyName]

is_valid(name)

Return True if a candidate is valid (it doesn’t have reached its max seats).

Parameters:

name (AnyName)

Return type:

bool

start()

Initialize this filter.

Logged events

MaxSeatsReachedEvent when the initial seats of candidates reach constraints.

Return type:

Sequence[MaxSeatsReachedEvent[AnyName]]

update(cand)

Update information with new seats added to a candidate.

Parameters:

cand (Candidate[AnyName])

Return type:

Sequence[MaxSeatsReachedEvent[AnyName]]

class interregnum.methods.adapters.maxseats.RuleSet(constraints, validate=False)

Bases: Generic[AnyName]

A set of max seats rules.

Create a max seats rule set.

Parameters:
  • constraints (Sequence[Rule[AnyName]]) – list of rules (<max seats>, [candidate names])

  • validate (bool) –

    if True, check if seats rule complies the following conditions:

    • A candidate A must have one or none simple rule: A <= seats

    • A candidate A must be in one or none complex rule: A + B + C <= seats

    • If a candidate A verifies (A <= seats1) and (A + B + C <= seats2), seats2 must be greater or equal than seats1.

static validate(constraints)

Check if seats rules complies with alliances definitions.

Constraints for defining restricted alliances must follow these conditions:

  • A candidate A must have one or none simple rule: A <= seats

  • A candidate A must be in one or none complex rule: A + B + C <= seats

  • If a candidate A verifies (A <= seats1) and (A + B + C <= seats2), seats2 must be greater or equal than seats1.

Yields:

non-empty rules

Parameters:

constraints (Sequence[tuple[int, Sequence[AnyName]]])

Return type:

Iterator[tuple[int, Sequence[AnyName]]]

__contains__(name)

Return True if a candidate name is in any rule.

Parameters:

name (AnyName)

Return type:

bool

__getitem__(index)

Return rule at index.

Parameters:

index (int)

Return type:

tuple[int, Sequence[AnyName]]

check(seats)

Check if the provided setting violates any rule.

Return a dictionary with the violated rules.

(index, rule seats, assigned seats)

Parameters:

seats (Mapping[AnyName, Candidate[AnyName]])

Return type:

dict[tuple[AnyName, …], list[TriggeredRule]]

compact()

Remove empty rules and sort by length and seats.

Return type:

None

find(name)

Find a candidate and return its main rule.

Parameters:

name (AnyName)

Return type:

tuple[int, tuple[int, Sequence[AnyName]]] | None

remove_name(name, seats)

Simplify ruleset by removing a candidate with seats.

Empty rules are not removed. Invoke compact() explicitly.

Parameters:
Return type:

None

subset(index, redux)

Return a subset with candidates from rule index.

Parameters:
  • index (int) – rule id from where the valid candidates will be taken as reference

  • redux (bool) – exclude rule index if True.

Return type:

Sequence[tuple[int, Sequence[AnyName]]]

class interregnum.methods.adapters.maxseats.TriggeredRule(rule_index, rule_seats, assigned_seats)

Bases: NamedTuple

A rule violation.

Create new instance of TriggeredRule(rule_index, rule_seats, assigned_seats)

Parameters:
  • rule_index (int)

  • rule_seats (int)

  • assigned_seats (int)

is_valid()

Return True if the assigned seats are in the allowed range.

Return type:

bool

assigned_seats: int

Alias for field number 2

rule_index: int

Alias for field number 0

rule_seats: int

Alias for field number 1

interregnum.methods.adapters.maxseats.Rule

A max seats rule.

alias of tuple[int, Sequence[AnyName]]

interregnum.methods.adapters.multiwinner module

Adapters to convert single-winner methods to multi-winner methods.

class interregnum.methods.adapters.multiwinner.MultiWinnerAdapter(make_input_f, ranking_f, required_input, optional_input)

Bases: NonDeterministicAllocator[AnyName, MultiDataT], Generic[AnyName, MultiDataT, DataT, IDataT]

Create a multi-winner allocator from a single-winner allocator.

Given N seats, this method will give each seat for the most ranked candidate in succesive rounds,

Create a multi-winner adapter.

Parameters:
  • make_input_f (Callable[Concatenate[IDataT, ...], DataT]) – input data formatter

  • ranking_f (Callable[..., Ranking[AnyName]]) – a ranking method

  • required_input (Input) – declaration of required inputs for the calc method

  • optional_input (Input) – declaration of optional inputs for the calc method

class interregnum.methods.adapters.multiwinner.MultiWinnerResultData(log=<factory>, threshold=0, remaining_seats=0, rounds=0)

Bases: EventLog

Multi-winner 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.adapters.multiwinner.MultiWinnerState(data, *, random_seed)

Bases: NonDeterministicState, Generic[MultiDataT, AnyName]

A calculation state from multi-winner-adapter.

Parameters:
  • data (MultiDataT)

  • random_seed (dataclasses.InitVar[Union[int, random.Random, NoneType]])

break_tie(candidates, ascending)

Break ties based on a ranking list, or choose randomly if not possible.

Parameters:
Return type:

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

data: MultiDataT
class interregnum.methods.adapters.multiwinner.WinnerTakesAllAdapter(make_input_f, ranking_f, required_input, optional_input)

Bases: MultiWinnerAdapter[AnyName, MultiDataT, DataT, IDataT]

Winner Takes All Adapter using a ranking list.

Create a Winner Takes All adapter.

Parameters:
  • make_input_f (Callable[Concatenate[IDataT, ...], DataT]) – input data formatter

  • ranking_f (Callable[..., Ranking[AnyName]]) – a ranking method

  • required_input (Input) – declaration of required inputs for the calc method

  • optional_input (Input) – declaration of optional inputs for the calc method

interregnum.methods.adapters.ranking module

Utilities to create rankings.

class interregnum.methods.adapters.ranking.Ranking(ascending)

Bases: Generic[AnyName]

A method that finds the most ranked candidates based on an internal criterion.

Create an ascending (or descending) ranking.

Parameters:

ascending (bool)

ascending()

Return True if the best score is the lowest one.

Return type:

bool

empty()

Return True if the ranking list is empty.

Return type:

bool

remove(candidate)

Remove a candidate from this ranking list.

Parameters:

candidate (Candidate[AnyName] | AnyName)

Return type:

None

remove_name(name)

Remove a candidate by name.

Parameters:

name (AnyName)

Return type:

None

winners()

Return winners sorted by score.

Return type:

list[Candidate[AnyName]]

class interregnum.methods.adapters.ranking.RankingList(sorted_scores, ascending)

Bases: Ranking[AnyName]

A ranking based on a sorted list.

Create a ranking based on the value of the votes property.

Parameters:
empty()

Return True if the ranking list is empty.

Return type:

bool

remove_name(name)

Remove a candidate by name.

Parameters:

name (AnyName)

Return type:

None

winners()

Return winners sorted by score.

Return type:

list[Candidate[AnyName]]

class interregnum.methods.adapters.ranking.RankingTable(scores, limit, ascending, from_first)

Bases: Ranking[AnyName]

Ranking for partial votes.

Each candidate owns a tuple of partial votes. Useful for ordering candidates by votes or scores earned in different rounds.

Create a ranking table.

Parameters:
  • limit (int) – explore a limited number of rounds

  • ascending (bool) – set to False for descending scores

  • from_first (bool) – explore from the first round, otherwise, explore from the last round

  • scores (Bidimensional[AnyName, int, Score])

empty()

Return True if the ranking list is empty.

Return type:

bool

remove_name(name)

Remove a candidate by name.

Parameters:

name (AnyName)

Return type:

None

winners()

Return winners sorted by score.

Return type:

list[Candidate[AnyName]]

interregnum.methods.adapters.ranking.break_tie_ranking(ranking, limit, *, fallback=None, first_criterion='tie_break_best_score')

Break a tie based on a ranking.

Parameters:
  • limit (int) – return no more than limit candidates as winners

  • fallback (Callable[[Sequence[Candidate[AnyName]], int], dict[str, list[Candidate[AnyName]]]] | None) – alternative tie-breaking method if an unsolvable tie is found.

  • first_criterion (str) – criterion applied to ties broken by this function (not the callback)

  • ranking (Ranking[AnyName])

Return type:

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