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(' > ').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.value = path[-1] if path else None
[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')),
]),
])
])