1import unittest
2
3import solution
4
5
6class TestSanity(unittest.TestCase):
7 """Check if all data is present."""
8
9 def test_requirements(self):
10 names = ["Currency", "PoliticalParty", "Coalition", "Elections"]
11 unimported = [name for name in names if name not in dir(solution)]
12 self.assertEqual(
13 unimported, [], "\n\nЕлементите по-горе липсват (проверете си имената)!"
14 )
15
16
17if __name__ == "__main__":
18 unittest.main()
1import unittest
2
3from solution import *
4
5
6class TestCurrency(unittest.TestCase):
7 def test_currency_equals(self):
8 """Currency elements should be equal when their name and "rate" is the same."""
9 cur1 = Currency("something", 5)
10 cur2 = Currency("something", 5)
11 cur3 = Currency("something", 10)
12 cur4 = Currency("something_else", 5)
13 cur5 = Currency("something_completely_else", 20)
14 self.assertEqual(cur1, cur2)
15 self.assertNotEqual(cur1, cur3)
16 self.assertNotEqual(cur1, cur4)
17 self.assertNotEqual(cur1, cur5)
18
19
20class TestPoliticalParty(unittest.TestCase):
21 def setUp(self):
22 self.party = PoliticalParty("Some Name", "Some motto")
23 self.currency = Currency("something", 8.5)
24
25 def test_party_init(self):
26 """PoliticalParty should support initialization with optional members and preferred currency."""
27 PoliticalParty("Some Name", "Some motto")
28 PoliticalParty("Some Name", "Some motto", members=["a", "b", "c"])
29 PoliticalParty("Some Name", "Some motto", preferred_currency=Currency("something", 10))
30
31 def test_motto(self):
32 """Motto should be accessible with the PoliticalParty.motto attribute."""
33 self.assertEqual("Some motto", self.party.motto)
34
35 def test_motto_write(self):
36 """Motto should not be writable after the party is created."""
37 with self.assertRaises(Exception):
38 self.party.motto = "some other motto" # type: ignore
39
40 def test_convert_currency_to_voters(self):
41 """convert_currency_to_voters should return normal or double voters depending on the preferred currency."""
42 self.assertEqual(4, self.party.convert_currency_to_voters(34, self.currency))
43
44 party_with_cur = PoliticalParty("Some Name", "Some motto", preferred_currency=self.currency)
45 self.assertEqual(8, party_with_cur.convert_currency_to_voters(34, self.currency))
46
47 def test_convert_currency_to_voters_rounding(self):
48 """convert_currency_to_voters should round the number of voters down."""
49 self.assertEqual(4, self.party.convert_currency_to_voters(34.5, self.currency))
50
51 def test_convert_currency_to_voters_floating_point_edge_case(self):
52 """convert_currency_to_voters should properly account for floating point edge cases (e.g. 0.200001 errors)."""
53 party = PoliticalParty("Some Name", "Some motto")
54 currency = Currency("something", 0.4)
55 self.assertEqual(5, party.convert_currency_to_voters(2, currency))
56
57 def test_party_str(self):
58 """PoliticalParty should convert to its name when cast to string."""
59 self.assertEqual("Some Name", str(self.party))
60
61 def test_party_addition(self):
62 """Adding two parties should create a Coalition."""
63 party1 = PoliticalParty("Party 1", "Some motto", members=["a", "b"])
64 party2 = PoliticalParty("Party 2", "Some motto", members=["c"])
65 coalition = party1 + party2
66 self.assertIsInstance(coalition, Coalition)
67
68
69class TestCoalition(unittest.TestCase):
70 def test_coalition_init_with_multiple(self):
71 """Coalition should support initialization with multiple parties."""
72 party1 = PoliticalParty("Party 1", "Motto 1")
73 party2 = PoliticalParty("Party 2", "Motto 2")
74 party3 = PoliticalParty("Party 3", "Motto 3")
75 Coalition(party1, party2, party3)
76
77 def test_members(self):
78 """Coalition.members should return a mapping from party names to member lists."""
79 party1 = PoliticalParty("Party 1", "Motto 1", members=["a"])
80 party2 = PoliticalParty("Party 2", "Motto 2", members=["b"])
81 coalition = Coalition(party1, party2)
82 self.assertEqual({"Party 1": ["a"], "Party 2": ["b"]}, coalition.members)
83
84 def test_party_addition_preserves_members(self):
85 """Creating a coalition from two parties should preserve their members."""
86 party1 = PoliticalParty("Party 1", "Motto 1", members=["a"])
87 party2 = PoliticalParty("Party 2", "Motto 2", members=["b"])
88 coalition = party1 + party2
89 self.assertEqual({"Party 1": ["a"], "Party 2": ["b"]}, coalition.members)
90
91 def test_coalition_members_include_empty_lists(self):
92 """Coalition.members should return an empty list for parties without members."""
93 party1 = PoliticalParty("Party 1", "Motto 1")
94 party2 = PoliticalParty("Party 2", "Motto 2", members=["a"])
95 coalition = Coalition(party1, party2)
96 self.assertEqual({"Party 1": [], "Party 2": ["a"]}, coalition.members)
97
98 def test_add_party_to_coalition(self):
99 """Adding a party to a coalition should return a new coalition with all members preserved."""
100 party1 = PoliticalParty("Party 1", "Motto 1", members=["a"])
101 party2 = PoliticalParty("Party 2", "Motto 2", members=["b"])
102 party3 = PoliticalParty("Party 3", "Motto 3", members=["c"])
103 coalition = Coalition(party1, party2)
104 new_coalition = coalition + party3
105 self.assertEqual({"Party 1": ["a"], "Party 2": ["b"], "Party 3": ["c"]}, new_coalition.members)
106 self.assertIsNot(new_coalition, coalition)
107
108 def test_add_coalitions(self):
109 """Adding two coalitions should return a new coalition containing all parties."""
110 party1 = PoliticalParty("Party 1", "Motto 1", members=["a"])
111 party2 = PoliticalParty("Party 2", "Motto 2", members=["b"])
112 party3 = PoliticalParty("Party 3", "Motto 3", members=["c"])
113 party4 = PoliticalParty("Party 4", "Motto 4", members=["d"])
114 coalition1 = Coalition(party1, party2)
115 coalition2 = Coalition(party3, party4)
116 new_coalition = coalition1 + coalition2
117 self.assertEqual(
118 {"Party 1": ["a"], "Party 2": ["b"], "Party 3": ["c"], "Party 4": ["d"]}, new_coalition.members
119 )
120 self.assertIsNot(new_coalition, coalition1)
121 self.assertIsNot(new_coalition, coalition2)
122
123 def test_coalition_str(self):
124 """Coalition should convert to a dash-separated list of party names."""
125 party1 = PoliticalParty("Party 1", "Motto 1", members=["a"])
126 party2 = PoliticalParty("Party 2", "Motto 2", members=["b"])
127 coalition = Coalition(party1, party2)
128 self.assertEqual("Party 1-Party 2", str(coalition))
129
130
131class TestElections(unittest.TestCase):
132 def setUp(self):
133 self.currency = Currency("something", 10)
134 self.party = PoliticalParty("Party 1", "Motto 1", members=["a"])
135 party2 = PoliticalParty("Party 2", "Motto 2", members=["b"])
136 party3 = PoliticalParty("Party 3", "Motto 3", members=["c"], preferred_currency=self.currency)
137 self.coalition = Coalition(party2, party3)
138 self.elections_2026 = Elections(2026)
139
140 def test_vote(self):
141 """vote should add one vote to the given registered party or coalition."""
142 self.elections_2026.register_party_or_coalition(self.party)
143 self.elections_2026.register_party_or_coalition(self.coalition)
144 self.elections_2026.vote(self.party)
145 self.elections_2026.vote(self.party)
146 self.elections_2026.vote(self.coalition)
147 self.assertEqual({"Party 1": 2, "Party 2-Party 3": 1}, self.elections_2026.get_results())
148
149 def test_register_party_or_coalition_starts_with_zero_votes(self):
150 """Registered parties and coalitions should start with zero votes."""
151 self.elections_2026.register_party_or_coalition(self.party)
152 self.assertEqual({"Party 1": 0}, self.elections_2026.get_results())
153
154 def test_rig_elections(self):
155 """rig_elections should add as many bought votes as possible to the result."""
156 self.elections_2026.register_party_or_coalition(self.party)
157 self.elections_2026.rig_elections(self.party, 50, self.currency)
158 self.assertEqual({"Party 1": 5}, self.elections_2026.get_results())
159
160 def test_rig_elections_preferred_currency(self):
161 """rig_elections should use the most effective preferred currency conversion in a coalition."""
162 self.elections_2026.register_party_or_coalition(self.coalition)
163 self.elections_2026.rig_elections(self.coalition, 80, self.currency)
164 self.elections_2026.rig_elections(self.coalition, 50, Currency("something else", 10))
165 self.assertEqual({"Party 2-Party 3": 21}, self.elections_2026.get_results())
166
167 def test_get_results_by_year(self):
168 """get_results_by_year should return the results for the given election year."""
169 self.elections_2026.register_party_or_coalition(self.party)
170 self.elections_2026.vote(self.party)
171 self.assertEqual({"Party 1": 1}, Elections.get_results_by_year(2026))
172
173
174if __name__ == "__main__":
175 unittest.main()
Гергана Панделиева
25.03.2026 00:02Бях влезнала съм в профила си и в 23:50(ясно е, че не трябваше да чакам последния момент) не ми даваше възможност да си прикача домашното, а до сега не ми беше създавало проблем.
| |||
Николай Георгиев
24.03.2026 18:11Трябва ли да проверявам в register_party_or_coalition() или въобще някъде в Elections дали някоя партия не е станала твърде алчна и освен че участва сама в изборите, е и част от коалиция, или разчитаме на честна игра?
| |||
Илиян Гаврилов
18.03.2026 18:32Няколко неща:
1. `elections_2026.get_results() # {"БСП": 1, "ГЕРБ-СДС": 5}` не трябва ли да е `elections_2026.get_results() # {"БСП": 1, "ГЕРБ-СДС": 10}`, тъй като на `GERB` предпочитаната валута е `gold_bars`? (1/0.2) * 2 = 10?
2. За коалицията пише, че "се инициализира с произволен брой PoliticalParty обекти", значи ли, че може с <2 партии?
3. `PPDB = DB + PP
print(DB.members) # {"Да, България": ["Божо", "Ивайло Мирчев"], "ДСБ": ["Не-Иван-Костов", "Пак не е Иван Костов"], "ПП": ["Асенката"]}` не трябва ли да е `PPDB.members`, защото така се мутира `DB`, а в условието пише, че трябва да се създаде нова инстанция
Нишка
| |||
Милка Кръстева
18.03.2026 14:58kebapcheta = Currency("кебапчета", 15)
DPS = PoliticalParty("ДПС", kebapcheta)
В описанието вторият позиционен аргумент не е опционален, а в примера тук липсва. :) Кое да приемем да вярно ?:) И опционалните параметри keyword ли са, или позиционни ? :) И отговора не трябва ли да е 6, защото kebapcheta са предпочитана валута на ДПС :)
Нишка
| |||
Михаил Георгиев
18.03.2026 12:12Може ли да попитам ако гласуваме за партия, която не е регистрирана дали трябва да има допълнителна проверка за това, също така методът get_results_by_year дали е static или class метод и откъде идват данните и coalition , мисля че се пише с едно L и дали това ще гръмне на тестовете и последно как се купуват гласове за коалиция дали трябва да изберем най-добрата партия демек тази, която дава най-много гласове
Нишка
| |||
Виктор Бечев
17.03.2026 22:48Примерите са много, домашното не е сложно... Но е обемно, а ако все още не сте свикнали с ООП-то в [Python](https://www.youtube.com/watch?v=a1sn0ZSfnMo) - времеемко.
Така че ви съветваме, да не го оставяте за последния момент. Оставаме насреща да ни питате ако има нещо неясно или пък сме допуснали грешка. Успех!
Нишка |