1class Currency:
2 def __init__(self, name, rate):
3 self.name = name
4 self.rate = rate
5
6 def __eq__(self, other):
7 if not isinstance(other, Currency):
8 return False
9 return self.name == other.name and self.rate == other.rate
10
11
12class PoliticalParty:
13 def __init__(self, name, motto, members=None, preferred_currency=None):
14 self.name = name
15 self._motto = motto
16
17 if members is None:
18 self.members = []
19 else:
20 self.members = members.copy()
21
22 self.preferred_currency = preferred_currency
23
24 @property
25 def motto(self):
26 return self._motto
27
28 def convert_currency_to_voters(self, amount, currency):
29 voters = amount // currency.rate
30
31 if self.preferred_currency == currency:
32 voters *= 2
33
34 return int(voters)
35
36 def __str__(self):
37 return self.name
38
39 def __add__(self, other):
40 if isinstance(other, PoliticalParty):
41 return Coalition(self, other)
42 return NotImplemented
43
44
45class Coalition:
46 def __init__(self, *parties):
47 self.parties = []
48
49 for party in parties:
50 self.parties.append(party)
51
52 @property
53 def members(self):
54 result = {}
55
56 for party in self.parties:
57 result[party.name] = party.members.copy()
58
59 return result
60
61 def __add__(self, other):
62 if isinstance(other, PoliticalParty):
63 new_parties = self.parties.copy()
64 new_parties.append(other)
65 return Coalition(*new_parties)
66
67 if isinstance(other, Coalition):
68 new_parties = self.parties.copy()
69
70 for party in other.parties:
71 new_parties.append(party)
72
73 return Coalition(*new_parties)
74
75 return NotImplemented
76
77 def __str__(self):
78 names = []
79
80 for party in self.parties:
81 names.append(str(party))
82
83 return "-".join(names)
84
85
86class Elections:
87 elections_by_year = {}
88
89 def __init__(self, year):
90 self.year = year
91 self.results = {}
92
93 Elections.elections_by_year[year] = self
94
95 def register_party_or_coalition(self, party_or_coalition):
96 name = str(party_or_coalition)
97
98 if name not in self.results:
99 self.results[name] = 0
100
101 def vote(self, party_or_coalition):
102 name = str(party_or_coalition)
103 self.results[name] += 1
104
105 def rig_elections(self, party_or_coalition, amount, currency):
106 name = str(party_or_coalition)
107
108 bought_votes = 0
109
110 if isinstance(party_or_coalition, PoliticalParty):
111 bought_votes = party_or_coalition.convert_currency_to_voters(amount, currency)
112
113 elif isinstance(party_or_coalition, Coalition):
114 for party in party_or_coalition.parties:
115 current_votes = party.convert_currency_to_voters(amount, currency)
116 if current_votes > bought_votes:
117 bought_votes = current_votes
118
119 self.results[name] += bought_votes
120
121 def get_results(self):
122 return self.results.copy()
123
124 @classmethod
125 def get_results_by_year(cls, year):
126 if year in cls.elections_by_year:
127 return cls.elections_by_year[year].get_results()
128 return {}
..............F......
======================================================================
FAIL: test_convert_currency_to_voters_floating_point_edge_case (test.TestPoliticalParty.test_convert_currency_to_voters_floating_point_edge_case)
convert_currency_to_voters should properly account for floating point edge cases (e.g. 0.200001 errors).
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 55, in test_convert_currency_to_voters_floating_point_edge_case
self.assertEqual(5, party.convert_currency_to_voters(2, currency))
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 5 != 4
----------------------------------------------------------------------
Ran 21 tests in 0.001s
FAILED (failures=1)
22.03.2026 12:02
22.03.2026 12:03
22.03.2026 12:04
22.03.2026 12:06