Source code for swissvotes.models.policy_area

from decimal import Decimal
from functools import cached_property
from markupsafe import Markup
from onegov.swissvotes import _

from typing import overload
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from onegov.swissvotes.request import SwissvotesRequest


[docs] class PolicyArea: """ Helper class for handling of descriptors. There are three levels of descriptors, each new level refining the given category. Policy areas are internally represented as a string value containing the descriptor of all three levels separated by a comma, e.g. "1.12.121". Policy areas are stored in the dataset as float, with the pre-decimal part refering to the first level category and the decimal part to the category of the given level. For example: Level 1 descriptor "1": 1 Level 2 descriptor "1.12": 1.12 Level 3 descriptor "1.12.121": 1.121 """ @overload def __init__(self, value: str | list[int]) -> None: ... @overload def __init__(self, value: Decimal, level: int) -> None: ... def __init__( self, value: str | list[int] | Decimal, level: int | None = None ) -> None: """ Creates a new policy descriptor out of the given value. The given value might be a string (such as "1.12" or "1.12.121"), a list (such as [1, 12] or [1, 12, 121]) or a float together with a level (such as 1.12/2 or 1.121/3). """ if isinstance(value, str): self.value = value elif isinstance(value, list): self.value = '.'.join(str(x) for x in value) elif isinstance(value, Decimal): assert level is not None self.value = '.'.join( str(int(value * 10 ** x)) for x in range(level) ) else: raise NotImplementedError()
[docs] def __repr__(self) -> str: return self.value
[docs] def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.value == other.value
@cached_property
[docs] def level(self) -> int: return self.value.count('.') + 1
@cached_property
[docs] def descriptor(self) -> int: """ Returns the highest descriptor, e.g. 121 if "1.12.121". """ return int(self.value.rsplit('.', 1)[-1])
@cached_property
[docs] def descriptor_path(self) -> list[int]: """ Returns all descriptors, e.g [1, 12, 121] if "1.12.121". """ return [int(part) for part in self.value.split('.')]
@cached_property
[docs] def descriptor_decimal(self) -> Decimal: """ Returns the descriptor as float for the dataset, e.g 1.121 if "1.12.121". """ return Decimal(self.descriptor) / (10 ** (self.level - 1))
@cached_property
[docs] def label(self) -> str: """ Returns a translatable label of the highest descriptor, e.g. "Bundesverfassung" if "1.12.121". """ return self.label_path[-1]
@cached_property
[docs] def label_path(self) -> list[str]: """ Returns translatable labels for all descriptor levels, e.g. ["Staatsordnung", "Politisches System", "Bundesverfassung"] if "1.12.121". """ result = [] lookup: PolicyAreaDefinition | None lookup = PolicyAreaDefinition.all() for part in self.descriptor_path: lookup = lookup.get(part) if not lookup: result.append(str(self.descriptor_decimal)) break result.append(lookup.label or str(self.descriptor)) return result
[docs] def html(self, request: 'SwissvotesRequest') -> Markup: title = Markup(' &gt; ').join( request.translate(part) for part in self.label_path ) return Markup('<span>{}</span>').format(title)
[docs] class PolicyAreaDefinition: """ Helper class for all the policy areas and their translatable labels. Example: Get the label of the policy area "1.12.121": PolicyAreaDefinition.all().get(1).get(12).get(121).label """ def __init__( self, path: list[int] | None = None, label: str | None = None, children: list['PolicyAreaDefinition'] | None = None ) -> None:
[docs] self.path = path or []
[docs] self.decimal = None
[docs] self.value = path[-1] if path else None
[docs] self.label = label
[docs] self.children = children or []
[docs] self.index = { child.value: index for index, child in enumerate(self.children) }
[docs] def get(self, key: int) -> 'PolicyAreaDefinition | None': """ Returns the child with the given value. """ if key in self.index: return self.children[self.index[key]] return None
@staticmethod
[docs] def all() -> 'PolicyAreaDefinition': """ Returns the tree of all policy areas. """ return PolicyAreaDefinition(children=[ PolicyAreaDefinition([1], _('d-1-1'), [ PolicyAreaDefinition([1, 11], _('d-2-11')), PolicyAreaDefinition([1, 12], _('d-2-12'), [ PolicyAreaDefinition([1, 12, 121], _('d-3-121')), PolicyAreaDefinition([1, 12, 122], _('d-3-122')), PolicyAreaDefinition([1, 12, 123], _('d-3-123')), PolicyAreaDefinition([1, 12, 124], _('d-3-124')), ]), PolicyAreaDefinition([1, 13], _('d-2-13'), [ PolicyAreaDefinition([1, 13, 131], _('d-3-131')), PolicyAreaDefinition([1, 13, 132], _('d-3-132')), PolicyAreaDefinition([1, 13, 133], _('d-3-133')), PolicyAreaDefinition([1, 13, 134], _('d-3-134')), ]), PolicyAreaDefinition([1, 14], _('d-2-14'), [ PolicyAreaDefinition([1, 14, 141], _('d-3-141')), PolicyAreaDefinition([1, 14, 142], _('d-3-142')), PolicyAreaDefinition([1, 14, 143], _('d-3-143')), ]), PolicyAreaDefinition([1, 15], _('d-2-15'), [ PolicyAreaDefinition([1, 15, 151], _('d-3-151')), PolicyAreaDefinition([1, 15, 152], _('d-3-152')), PolicyAreaDefinition([1, 15, 153], _('d-3-153')), ]), PolicyAreaDefinition([1, 16], _('d-2-16'), [ PolicyAreaDefinition([1, 16, 161], _('d-3-161')), PolicyAreaDefinition([1, 16, 162], _('d-3-162')), PolicyAreaDefinition([1, 16, 163], _('d-3-163')), PolicyAreaDefinition([1, 16, 164], _('d-3-164')), PolicyAreaDefinition([1, 16, 165], _('d-3-165')), PolicyAreaDefinition([1, 16, 166], _('d-3-166')), ]) ]), PolicyAreaDefinition([2], _('d-1-2'), [ PolicyAreaDefinition([2, 21], _('d-2-21'), [ PolicyAreaDefinition([2, 21, 211], _('d-3-211')), PolicyAreaDefinition([2, 21, 212], _('d-3-212')), PolicyAreaDefinition([2, 21, 213], _('d-3-213')), ]), PolicyAreaDefinition([2, 22], _('d-2-22'), [ PolicyAreaDefinition([2, 22, 221], _('d-3-221')), PolicyAreaDefinition([2, 22, 222], _('d-3-222')), PolicyAreaDefinition([2, 22, 223], _('d-3-223')), PolicyAreaDefinition([2, 22, 224], _('d-3-224')), ]), PolicyAreaDefinition([2, 23], _('d-2-23'), [ PolicyAreaDefinition([2, 23, 231], _('d-3-231')), PolicyAreaDefinition([2, 23, 232], _('d-3-232')), ]), PolicyAreaDefinition([2, 24], _('d-2-24')), PolicyAreaDefinition([2, 25], _('d-2-25')), PolicyAreaDefinition([2, 26], _('d-2-26'), [ PolicyAreaDefinition([2, 26, 261], _('d-3-261')), PolicyAreaDefinition([2, 26, 262], _('d-3-262')), ]), PolicyAreaDefinition([2, 27], _('d-2-27')), PolicyAreaDefinition([2, 28], _('d-2-28')), ]), PolicyAreaDefinition([3], _('d-1-3'), [ PolicyAreaDefinition([3, 31], _('d-2-31'), [ PolicyAreaDefinition([3, 31, 311], _('d-3-311')), PolicyAreaDefinition([3, 31, 312], _('d-3-312')), PolicyAreaDefinition([3, 31, 313], _('d-3-313')), ]), PolicyAreaDefinition([3, 32], _('d-2-32'), [ PolicyAreaDefinition([3, 32, 321], _('d-3-321')), PolicyAreaDefinition([3, 32, 322], _('d-3-322')), PolicyAreaDefinition([3, 32, 323], _('d-3-323')), PolicyAreaDefinition([3, 32, 324], _('d-3-324')), PolicyAreaDefinition([3, 32, 325], _('d-3-325')), PolicyAreaDefinition([3, 32, 326], _('d-3-326')), PolicyAreaDefinition([3, 32, 327], _('d-3-327')), PolicyAreaDefinition([3, 32, 328], _('d-3-328')), ]), PolicyAreaDefinition([3, 33], _('d-2-33')), ]), PolicyAreaDefinition([4], _('d-1-4'), [ PolicyAreaDefinition([4, 41], _('d-2-41'), [ PolicyAreaDefinition([4, 41, 411], _('d-3-411')), PolicyAreaDefinition([4, 41, 412], _('d-3-412')), PolicyAreaDefinition([4, 41, 413], _('d-3-413')), PolicyAreaDefinition([4, 41, 414], _('d-3-414')), PolicyAreaDefinition([4, 41, 415], _('d-3-415')), PolicyAreaDefinition([4, 41, 416], _('d-3-416')), ]), PolicyAreaDefinition([4, 42], _('d-2-42'), [ PolicyAreaDefinition([4, 42, 421], _('d-3-421')), PolicyAreaDefinition([4, 42, 422], _('d-3-422')), PolicyAreaDefinition([4, 42, 423], _('d-3-423')), PolicyAreaDefinition([4, 42, 424], _('d-3-424')), ]), PolicyAreaDefinition([4, 43], _('d-2-43'), [ PolicyAreaDefinition([4, 43, 431], _('d-3-431')), PolicyAreaDefinition([4, 43, 432], _('d-3-432')), ]), PolicyAreaDefinition([4, 44], _('d-2-44'), [ PolicyAreaDefinition([4, 44, 441], _('d-3-441')), PolicyAreaDefinition([4, 44, 442], _('d-3-442')), PolicyAreaDefinition([4, 44, 443], _('d-3-443')), ]), ]), PolicyAreaDefinition([5], _('d-1-5'), [ PolicyAreaDefinition([5, 51], _('d-2-51')), PolicyAreaDefinition([5, 52], _('d-2-52')), PolicyAreaDefinition([5, 53], _('d-2-53')), PolicyAreaDefinition([5, 54], _('d-2-54')), PolicyAreaDefinition([5, 55], _('d-2-55')), ]), PolicyAreaDefinition([6], _('d-1-6'), [ PolicyAreaDefinition([6, 61], _('d-2-61'), [ PolicyAreaDefinition([6, 61, 611], _('d-3-611')), PolicyAreaDefinition([6, 61, 612], _('d-3-612')), PolicyAreaDefinition([6, 61, 613], _('d-3-613')), PolicyAreaDefinition([6, 61, 614], _('d-3-614')), ]), PolicyAreaDefinition([6, 62], _('d-2-62')), PolicyAreaDefinition([6, 63], _('d-2-63')), PolicyAreaDefinition([6, 64], _('d-2-64')), ]), PolicyAreaDefinition([7], _('d-1-7'), [ PolicyAreaDefinition([7, 71], _('d-2-71')), PolicyAreaDefinition([7, 72], _('d-2-72')), PolicyAreaDefinition([7, 73], _('d-2-73')), PolicyAreaDefinition([7, 74], _('d-2-74')), PolicyAreaDefinition([7, 75], _('d-2-75')), ]), PolicyAreaDefinition([8], _('d-1-8'), [ PolicyAreaDefinition([8, 81], _('d-2-81'), [ PolicyAreaDefinition([8, 81, 811], _('d-3-811')), PolicyAreaDefinition([8, 81, 812], _('d-3-812')), ]), PolicyAreaDefinition([8, 82], _('d-2-82'), [ PolicyAreaDefinition([8, 82, 821], _('d-3-821')), PolicyAreaDefinition([8, 82, 822], _('d-3-822')), ]), PolicyAreaDefinition([8, 83], _('d-2-83'), [ PolicyAreaDefinition([8, 83, 831], _('d-3-831')), PolicyAreaDefinition([8, 83, 832], _('d-3-832')), ]), PolicyAreaDefinition([8, 84], _('d-2-84')), PolicyAreaDefinition([8, 85], _('d-2-85')), PolicyAreaDefinition([8, 86], _('d-2-86')), PolicyAreaDefinition([8, 87], _('d-2-87')), ]), PolicyAreaDefinition([9], _('d-1-9'), [ PolicyAreaDefinition([9, 91], _('d-2-91'), [ PolicyAreaDefinition([9, 91, 911], _('d-3-911')), PolicyAreaDefinition([9, 91, 912], _('d-3-912')), ]), PolicyAreaDefinition([9, 92], _('d-2-92'), [ PolicyAreaDefinition([9, 92, 921], _('d-3-921')), PolicyAreaDefinition([9, 92, 922], _('d-3-922')), ]), PolicyAreaDefinition([9, 93], _('d-2-93'), [ PolicyAreaDefinition([9, 93, 931], _('d-3-931')), PolicyAreaDefinition([9, 93, 932], _('d-3-932')), PolicyAreaDefinition([9, 93, 933], _('d-3-933')), PolicyAreaDefinition([9, 93, 934], _('d-3-934')), PolicyAreaDefinition([9, 93, 935], _('d-3-935')), PolicyAreaDefinition([9, 93, 936], _('d-3-936')), PolicyAreaDefinition([9, 93, 937], _('d-3-937')), PolicyAreaDefinition([9, 93, 938], _('d-3-938')), ]), ]), PolicyAreaDefinition([10], _('d-1-10'), [ PolicyAreaDefinition([10, 101], _('d-2-101'), [ PolicyAreaDefinition([10, 101, 1011], _('d-3-1011')), PolicyAreaDefinition([10, 101, 1012], _('d-3-1012')), PolicyAreaDefinition([10, 101, 1013], _('d-3-1013')), PolicyAreaDefinition([10, 101, 1014], _('d-3-1014')), PolicyAreaDefinition([10, 101, 1015], _('d-3-1015')), ]), PolicyAreaDefinition([10, 102], _('d-2-102'), [ PolicyAreaDefinition([10, 102, 1021], _('d-3-1021')), PolicyAreaDefinition([10, 102, 1022], _('d-3-1022')), PolicyAreaDefinition([10, 102, 1023], _('d-3-1023')), PolicyAreaDefinition([10, 102, 1024], _('d-3-1024')), PolicyAreaDefinition([10, 102, 1025], _('d-3-1025')), PolicyAreaDefinition([10, 102, 1026], _('d-3-1026')), PolicyAreaDefinition([10, 102, 1027], _('d-3-1027')), PolicyAreaDefinition([10, 102, 1028], _('d-3-1028')), ]), PolicyAreaDefinition([10, 103], _('d-2-103'), [ PolicyAreaDefinition([10, 103, 1031], _('d-3-1031')), PolicyAreaDefinition([10, 103, 1032], _('d-3-1032')), PolicyAreaDefinition([10, 103, 1033], _('d-3-1033')), PolicyAreaDefinition([10, 103, 1034], _('d-3-1034')), PolicyAreaDefinition([10, 103, 1035], _('d-3-1035')), PolicyAreaDefinition([10, 103, 1036], _('d-3-1036')), PolicyAreaDefinition([10, 103, 1037], _('d-3-1037')), PolicyAreaDefinition([10, 103, 1038], _('d-3-1038')), ]), ]), PolicyAreaDefinition([11], _('d-1-11'), [ PolicyAreaDefinition([11, 111], _('d-2-111')), PolicyAreaDefinition([11, 112], _('d-2-112')), PolicyAreaDefinition([11, 113], _('d-2-113')), PolicyAreaDefinition([11, 114], _('d-2-114'), [ PolicyAreaDefinition([11, 114, 1141], _('d-3-1141')), PolicyAreaDefinition([11, 114, 1142], _('d-3-1142')), ]), PolicyAreaDefinition([11, 115], _('d-2-115')), ]), PolicyAreaDefinition([12], _('d-1-12'), [ PolicyAreaDefinition([12, 121], _('d-2-121')), PolicyAreaDefinition([12, 122], _('d-2-122')), PolicyAreaDefinition([12, 123], _('d-2-123')), PolicyAreaDefinition([12, 124], _('d-2-124')), PolicyAreaDefinition([12, 125], _('d-2-125'), [ PolicyAreaDefinition([12, 125, 1251], _('d-3-1251')), PolicyAreaDefinition([12, 125, 1252], _('d-3-1252')), PolicyAreaDefinition([12, 125, 1253], _('d-3-1253')), PolicyAreaDefinition([12, 125, 1254], _('d-3-1254')), ]), ]) ])