interregnum.district package¶
Multi-district electoral systems.
- class interregnum.district.Compensatory(type='compensatory', name=None, key=None, candidates=None, alliances=None, preferences=None, seats=None, mode=CompensatoryType.ADDITIONAL_MEMBER, max_seats=None, first_vote=None, subtract_excluded_candidates=False, propagate_initial_seats=False, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
BallotsNodeA node for compensatory systems.
- Parameters:
type (Literal['compensatory'])
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
seats (int | ReferenceSet[GroupableReference] | None)
mode (CompensatoryType)
max_seats (int | None)
first_vote (Node | ReferenceSet[GroupableReference] | None)
subtract_excluded_candidates (bool)
propagate_initial_seats (bool)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return seats to allocate.
- Return type:
int | ReferenceSet[GroupableReference]
- grouping()¶
Return a grouping criterion for this node.
- Return type:
Literal[GroupBy.CANDIDATE]
- first_vote: Node | ReferenceSet[GroupableReference] | None = None¶
child node or reference where the first vote is extracted from
- max_seats: int | None = None¶
max number of seats the allocation can use (for growing allocations)
- mode: CompensatoryType = 1¶
allocation mode
- propagate_initial_seats: bool = False¶
propagate candidates’ initial seats to the inner method
- seats: int | ReferenceSet[GroupableReference] | None = None¶
levelling seats
- subtract_excluded_candidates: bool = False¶
exclude seats for excluded candidates due to restrictions
- type: Literal['compensatory'] = 'compensatory'¶
- class interregnum.district.District(type='district', name=None, key=None, candidates=None, alliances=None, preferences=None, seats=None, party_seats=None, district_seats=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
BallotsNodeAn electoral district or constituency.
This node supports methods, candidates and preferences.
- Parameters:
type (Literal['district'])
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
seats (int | ReferenceSet[GroupableReference] | None)
party_seats (Node | ReferenceSet[GroupableReference] | None)
district_seats (Node | ReferenceSet[GroupableReference] | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return seats to allocate.
- Return type:
int | ReferenceSet[GroupableReference]
- grouping()¶
Return a grouping criterion for this node.
- Return type:
Literal[GroupBy.CANDIDATE]
- district_seats: Node | ReferenceSet[GroupableReference] | None = None¶
seats allocated by district (used by bi-proportional methods), extracted from a node result
- party_seats: Node | ReferenceSet[GroupableReference] | None = None¶
seats allocated by party (used by bi-proportional methods), extracted from a node result
- seats: int | ReferenceSet[GroupableReference] | None = None¶
number of seats to allocate (default = 1)
- type: Literal['district'] = 'district'¶
- class interregnum.district.Group(type='group', name=None, key=None, aggregate=False, groupby=None, divisions=<factory>, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
NodeA group of electoral districts.
- Parameters:
type (Literal['group'])
name (str | None)
key (str | None)
aggregate (bool)
groupby (GroupBy | None)
divisions (Sequence[Node])
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return 0 (no seats are associated to groups).
- Return type:
Literal[0]
- grouping()¶
Return a grouping criterion for this node (default:
GroupBy.CANDIDATE).- Return type:
- local_alliances()¶
Return node alliances or None.
- Return type:
Literal[None]
- local_candidates()¶
Return node local candidates or None.
- Return type:
Literal[None]
- local_candidates_references()¶
Return references to local candidates defined elsewhere.
If no references but local candidates exist, return True
- Return type:
Literal[False]
- local_preferences(candidates)¶
Return node local preferential votes or None.
- Parameters:
candidates (Iterable[ContenderId])
- Return type:
Literal[None]
- local_preferences_references()¶
Return references to local preferences defined elsewhere.
If no references but local preferences exist, return True
- Return type:
Literal[False]
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- aggregate: bool = False¶
if True, aggregate children results as this node result
- type: Literal['group'] = 'group'¶
- class interregnum.district.Node(type, name=None, key=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
NodeContextAn electoral node.
A node represents an allocation unit in an electoral system.
- Parameters:
type (str)
name (str | None)
key (str | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- build()¶
Build an allocation context.
- Return type:
- calculate()¶
Build an allocation context from this node and calculate.
- Return type:
None
- clear_data()¶
Clear results, ballots and meta.
- Return type:
None
- find_district(district_id)¶
Find a district by identifier and return a reference to it.
District(id) or None
- Parameters:
district_id (str)
- Return type:
Node | None
- find_level(level)¶
Iterate nodes at a given level from this node.
Positive levels will look levels from this node. Negative levels will look levels from a leaf node.
- Parameters:
level (int)
- Return type:
Iterator[Node]
- get_id()¶
Return a unique identifier for this node.
If a key is present, use it. Otherwise, use name or return a generated id.
- Return type:
str
- get_seats()¶
Return seats to allocate.
- Return type:
int | ReferenceSet[GroupableReference]
- ignore_compute_dependency()¶
Ignore these nodes when computing result.
- Return type:
Sequence[str] | None
- local_alliances()¶
Return node alliances or None.
- Return type:
Sequence[Alliance] | ReferenceSet[GroupableReference] | None
- local_candidates()¶
Return node local candidates or None.
- Return type:
Ballots | ReferenceSet[GroupableReference] | None
- local_candidates_references()¶
Return references to local candidates defined elsewhere.
If no references but local candidates exist, return True
- Return type:
ReferenceSet[GroupableReference] | bool
- local_preferences(candidates)¶
Return node local preferential votes or None.
- Parameters:
candidates (Iterable[ContenderId])
- Return type:
Iterator[Preference[ContenderId]] | ReferenceSet[GroupableReference] | None
- local_preferences_references()¶
Return references to local preferences defined elsewhere.
If no references but local preferences exist, return True
- Return type:
ReferenceSet[GroupableReference] | bool
- transform_contender(contender)¶
Transform contender using the district mapping.
- transform_contender_id(contender_id)¶
Transform contender_id using the district mapping.
- Parameters:
contender_id (ContenderId)
- Return type:
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- groups: Sequence[str] | None = None¶
tags useful for finding node groups
- ignore: Sequence[str] | None = None¶
ignore these node when computing dependencies on results
- key: str | None = None¶
human readable node name (must be unique)
- map_districts: Mapping[str | None, str | None] | None = None¶
map for changing district names when collecting candidates
- max_adjustment_seats: int | None = None¶
maximum number of additional seats this node can win in systems with adjustment seats (such as levelling seats or mixed-member systems)
- meta: dict[str, Any] | None = None¶
additional data
- name: str | None = None¶
type of node
- result: Result[ContenderId, Any] | None = None¶
allocation result
- type: str¶
- class interregnum.district.Reapportionment(type='reapportionment', name=None, key=None, candidates=None, alliances=None, preferences=None, strategy=<GroupBy.DISTRICT: 4>, relative=None, adjustment=None, first_vote=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
BallotsNodeRe-apportionment system.
Use to project adjustment seats allocated by compensatory systems to final districts which already have initial seats, using the votes provided by the field candidates.
Negative levelling seats are supported.
See [Denmark:2011], [Iceland:2013], [Norway:2023], [Germany:2025].
- Parameters:
type (Literal['reapportionment'])
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
strategy (Literal['parallel'] | ~interregnum.district.contenders.GroupBy)
relative (RelativeDivisor | None)
adjustment (Node | ReferenceSet[GroupableReference] | None)
first_vote (Node | ReferenceSet[GroupableReference] | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return seats to allocate.
- Return type:
Literal[0]
- grouping()¶
Return a grouping criterion for this node.
- Return type:
Literal[GroupBy.CANDIDATE]
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- adjustment: Node | ReferenceSet[GroupableReference] | None = None¶
adjustment seats that will be projected to the new districts
- first_vote: Node | ReferenceSet[GroupableReference] | None = None¶
districts where the seats will be projected
- relative: RelativeDivisor | None = None¶
reference numbers (score used as votes for the allocation):
None: use absolute votes for party and district
RelativeDivisor: make a relative score using this divisor
- strategy: Literal['parallel'] | GroupBy = 4¶
how to split allocations:
- parallel ([Iceland:2013]) will allocate each compensatory seat in
the order it was won (requires a method that produces
WinnerEventfor each seat)
GroupBy: split the allocations by the given criterion (for example,party names or districts)
- type: Literal['reapportionment'] = 'reapportionment'¶
- interregnum.district.to_serializable(data, decimals)¶
Serialize objects.
- Parameters:
decimals (int | None) – rounding precision
data (Any)
- Return type:
Any
- interregnum.district.unserialize_node(data: Mapping[str, Any] | str, cwd: Path | None, groupby: Literal[False] = False) Node | ReferenceSet[Reference]¶
- interregnum.district.unserialize_node(data: Mapping[str, Any] | str, cwd: Path | None, groupby: Literal[True]) Node | ReferenceSet[GroupableReference]
Convert a mapping to a node.
The field
fill_candidateswill be interpreted as aCandidatesFileand rows will be injected to nodes.- Parameters:
data (Mapping[str, Any] | str) – source data: if data is a string instead of a mapping, a reference will be returned
cwd (Path | None) – working directory. Used by file readers.
groupby (bool) – use
GroupableReferenceinstead ofReference
- Return type:
Node | ReferenceSet[Reference] | ReferenceSet[GroupableReference]
Submodules¶
interregnum.district.compensatory module¶
Compensatory systems.
- class interregnum.district.compensatory.Compensatory(type='compensatory', name=None, key=None, candidates=None, alliances=None, preferences=None, seats=None, mode=CompensatoryType.ADDITIONAL_MEMBER, max_seats=None, first_vote=None, subtract_excluded_candidates=False, propagate_initial_seats=False, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
BallotsNodeA node for compensatory systems.
- Parameters:
type (Literal['compensatory'])
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
seats (int | ReferenceSet[GroupableReference] | None)
mode (CompensatoryType)
max_seats (int | None)
first_vote (Node | ReferenceSet[GroupableReference] | None)
subtract_excluded_candidates (bool)
propagate_initial_seats (bool)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return seats to allocate.
- Return type:
int | ReferenceSet[GroupableReference]
- grouping()¶
Return a grouping criterion for this node.
- Return type:
Literal[GroupBy.CANDIDATE]
- first_vote: Node | ReferenceSet[GroupableReference] | None = None¶
child node or reference where the first vote is extracted from
- max_seats: int | None = None¶
max number of seats the allocation can use (for growing allocations)
- mode: CompensatoryType = 1¶
allocation mode
- propagate_initial_seats: bool = False¶
propagate candidates’ initial seats to the inner method
- seats: int | ReferenceSet[GroupableReference] | None = None¶
levelling seats
- subtract_excluded_candidates: bool = False¶
exclude seats for excluded candidates due to restrictions
- type: Literal['compensatory'] = 'compensatory'¶
- class interregnum.district.compensatory.CompensatoryType(*values)¶
Bases:
EnumTypes of compensatory systems.
- classmethod parse(value)¶
Parse from string format.
- Parameters:
value (str | CompensatoryType | None)
- Return type:
CompensatoryType | None
- __str__()¶
Return the attribute as a string key.
- Return type:
str
- to_mode()¶
Return an associated mode for the allocator.
- Return type:
- ABSORB_OVERHANG = 3¶
Allocate and subtract the seats won by first vote. The allocated seats are incremented until no overhang seats exist
- ADDITIONAL_MEMBER = 1¶
Resume allocation from the seats won by first vote
- EXCLUDE_OVERHANG_PARTIES = 4¶
Subtract the overhang seats and exclude those parties from the compensatory allocation.
- MIXED_MEMBER = 2¶
Allocate and subtract the seats won by first vote. Any party with overhang seats will will get no new seat.
- SUBTRACT_OVERHANG_SEATS = 5¶
Allocate and subtract the already won seats. Any party with overhang seats will win negative seats in order to compensate the overhang seats
- interregnum.district.compensatory.unserialize_compensatory_dict(data, cwd)¶
Unserialize Compensatory fields.
- Parameters:
data (Mapping[str, Any])
cwd (Path | None)
- Return type:
dict[str, Any]
interregnum.district.contenders module¶
Structures and functions to store and manipulate election contenders.
- class interregnum.district.contenders.Alliance(name, district=None, max_seats=None, groups=<factory>, meta=None)¶
Bases:
objectAlliance information.
- Parameters:
name (str)
district (str | None)
max_seats (int | None)
groups (tuple[str, ...])
meta (dict[str, Any] | None)
- static make(data)¶
Construct a list of alliances from items.
- static merge_collection(batches, by=None)¶
Merge a collection of collections of alliances using a name transformation.
- get_id()¶
Return the alliance ContenderId.
- Return type:
- with_id(cid)¶
Return this alliance with a different ContenderId.
- Parameters:
cid (ContenderId)
- Return type:
- district: str | None¶
alliance district scope
- groups: tuple[str, ...]¶
tags
- max_seats: int | None¶
maximum number of seats the members of this allliance can win in district.
- meta: dict[str, Any] | None¶
additional information
- name: str¶
alliance id
- class interregnum.district.contenders.Contender(name, alliance=None, district=None, votes=None, seats=None, min_seats=0, max_seats=None, groups=<factory>, meta=None)¶
Bases:
objectInformation for a node contender.
- Parameters:
name (str)
alliance (str | None)
district (str | None)
votes (int | Fraction | None)
seats (int | None)
min_seats (int | None)
max_seats (int | None)
groups (tuple[str, ...])
meta (dict[str, Any] | None)
- classmethod from_candidate(candidate, *groups)¶
Convert a Candidate object to a Contender.
- Parameters:
candidate (Candidate[ContenderId])
groups (str)
- Return type:
- static from_dict(items)¶
Create a contender from a mapping.
- Parameters:
items (Mapping[str, str | None])
- Return type:
- static make(data)¶
Make contender objects from a sequence of items.
- static merge_collection(batches, by=<GroupBy.CANDIDATE: 7>)¶
Merge contenders grouped on batches using a name transformation.
- add_groups(*groups)¶
Return a new contender with these groups.
- Parameters:
groups (str)
- Return type:
- candidate(initial_seats)¶
Return a
Candidateobject associated to this contender with initial_seats.- Parameters:
initial_seats (int | None)
- Return type:
- get_alliance()¶
Return the alliance id.
If no alliance is defined, return the contender’s name.
- Return type:
str
- get_id()¶
Return the contender id (name, alliance, district).
- Return type:
- is_blank()¶
Return if this contender is storing blank votes.
Names for blank votes are prefixed with
?- Return type:
bool
- is_special()¶
Return True if this is a special contender (blank or void votes).
- Return type:
bool
- is_void()¶
Return if this contender is storing void/null votes.
Names for void votes are prefixed with
!- Return type:
bool
- merge(other)¶
Merge this contender with another contender and return it as a new contender.
- with_id(cid)¶
Return a new contender replacing the contender id.
- Parameters:
cid (ContenderId)
- Return type:
- alliance: str | None¶
contender’s alliance id
- district: str | None¶
contender’s electoral district
- groups: tuple[str, ...]¶
tags for diverse uses
- max_seats: int | None¶
maximum number of seats the contender can win
- meta: dict[str, Any] | None¶
a dictionary of additional information
- min_seats: int | None¶
minimum number of seats the contender can win
- name: str¶
contender’s name
- seats: int | None¶
seats the contender won (used mainly for testing)
- votes: int | Fraction | None¶
contender’s votes
- class interregnum.district.contenders.ContenderId(name, alliance, district=None)¶
Bases:
objectIdentifier for contenders.
- Parameters:
name (str)
alliance (str)
district (str | None)
- __contains__(other)¶
Return True if this is equal or a more general definition of other’s.
Examples
>>> ContenderId("A", "PARTY", "DISTRICT") in ContenderId("A", "PARTY") True
- Parameters:
other (Any)
- Return type:
bool
- matches(other, criterion)¶
Return True if other matches this using a given transformation criterion.
Examples
>>> ContenderId("A", "PARTY").matches( >>> ContenderId("B", "PARTY"), >>> GroupBy.ALLIANCE >>> ) True
- Parameters:
other (ContenderId)
criterion (GroupBy)
- Return type:
bool
- transform(required)¶
Transform this by removing parts not specified in the required elements.
Examples
>>> ContenderId( >>> "A", "PARTY", "DISTRICT" >>> ).transform(GroupBy.ALLIANCE_ID) ContenderId(name="PARTY", alliance="DISTRICT", district=None)
- Parameters:
required (GroupBy)
- Return type:
- with_district(district, force=False)¶
Return this with the specified district.
If there is already a district, it will not be replaced unless force is True
- Parameters:
district (str | None) – new district name
force (bool) – replace district always (even when the field is not empty)
- Return type:
- alliance: str¶
collective name for all the contender’s allies
- district: str | None¶
district where the contender’s candidature is registered or associated to
- name: str¶
contender’s name
- class interregnum.district.contenders.GroupBy(*values)¶
Bases:
FlagGrouping criterion for contenders transformation.
- classmethod parse(text, sep='+')¶
Parse GroupBy from string format.
Examples
alliance->ALLIANCEname+district->NAME|DISTRICT- Parameters:
text (str | None)
sep (str)
- Return type:
GroupBy | None
- __invert__()¶
- __str__()¶
Return string attribute representation.
- Return type:
str
- ALLIANCE = 2¶
keep the field alliance
- ALLIANCE_ID = 6¶
keep the fields alliance and district
- CANDIDATE = 7¶
keep all the fields
- DISTRICT = 4¶
get the field district
- ID = 3¶
keep the fields name and alliance
- NAME = 1¶
keep the field name
- interregnum.district.contenders.group_candidates(groupby, groups)¶
Merge candidates from district mapping using a name transformation.
If there is only one group, district is omitted.
- Parameters:
groupby (GroupBy)
groups (Mapping[str, Iterable[Candidate[ContenderId]]])
- Return type:
Generator[Candidate[ContenderId], None, None]
- interregnum.district.contenders.group_preferences(groups)¶
Transform preferences using groupby and district.
- Parameters:
groups (Sequence[tuple[GroupBy, str, Iterable[Preference[ContenderId]]]]) – (GroupBy, district, preferences)
- Return type:
Generator[Preference[ContenderId], None, None]
- interregnum.district.contenders.merge_candidates(contenders, groupby=None)¶
Merge candidates using a name transformation.
- Parameters:
contenders (Iterable[Candidate[ContenderId]])
groupby (GroupBy | None)
- Return type:
Generator[Candidate[ContenderId], None, None]
- interregnum.district.contenders.transform_preferences(preferences, by=<GroupBy.CANDIDATE: 7>, district=None)¶
Transform preferences by name and district.
- Parameters:
preferences (Iterable[Preference[ContenderId]])
by (GroupBy)
district (str | None)
- Return type:
Generator[Preference[ContenderId], None, None]
interregnum.district.counting module¶
Utilities related to counting votes.
- class interregnum.district.counting.Ballots(blank=0, void=0, ballots=None)¶
Bases:
objectA collection of ballots useful for counting total votes.
- Parameters:
blank (int | Fraction)
void (int | Fraction)
ballots (Sequence[Contender] | None)
- static build(candidates)¶
Build a collection from a list of contenders.
- contenders_seats()¶
Return seats won by contenders.
- Return type:
int
- contenders_votes()¶
Return the sum of votes given to contenders.
- Return type:
int | Fraction
- blank: int | Fraction¶
- void: int | Fraction¶
- class interregnum.district.counting.Counting(candidates=None, preferences=None, alliances=None)¶
Bases:
objectCollection candidates votes, preferences and alliances from a node.
- Parameters:
candidates (Ballots | None)
preferences (Sequence[Preference[ContenderId]] | None)
alliances (Sequence[Alliance] | None)
- get_bundle()¶
Return preferences if not empty, or candidates.
- Return type:
Ballots | Sequence[Preference[ContenderId]] | None
- seat_rules()¶
Compute seat restrictions for candidates and alliances.
Each item
(Max seats, [candidate 1, ..., candidate N])as a rule likeseats(candidate1) + ... + seats(candidateN) <= Max seats- Return type:
list[tuple[int, Sequence[ContenderId]]]
- preferences: Sequence[Preference[ContenderId]] | None¶
preferential ballots
- class interregnum.district.counting.InitialSeatsSource(*values)¶
Bases:
EnumOrigin for initial seats.
- classmethod parse(value)¶
Parse an InitialSeatsSource value from text.
- Parameters:
value (str | InitialSeatsSource)
- Return type:
- __str__()¶
Return value as text.
- Return type:
str
- MIN_SEATS = 1¶
Get initial seats from the contender’s min_seats field.
Alternative names:
MIN_SEAT
FROM_MIN_SEATS
FROM_MIN_SEAT
- RESULT = 2¶
Get initial seats from a node result.
Alternative names:
RESULTS
FROM_RESULT
FROM_RESULTS
- class interregnum.district.counting.TotalVotes(*values)¶
Bases:
EnumHow to compute total votes.
- classmethod parse(value)¶
Parse a TotalVotes value from text.
- Parameters:
value (str)
- Return type:
- __str__()¶
Return this value as string.
- Return type:
str
- ALL = 3¶
total_votes is the sum of every vote, valid or not
- CANDIDATES = 1¶
total votes is the sum of the votes given to any candidate
- VALID_VOTES = 2¶
total_votes is the sum of the votes considered as valid
- class interregnum.district.counting.Votes(candidates=0, blank=0, void=0)¶
Bases:
objectCount of votes by origin.
- Parameters:
candidates (int | Fraction)
blank (int | Fraction)
void (int | Fraction)
- all_votes()¶
Return the sum of valid votes and invalid votes.
- Return type:
int | Fraction
- usable_votes(usable)¶
Return usable votes given a criterion.
- Parameters:
usable (TotalVotes)
- Return type:
int | Fraction
- valid_votes()¶
Return the sum of candidates votes and blank votes.
- Return type:
int | Fraction
- blank: int | Fraction¶
blank votes
- candidates: int | Fraction¶
votes given to candidates
- void: int | Fraction¶
void/null votes
interregnum.district.district module¶
Basic district.
- class interregnum.district.district.BallotsNode(type, name=None, key=None, candidates=None, alliances=None, preferences=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
NodeA node with ballots.
- Parameters:
type (str)
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- local_alliances()¶
Return node alliances or None.
- Return type:
Sequence[Alliance] | ReferenceSet[GroupableReference] | None
- local_candidates()¶
Return node local candidates or None.
- Return type:
Ballots | ReferenceSet[GroupableReference] | None
- local_candidates_references()¶
Return references to local candidates defined elsewhere.
If no references but local candidates exist, return True
- Return type:
ReferenceSet[GroupableReference] | bool
- local_preferences(candidates)¶
Return node local preferential votes or None.
- Parameters:
candidates (Iterable[ContenderId])
- Return type:
Iterator[Preference[ContenderId]] | ReferenceSet[GroupableReference] | None
- local_preferences_references()¶
Return references to local preferences defined elsewhere.
If no references but local preferences exist, return True
- Return type:
ReferenceSet[GroupableReference] | bool
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- candidates: Sequence[Contender] | ReferenceSet[GroupableReference] | None = None¶
votes for candidates
- preferences: Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None = None¶
list of preferential ballots
- class interregnum.district.district.District(type='district', name=None, key=None, candidates=None, alliances=None, preferences=None, seats=None, party_seats=None, district_seats=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
BallotsNodeAn electoral district or constituency.
This node supports methods, candidates and preferences.
- Parameters:
type (Literal['district'])
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
seats (int | ReferenceSet[GroupableReference] | None)
party_seats (Node | ReferenceSet[GroupableReference] | None)
district_seats (Node | ReferenceSet[GroupableReference] | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return seats to allocate.
- Return type:
int | ReferenceSet[GroupableReference]
- grouping()¶
Return a grouping criterion for this node.
- Return type:
Literal[GroupBy.CANDIDATE]
- district_seats: Node | ReferenceSet[GroupableReference] | None = None¶
seats allocated by district (used by bi-proportional methods), extracted from a node result
- party_seats: Node | ReferenceSet[GroupableReference] | None = None¶
seats allocated by party (used by bi-proportional methods), extracted from a node result
- seats: int | ReferenceSet[GroupableReference] | None = None¶
number of seats to allocate (default = 1)
- type: Literal['district'] = 'district'¶
- class interregnum.district.district.Filters(context, node, key, lists=None)¶
Bases:
objectExclusion filters provider.
- Parameters:
context (AllocationContext)
node (NodeContext)
key (str)
lists (tuple[set[ContenderId], set[ContenderId]] | None)
- get_exclude_candidates()¶
Return the combination of exclusion and inclusion lists.
- Return type:
set[ContenderId]
- get_filter_f()¶
Return a candidate filter using the combination of exclusion and inclusion lists.
- Return type:
- context: AllocationContext¶
electoral system allocation context
- key: str¶
working node id
- lists: tuple[set[ContenderId], set[ContenderId]] | None¶
exlusion list and inclusion list
- node: NodeContext¶
working node local context
- interregnum.district.district.adapt_allocator(allocator, inputs, **kwargs)¶
Add adapters to allocator so that all inputs can be processed.
- interregnum.district.district.clean_inputs(method, inputs)¶
Clean superfluous inputs.
Max seats restrictions will be reduced to the subset of used candidates.
- Parameters:
method (Allocator[Any, Any])
inputs (InputDict[ContenderId, Event])
- Return type:
- interregnum.district.district.expand_nodes(node)¶
Iterate nodes or references.
- interregnum.district.district.from_biproportional_contender(contender)¶
Compose a contender id from party and district ids.
- Parameters:
contender (tuple[ContenderId, ContenderId])
- Return type:
- interregnum.district.district.get_candidates(district, by)¶
Return a reference for a district.
If district is already a reference, return as is. Otherwise, compose a groupable reference.
- Parameters:
district (Node | ReferenceSet[GroupableReference] | None)
by (GroupBy)
- Return type:
ReferenceSet[_Ref] | ReferenceSet[GroupableReference]
- interregnum.district.district.input_required(method, inputs, flag)¶
Return True if flag is required for method.
- Parameters:
method (Allocator[Any, Any])
inputs (InputDict[ContenderId, Event])
flag (Input)
- Return type:
bool
- interregnum.district.district.to_biproportional_contender(contender)¶
De-compose a contender in party and district ids.
- Parameters:
contender (ContenderId)
- Return type:
tuple[ContenderId, ContenderId]
- interregnum.district.district.to_district(contender)¶
Return a district identifier from a contender id.
- Parameters:
contender (ContenderId)
- Return type:
- interregnum.district.district.to_party(contender)¶
Return a party identifier from a contender id.
- Parameters:
contender (ContenderId)
- Return type:
- interregnum.district.district.unserialize_ballotsnode_dict(data, cwd)¶
Unserialize fields for a BallotsNode node.
- Parameters:
data (Mapping[str, Any])
cwd (Path | None)
- Return type:
dict[str, Any]
- interregnum.district.district.unserialize_district_dict(data, cwd)¶
Unserialize District fields.
- Parameters:
data (Mapping[str, Any])
cwd (Path | None)
- Return type:
dict[str, Any]
interregnum.district.group module¶
Group of electoral districts.
- class interregnum.district.group.Group(type='group', name=None, key=None, aggregate=False, groupby=None, divisions=<factory>, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
NodeA group of electoral districts.
- Parameters:
type (Literal['group'])
name (str | None)
key (str | None)
aggregate (bool)
groupby (GroupBy | None)
divisions (Sequence[Node])
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return 0 (no seats are associated to groups).
- Return type:
Literal[0]
- grouping()¶
Return a grouping criterion for this node (default:
GroupBy.CANDIDATE).- Return type:
- local_alliances()¶
Return node alliances or None.
- Return type:
Literal[None]
- local_candidates()¶
Return node local candidates or None.
- Return type:
Literal[None]
- local_candidates_references()¶
Return references to local candidates defined elsewhere.
If no references but local candidates exist, return True
- Return type:
Literal[False]
- local_preferences(candidates)¶
Return node local preferential votes or None.
- Parameters:
candidates (Iterable[ContenderId])
- Return type:
Literal[None]
- local_preferences_references()¶
Return references to local preferences defined elsewhere.
If no references but local preferences exist, return True
- Return type:
Literal[False]
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- aggregate: bool = False¶
if True, aggregate children results as this node result
- type: Literal['group'] = 'group'¶
- interregnum.district.group.unserialize_group_dict(data, cwd)¶
Serialize Group fields.
- Parameters:
data (Mapping[str, Any])
cwd (Path | None)
- Return type:
dict[str, Any]
interregnum.district.io module¶
Tools for reading ballots info.
- class interregnum.district.io.CandidatesFile(path, format, encoding='utf-8', cwd=None, type='candidates-file', sep=',')¶
Bases:
FileA file with candidates.
yaml, json: should be compatible with Contender
csv, tsv: the columns should be compatible with Contender’s properties
- Parameters:
path (Path)
format (str)
encoding (str)
cwd (Path | None)
type (Literal['candidates-file'])
sep (str)
- classmethod from_path(path, cwd, extension=None)¶
Create a CandidatesFile object from a path name.
- Parameters:
path (Path)
cwd (Path | None)
extension (str | None)
- Return type:
- __call__()¶
Return a list of contenders.
- Return type:
Generator[tuple[str | None, Contender], None, None]
- write_data(nodes)¶
Write data to this file.
- Parameters:
nodes (Iterable[tuple[str, Iterable[Candidate[ContenderId] | Contender]]])
- Return type:
None
- sep: str = ','¶
- type: Literal['candidates-file'] = 'candidates-file'¶
- class interregnum.district.io.File(path, format, encoding='utf-8', cwd=None)¶
Bases:
objectA resource file definition.
- Parameters:
path (Path)
format (str)
encoding (str)
cwd (Path | None)
- cwd: Path | None = None¶
working directory
- encoding: str = 'utf-8'¶
char encoding
- format: str¶
file format
- path: Path¶
file path
- class interregnum.district.io.PreferencesFile(path, format, encoding='utf-8', cwd=None, type='preferences-file')¶
Bases:
FileA file with preferences.
Formats:
pref
yaml: should be compatible with the preference converter
json: should be compatible with the preference converter
- Parameters:
path (Path)
format (str)
encoding (str)
cwd (Path | None)
type (Literal['preferences-file'])
- classmethod from_path(path, cwd, extension=None)¶
Create a PreferencesFile from a path.
- Parameters:
path (Path)
cwd (Path | None)
extension (str | None)
- Return type:
- __call__(converter)¶
Read file and convert candidates names using converter.
- Parameters:
converter (Callable[[str], ContenderId])
- Return type:
Generator[Preference[ContenderId], None, None]
- write_data(converter, preferences, contenders=None)¶
Write data to this file.
- Parameters:
converter (Callable[[ContenderId], str])
preferences (Iterable[Preference[ContenderId]])
contenders (Iterable[ContenderId] | None)
- Return type:
None
- type: Literal['preferences-file'] = 'preferences-file'¶
- interregnum.district.io.open_ro(path, *args, **kwargs)¶
Open a text file for reading.
If path is ‘-’, use stdin
- Parameters:
path (str | Path)
args (Any)
kwargs (Any)
- Return type:
Any
- interregnum.district.io.open_w(path, *args, **kwargs)¶
Open a file for writing.
If path is ‘-’, use stdout
- Parameters:
path (str | Path)
args (Any)
kwargs (Any)
- Return type:
Any
- interregnum.district.io.unserialize_file_object(data, path)¶
Unserialize File fields.
- Parameters:
data (Mapping[str, Any])
path (Path | None)
- Return type:
dict[str, Any]
- interregnum.district.io.unserialize_preferences_file(data, path)¶
Unserialize PreferencesFile fields.
- Parameters:
data (Mapping[str, Any])
path (Path | None)
- Return type:
interregnum.district.node module¶
Information for districts or constituencies.
- class interregnum.district.node.AllocationContext(root, keys, groups, cand_cache=<factory>, alli_cache=<factory>, stats=<factory>)¶
Bases:
objectAn electoral system allocation context.
It stores information needed to access all data required at each step.
- Parameters:
root (str)
keys (Mapping[str, NodeOffset])
groups (Mapping[str, set[str]])
cand_cache (dict[str, Ballots])
alli_cache (dict[str, Sequence[Alliance]])
- __call__()¶
Compute allocation for all nodes in the electoral system.
Since dependencies are computed using depth first search, the electoral system must be a directed acyclic graph.
- Return type:
None
- build_stats(targets, requires_results)¶
Compute statistics for nodes, candidates and alliances.
This statistics are required for computing restrictions.
- children(key)¶
Iterate key’s children node ids.
- Parameters:
key (str | Node)
- Return type:
Iterator[str]
- dependencies(key, restrictions=True)¶
Return keys for nodes that must have a result before this node.
- Parameters:
key (str | Node) – a node or a node id
restrictions (bool) – if True, include nodes referred in restrictions that need computed results.
- Return type:
frozenset[str]
- flatten_alliances(key)¶
Compute alliances for a node identified by key.
All references will be expanded, and alliances id will be transformed using the node names as districts.
- flatten_candidates(key)¶
Compute candidates for a node identified by key.
All references will be expanded, and candidates id will be transformed using the node names as districts.
- flatten_preferences(key)¶
Compute preferences for a node identified by key.
All references will be expanded, and preferences id will be transformed using the node names as districts.
Preferences are not cached because of memory consumption.
- Parameters:
key (str | Node)
- Return type:
list[Preference[ContenderId]] | None
- group_result(reference)¶
Merge results from the referred nodes.
Candidate-id transformations will be applied.
- Parameters:
reference (Iterable[Reference])
- Return type:
Sequence[Candidate[ContenderId]]
- nested_results(key)¶
Return ids from nodes with results, considering key as the root.
- Parameters:
key (str | Node)
- Return type:
list[str]
- references(references)¶
Iterate nodes referred by a list of references.
- resolve_seats(key)¶
Resolve referenced seats.
If the seats for a node depends on the result of other nodes, return the seats of the candidate with the same name as the node id. Otherwise return the node seats.
- Parameters:
key (str | Node)
- Return type:
int
- resolve_threshold(key, include=False)¶
Resolve restrictions for a node identified by key.
- Parameters:
include (bool) – return restrictions from include instead of exclude
key (str | Node)
- Return type:
set[ContenderId] | None
- groups: Mapping[str, set[str]]¶
translation of groups to sets of node ids
- keys: Mapping[str, NodeOffset]¶
mapping of node ids and node offsets
- root: str¶
root node id
- class interregnum.district.node.Node(type, name=None, key=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
NodeContextAn electoral node.
A node represents an allocation unit in an electoral system.
- Parameters:
type (str)
name (str | None)
key (str | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- build()¶
Build an allocation context.
- Return type:
- calculate()¶
Build an allocation context from this node and calculate.
- Return type:
None
- clear_data()¶
Clear results, ballots and meta.
- Return type:
None
- find_district(district_id)¶
Find a district by identifier and return a reference to it.
District(id) or None
- Parameters:
district_id (str)
- Return type:
Node | None
- find_level(level)¶
Iterate nodes at a given level from this node.
Positive levels will look levels from this node. Negative levels will look levels from a leaf node.
- Parameters:
level (int)
- Return type:
Iterator[Node]
- get_id()¶
Return a unique identifier for this node.
If a key is present, use it. Otherwise, use name or return a generated id.
- Return type:
str
- get_seats()¶
Return seats to allocate.
- Return type:
int | ReferenceSet[GroupableReference]
- ignore_compute_dependency()¶
Ignore these nodes when computing result.
- Return type:
Sequence[str] | None
- local_alliances()¶
Return node alliances or None.
- Return type:
Sequence[Alliance] | ReferenceSet[GroupableReference] | None
- local_candidates()¶
Return node local candidates or None.
- Return type:
Ballots | ReferenceSet[GroupableReference] | None
- local_candidates_references()¶
Return references to local candidates defined elsewhere.
If no references but local candidates exist, return True
- Return type:
ReferenceSet[GroupableReference] | bool
- local_preferences(candidates)¶
Return node local preferential votes or None.
- Parameters:
candidates (Iterable[ContenderId])
- Return type:
Iterator[Preference[ContenderId]] | ReferenceSet[GroupableReference] | None
- local_preferences_references()¶
Return references to local preferences defined elsewhere.
If no references but local preferences exist, return True
- Return type:
ReferenceSet[GroupableReference] | bool
- transform_contender(contender)¶
Transform contender using the district mapping.
- transform_contender_id(contender_id)¶
Transform contender_id using the district mapping.
- Parameters:
contender_id (ContenderId)
- Return type:
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- groups: Sequence[str] | None = None¶
tags useful for finding node groups
- ignore: Sequence[str] | None = None¶
ignore these node when computing dependencies on results
- key: str | None = None¶
human readable node name (must be unique)
- map_districts: Mapping[str | None, str | None] | None = None¶
map for changing district names when collecting candidates
- max_adjustment_seats: int | None = None¶
maximum number of additional seats this node can win in systems with adjustment seats (such as levelling seats or mixed-member systems)
- meta: dict[str, Any] | None = None¶
additional data
- name: str | None = None¶
type of node
- result: Result[ContenderId, Any] | None = None¶
allocation result
- type: str¶
- class interregnum.district.node.NodeContext(*, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None)¶
Bases:
objectInherited node context.
Set of attributes inherited from parent context.
If a node defines any of these attribute, the own node attribute is used. Otherwise, the inherited value for the attribute from parents is used.
- Parameters:
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
- static unserialize_dict(**data)¶
Unserialize a node context attributes from arguments.
- Parameters:
data (Any)
- Return type:
dict[str, Any]
- get_method()¶
Resolve method and return an allocator factory.
- Return type:
Callable[[], Allocator[ContenderId, Any]] | None
- merge_context(parent)¶
Merge this context with the parent context.
Local values will take precedence, and it will use the parent value as a fallback value.
- Parameters:
parent (NodeContext)
- Return type:
- exclude: RestrictionList | None = None¶
rules for excluding contenders from allocation
- include: RestrictionList | None = None¶
rules for including contenders in allocation (even if the contender is present in the exclusion list)
- initial_seats: int | InitialSeatsSource = 1¶
how to calculate total votes
- method: str | Callable[[...], Allocator[ContenderId, Any]] | None = None¶
allocation method
- method_params: dict[str, Any] | None = None¶
arguments for the allocation method (only used if method is defined in the same node)
- random_seed: int | None = None¶
random number generator seed passed to allocators
- resume_allocation: bool | None = None¶
resume allocation from the initial seats
- skip_initial_seats: bool | None = None¶
add initial seats to result
- total_votes: TotalVotes | None = None¶
how to calculate total votes
- class interregnum.district.node.NodeOffset(key, level, reverse_level, context, node)¶
Bases:
objectLocation offset of a node from the root tree.
- Parameters:
key (str)
level (int)
reverse_level (int)
context (NodeContext)
node (Node)
- classmethod walk(node, parent_level=-1)¶
Walk nodes from node.
- Parameters:
parent_level (int) – parent’s computed root offset
node (Node)
- Return type:
Generator[NodeOffset, None, None]
- context: NodeContext¶
computed node context
- key: str¶
node key
- level: int¶
positive offset from the root
- reverse_level: int¶
negative offset from the leaf
- interregnum.district.node.MethodDef¶
a method definition
alias of
str|Callable[[…],Allocator[ContenderId,Any]]
interregnum.district.reapportionment module¶
Re-apportionment from one node to others.
References¶
- exception interregnum.district.reapportionment.ParallelReapportionmentError¶
Bases:
PreconditionErrorRaised when the parallel strategy can’t be used.
- class interregnum.district.reapportionment.CompositeResultData(log=<factory>, steps=None)¶
Bases:
EventLogA result that stores several allocation steps.
- Parameters:
log (list[Event])
steps (list[Result[ContenderId, Any]] | None)
- steps: list[Result[ContenderId, Any]] | None = None¶
result for each allocation step
- class interregnum.district.reapportionment.Reapportionment(type='reapportionment', name=None, key=None, candidates=None, alliances=None, preferences=None, strategy=<GroupBy.DISTRICT: 4>, relative=None, adjustment=None, first_vote=None, *, total_votes=None, resume_allocation=None, skip_initial_seats=None, exclude=None, include=None, initial_seats=InitialSeatsSource.MIN_SEATS, method=None, method_params=None, random_seed=None, groups=None, result=None, max_adjustment_seats=None, ignore=None, map_districts=None, meta=None)¶
Bases:
BallotsNodeRe-apportionment system.
Use to project adjustment seats allocated by compensatory systems to final districts which already have initial seats, using the votes provided by the field candidates.
Negative levelling seats are supported.
See [Denmark:2011], [Iceland:2013], [Norway:2023], [Germany:2025].
- Parameters:
type (Literal['reapportionment'])
name (str | None)
key (str | None)
candidates (Sequence[Contender] | ReferenceSet[GroupableReference] | None)
alliances (Sequence[Alliance] | None)
preferences (Sequence[Preference[str]] | Callable[[Callable[[str], ContenderId]], Iterator[Preference[ContenderId]]] | ReferenceSet[GroupableReference] | None)
strategy (Literal['parallel'] | ~interregnum.district.contenders.GroupBy)
relative (RelativeDivisor | None)
adjustment (Node | ReferenceSet[GroupableReference] | None)
first_vote (Node | ReferenceSet[GroupableReference] | None)
total_votes (TotalVotes | None)
resume_allocation (bool | None)
skip_initial_seats (bool | None)
exclude (RestrictionList | None)
include (RestrictionList | None)
initial_seats (int | InitialSeatsSource)
method (str | Callable[[...], Allocator[ContenderId, Any]] | None)
method_params (dict[str, Any] | None)
random_seed (int | None)
groups (Sequence[str] | None)
result (Result[ContenderId, Any] | None)
max_adjustment_seats (int | None)
ignore (Sequence[str] | None)
map_districts (Mapping[str | None, str | None] | None)
meta (dict[str, Any] | None)
- __call__(context, local_context)¶
Compute allocation for this tree given a context.
- Parameters:
context (AllocationContext)
local_context (NodeContext)
- Return type:
None
- get_seats()¶
Return seats to allocate.
- Return type:
Literal[0]
- grouping()¶
Return a grouping criterion for this node.
- Return type:
Literal[GroupBy.CANDIDATE]
- update_candidates(candidates)¶
Set these candidates as local candidates.
- Parameters:
candidates (Sequence[Contender])
- Return type:
None
- adjustment: Node | ReferenceSet[GroupableReference] | None = None¶
adjustment seats that will be projected to the new districts
- first_vote: Node | ReferenceSet[GroupableReference] | None = None¶
districts where the seats will be projected
- relative: RelativeDivisor | None = None¶
reference numbers (score used as votes for the allocation):
None: use absolute votes for party and district
RelativeDivisor: make a relative score using this divisor
- strategy: Literal['parallel'] | GroupBy = 4¶
how to split allocations:
- parallel ([Iceland:2013]) will allocate each compensatory seat in
the order it was won (requires a method that produces
WinnerEventfor each seat)
GroupBy: split the allocations by the given criterion (for example,party names or districts)
- type: Literal['reapportionment'] = 'reapportionment'¶
- class interregnum.district.reapportionment.ReapportionmentState(candidates, adjustment_seats=<factory>, initial_seats=<factory>, district_map=<factory>, rules=<factory>, excluded=<factory>)¶
Bases:
objectInternal state for reapportionment node.
- Parameters:
candidates (list[Candidate[ContenderId]])
adjustment_seats (dict[ContenderId, int])
initial_seats (dict[ContenderId, int])
district_map (dict[str | None, str | None])
rules (list[tuple[int, Sequence[ContenderId]]])
excluded (set[ContenderId])
- add_district_constraints(context)¶
Add constraints for districts that do no allow undetermined adjustment seats.
- Parameters:
context (AllocationContext)
- Return type:
None
- add_party_constraints()¶
Add constraints for parties based on the number of adjustment seats.
- Return type:
None
- clean_candidates()¶
Remove candidates not present in adjustment_seats.
- Return type:
None
- compute_relative_score(context, relative, total_votes)¶
Compute relative score (reference number) using a divisor (votes, quota).
- Parameters:
context (AllocationContext)
relative (RelativeDivisor)
total_votes (TotalVotes | None)
- Return type:
None
- pair_districts(context)¶
Map districts from the compensatory system to the destination districts.
- Parameters:
context (AllocationContext)
- Return type:
None
- adjustment_seats: dict[ContenderId, int]¶
- candidates: list[Candidate[ContenderId]]¶
- district_map: dict[str | None, str | None]¶
- excluded: set[ContenderId]¶
- initial_seats: dict[ContenderId, int]¶
- rules: list[tuple[int, Sequence[ContenderId]]]¶
- class interregnum.district.reapportionment.RelativeDivisor(*values)¶
Bases:
EnumDivisor that will be used as a divisor for party/district score.
- classmethod parse(value)¶
Parse from string format.
- Parameters:
value (str)
- Return type:
- __str__()¶
Return a formatted string.
- Return type:
str
- QUOTA = 2¶
use district votes quota
Norway ([Norway:2023]): votes / (constituency votes / number of constituency seats)
- VOTES = 1¶
Use district votes.
Iceland ([Iceland:2013]): votes / constituency votes
- interregnum.district.reapportionment.check_event_log(data)¶
Ensure that a result data is an instance of EventLog.
- Parameters:
data (Any)
- Return type:
- interregnum.district.reapportionment.unserialize_reapportionment_dict(data, cwd)¶
Unserialize Reapportionment fields.
- Parameters:
data (Mapping[str, Any])
cwd (Path | None)
- Return type:
dict[str, Any]
interregnum.district.references module¶
References to nodes.
- class interregnum.district.references.GroupableReference(ref=None, level=None, groupby=<GroupBy.CANDIDATE: 7>)¶
Bases:
ReferenceA reference with an associated grouping criterion.
- Parameters:
ref (str | None)
level (int | None)
groupby (GroupBy)
- classmethod parse(text)¶
Iterate groupable references separated by
|in text.- Parameters:
text (str) – a references expression
- Raises:
ValueError – when text could not be parsed
- Return type:
Generator[GroupableReference, None, None]
- classmethod parse_item(text)¶
Parse a groupable reference from text.
- Parameters:
text (str) –
reference expression with the following format:
- Raises:
ValueError – when text could not be parsed
- Return type:
GroupableReference | None
Examples
Get candidates from leaf nodes in Calabria and transform them to get only their alliance id.
alliance[Calabria:-1]
Get candidates identified by name and district from constituencies.
name+district[#constituencies]
Get candidates from constituencies without any transformation.
#constituencies
- __str__()¶
Return a groupable reference in string format.
- Return type:
str
- class interregnum.district.references.Reference(ref=None, level=None)¶
Bases:
objectA reference to a node or a set of nodes.
Examples
Point to node ‘Cádiz’:
>>> Reference("Cádiz")
Use ‘Andalucía’ as reference, and get its direct child nodes:
>>> Reference("Andalucía", 1)
Use ‘Andalucía’ as reference, and get its leaf nodes:
>>> Reference("Andalucía", -1)
Point to any node in the group ‘constituency’:
>>> Reference("#constituency")
- Parameters:
ref (str | None)
level (int | None)
- classmethod parse(text)¶
Iterate references separated by
|in text.- Parameters:
text (str) – text references expression: references parseables by
parse_reference()separated by|.- Return type:
Generator[Reference, None, None]
Examples
Input examples:
node node:<level> #group #group:<level> node:<level>|#group:<level>
- classmethod parse_one(text)¶
Parse one reference from text.
- Parameters:
text (str) – references expression: references parseables by
parse_reference()separated by|.- Return type:
Examples
Input examples:
node node:<level> #group #group:<level> node:<level>|#group:<level>
- Raises:
ValueError – when text could not be parsed
- Parameters:
text (str)
- Return type:
- __str__()¶
Return as a formatted string.
- Return type:
str
- ref: str | None = None¶
Node or group of nodes
- class interregnum.district.references.ReferenceSet(references=<factory>)¶
Bases:
Generic[_Ref]An iterable reference set.
- Parameters:
references (Sequence[_Ref])
- __str__()¶
Return the reference set as a text expression.
- Return type:
str
- references: Sequence[_Ref]¶
list of references
- interregnum.district.references.parse_reference(text)¶
Parse a single reference from text.
- Parameters:
text (str) –
A text reference expression, following the format:
<node> #<group> <node>:<level> #<group>:<level>
Where
<node>is a node id,<group>is a group tag, and<level>is the offset from the level of<node>or<group>. Level can be positive (counting from start) or negative (counting from leaves).- Returns:
(
<node>or<group>,<level>)- Return type:
tuple[str | None, int | None]
- interregnum.district.references.unserialize_groupable_reference(node)¶
Unserialize a groupable reference set from a string or a mapping.
- Parameters:
node (dict[str, Any] | str)
- Return type:
- interregnum.district.references.unserialize_reference(node)¶
Unserialize a reference set from a string or a mapping.
- Parameters:
node (list[dict[str, Any]] | dict[str, Any] | str)
- Return type:
interregnum.district.restriction module¶
Restrictions to rule the inclusion or exclusion of candidates.
- class interregnum.district.restriction.Attribute(*values)¶
Bases:
FlagRestriction attribute.
Candidates and alliances can be compare against these attributes.
- __invert__()¶
- __str__()¶
Return string representation.
- Return type:
str
- requires_results()¶
Return True if this attribute depends on results.
- Return type:
bool
- ALLIANCE_ = 4¶
- ALLIANCE_DISTRICTS = 517¶
- Criterion
number of districts where the alliance contends
- Total
number of districts
- ALLIANCE_GROUP = 4101¶
- Criterion
the alliance contains the group tag
- Total
not applicable
- ALLIANCE_QUORUM = 1030¶
- Criterion
alliance quorum (number of districts where the alliance won seats)
- Total
number of districts
- ALLIANCE_RANK = 2053¶
- Criterion
alliance rank in order of votes
- Total
not applicable
- ALLIANCE_SEATS = 262¶
- Criterion
alliance seats
- Total
the sum of alliance seats
- ALLIANCE_TOTAL_VOTES = 149¶
- Criterion
alliance votes
- Total
the sum of alliance votes, blank votes and void votes
- ALLIANCE_VALID_VOTES = 85¶
- Criterion
alliance votes
- Total
the sum of alliance votes and blank votes
- ALLIANCE_VOTES = 53¶
- Criterion
alliance votes
- Total
the sum of alliance votes
- CANDIDATE_ = 8¶
- COUNTING_ = 1¶
- DISTRICTS = 521¶
- Criterion
number of districts where the party contends
- Total
number of districts
- DISTRICTS_ = 512¶
- GROUP = 4105¶
- Criterion
the party contains the group tag
- Total
not applicable
- GROUP_ = 4096¶
- QUORUM = 1034¶
- Criterion
party quorum (number of districts where the party won seats)
- Total
number of districts
- QUORUM_ = 1024¶
- RANK = 2057¶
- Criterion
party rank in order of votes
- Total
not applicable
- RANK_ = 2048¶
- RESULTS_ = 2¶
- SEATS = 266¶
- Criterion
party seats
- Total
the sum of party seats
- SEATS_ = 256¶
- TOTAL_VOTES = 153¶
- Criterion
party votes
- Total
the sum of party votes, blank votes and void votes
- TOTAL_VOTES_ = 128¶
- VALID_VOTES = 89¶
- Criterion
party votes
- Total
the sum of party votes and blank votes
- VALID_VOTES_ = 64¶
- VOTES = 57¶
- Criterion
party votes
- Total
the sum of party votes
- VOTES_ = 32¶
- VOTES_ANY_ = 16¶
- class interregnum.district.restriction.ContenderStats(votes=0, seats=0, districts=<factory>, quorum=<factory>, rank=0, tags=<factory>)¶
Bases:
objectStatistics for contenders used when applying restrictions.
- Parameters:
votes (int | Fraction)
seats (int)
districts (set[str])
quorum (set[str])
rank (int)
tags (set[str])
- value(attribute)¶
Return the value associated to the attribute.
- Raises:
ValueError – if the attribute has no numeric value associated to it
- Parameters:
attribute (Attribute)
- Return type:
int | Fraction
- districts: set[str]¶
districts where the contender appears
- quorum: set[str]¶
districts where the contender won at least one seat
- rank: int¶
contender rank in order of seats won
- seats: int¶
seats won by the contender
- tags: set[str]¶
tags or groups associated to the contender
- votes: int | Fraction¶
contender votes
- class interregnum.district.restriction.NodeStats(candidates_votes=0, valid_votes=0, total_votes=0, seats=0, districts=<factory>, candidates=<factory>, alliances=<factory>)¶
Bases:
objectStatistics for nodes used when applying restrictions.
- Parameters:
candidates_votes (int | Fraction)
valid_votes (int | Fraction)
total_votes (int | Fraction)
seats (int | Fraction)
districts (set[str])
candidates (dict[ContenderId, ContenderStats])
alliances (dict[str, ContenderStats])
- usable_votes(usable)¶
Return usable votes given a criterion.
- Parameters:
usable (TotalVotes) – criterion of inclusion (valid, invalid, etc…)
- Return type:
int | Fraction
- alliances: dict[str, ContenderStats]¶
alliances statistics
- candidates: dict[ContenderId, ContenderStats]¶
candidates statistics
- candidates_votes: int | Fraction¶
total votes associated to any candidate
- districts: set[str]¶
districts associated to candidates
- seats: int | Fraction¶
total seats allocated by the node
- total_votes: int | Fraction¶
total votes, including invalid or null votes
- valid_votes: int | Fraction¶
total valid votes (associated to any candidate or not)
- class interregnum.district.restriction.Restriction(inequality, threshold, percentage, target, attribute, groupby=<GroupBy.CANDIDATE: 7>, tag=None)¶
Bases:
objectA non-composite restriction definition.
String format¶
<attribute><opt><threshold> <attribute><opt><threshold>% <attribute><opt><threshold> => <groupby> <attribute><opt><threshold>% => <groupby> <target>.<attribute><opt><threshold> <target>.<attribute><opt><threshold>% <target>.<attribute><opt><threshold> => <groupby> <target>.<attribute><opt><threshold>% => <groupby>
Where:
<attribute>an
Attributevalue as string (lower or upper-cased)<opt>an operator (see
Inequality)<threshold>a numeric threshold (it can be a percentage if the attribute supports total), or a string if the attribute is group or alliance_group
<target>a
Referenceto the nodeset where the restriction is to be computed<groupby>a transformation expression applied to filtered candidates (see
GroupBy)
Examples
Get candidates with at least 5% of the total votes:
valid_votes>=5%
Get candidates who won more than 2 seats at Paris district and transform their names removing the district name:
Paris.alliance_seats>2 => id
Get candidates within the group ‘minority’:
group=minority
- __str__()¶
Return the restriction formatted as as string.
- Return type:
str
- check_any(target, ref, attribute)¶
Check if this restriction depends on target and attribute.
If the restriction has no target, use ref instead.
- dependencies()¶
Iterate over dependencies on targets and attributes.
- resolve(context)¶
Resolve this restriction for a context and return the compliant contenders.
- Parameters:
context (Mapping[Reference | None, NodeStats]) – A context composed of statistics computed for nodes. It should contain stats for each possible node.
- Raises:
ValueError – When the operator does not support the threshold or when the attribute could not be resolved for the context
- Returns:
The set of filtered contenders ids
- Return type:
set[ContenderId]
- walk()¶
Yield this restriction.
- Yields:
self
- Return type:
Iterator[Restriction]
- inequality: Inequality¶
(in)equality operator
- percentage: bool¶
treat values as percentages
- tag: str | None¶
check that the candidate is associated to this tag instead of doing a numerical comparison
- threshold: Decimal¶
reference value for the inequality
- Parameters:
inequality (Inequality)
threshold (Decimal)
percentage (bool)
target (Reference | None)
attribute (Attribute)
groupby (GroupBy)
tag (str | None)
- class interregnum.district.restriction.RestrictionList(items, disjunctive=False)¶
Bases:
objectA set of conjunctive or disjunctive restriction clauses.
String formats¶
conjunctive: get every candidate returned by any of these restrictions
any{<restriction 1>|...|<restriction N>}disjunctive: get candidates if they are returned by all of these restrictions
all{<restriction 1>|...!<restriction N>}
- __str__()¶
Return the restrictions list formatted as as string.
- Return type:
str
- check_any(target, ref, attribute)¶
Check if this restriction depends on target and attribute.
If the restriction has no target, use ref instead.
- dependencies()¶
Iterate dependencies on nodes and attributes.
- resolve(context)¶
Resolve this restriction for a context and return the compliant contenders.
- Parameters:
context (Mapping[Reference | None, NodeStats]) – A context composed of statistics computed for nodes. It should contain stats for each possible node.
- Raises:
ValueError – When the operator does not support the threshold or when the attribute could not be resolved for the context
- Returns:
The set of filtered contenders ids
- Return type:
set[ContenderId]
- walk()¶
Recursively iterate all restrictions in this list.
- Return type:
Iterator[Restriction]
- disjunctive: bool¶
True for disjunctive, False for conjunctive
- items: list[Restriction | RestrictionList]¶
list of restrictions
- Parameters:
items (list[Restriction | RestrictionList])
disjunctive (bool)
- interregnum.district.restriction.parse_restrictions(text)¶
Parse restrictions from string expressions.
- Parameters:
text (str)
- Return type:
interregnum.district.serialize module¶
Serialization tools.
- interregnum.district.serialize.fill_node_candidates(node, data)¶
Populate nodes with lists of candidates read from file.
- Parameters:
node (Node) – root node
data (CandidatesFile)
- Return type:
None
- interregnum.district.serialize.serialize_fraction(obj, decimals)¶
Serialize fraction as a string or an integer.
- Parameters:
obj (Fraction) – a
Fractiondecimals (int | None) – number of decimals obj will be rounded to
- Return type:
str | int
- interregnum.district.serialize.serialize_to_str(obj)¶
Serialize anything to a string.
- Parameters:
obj (Any)
- Return type:
str
- interregnum.district.serialize.serializer(*object_types)¶
Register a function as a serializer (decorator).
- Parameters:
object_types (type)
- Return type:
Callable[[Callable[[_Arg], _Ret]], Callable[[_Arg], _Ret]]
- interregnum.district.serialize.to_serializable(data, decimals)¶
Serialize objects.
- Parameters:
decimals (int | None) – rounding precision
data (Any)
- Return type:
Any
- interregnum.district.serialize.unserialize_dict(kwargs, cwd)¶
Unserialize node fields from a mapping.
- Parameters:
cwd (Path | None) – working directory for opening files
kwargs (Mapping[str, Any])
- Return type:
dict[str, Any]
- interregnum.district.serialize.unserialize_node(data: Mapping[str, Any] | str, cwd: Path | None, groupby: Literal[False] = False) Node | ReferenceSet[Reference]¶
- interregnum.district.serialize.unserialize_node(data: Mapping[str, Any] | str, cwd: Path | None, groupby: Literal[True]) Node | ReferenceSet[GroupableReference]
Convert a mapping to a node.
The field
fill_candidateswill be interpreted as aCandidatesFileand rows will be injected to nodes.- Parameters:
data (Mapping[str, Any] | str) – source data: if data is a string instead of a mapping, a reference will be returned
cwd (Path | None) – working directory. Used by file readers.
groupby (bool) – use
GroupableReferenceinstead ofReference
- Return type:
Node | ReferenceSet[Reference] | ReferenceSet[GroupableReference]
- interregnum.district.serialize.unserializer(key, factory)¶
Register node unserializers.
Used as a decorator.
- Parameters:
key (str) – node type
factory (Callable[[...], Node]) – factory function for creating that type of node
- Return type:
Callable[[Callable[[Mapping[str, Any], Path | None], dict[str, Any]]], Callable[[Mapping[str, Any], Path | None], dict[str, Any]]]