Домашни > Хелоуин в Припят > Решения > Решението на Тихомир Божков

Резултати
9 точки от тестове
1 точки от учител

10 точки общо

11 успешни теста
1 неуспешни теста
Код

 1class Candy:
 2    def __init__(self, mass, uranium):
 3        self.mass = mass
 4        self.uranium = uranium
 5
 6    def get_uranium_quantity(self):
 7        return self.mass * self.uranium
 8
 9    def get_mass(self):
10        return self.mass
11
12
13class Person:
14    def __init__(self, position):
15        self.position = position
16
17    def get_position(self):
18        return self.position
19
20    def set_position(self, new_position):
21        self.position = new_position
22
23
24class Kid(Person):
25    def __init__(self, position, initiative):
26        super().__init__(position)
27        self.initiative = initiative
28        self.candies = []
29
30    def get_initiative(self):
31        return self.initiative
32
33    def add_candy(self, candy):
34        self.candies.append(candy)
35
36    def is_critical(self):
37        uranium_quantity = sum(candy.get_uranium_quantity() for candy in self.candies)
38        return uranium_quantity > 20
39
40
41class Host(Person):
42    def __init__(self, position, candies):
43        super().__init__(position)
44        self.candies = [Candy(mass, uranium) for mass, uranium in candies]
45
46    def remove_candy(self, choose_candy):
47        if not self.candies:
48            return None
49        chosen_candy = choose_candy(self.candies)
50        self.candies.remove(chosen_candy)
51        return chosen_candy
52
53
54class FluxCapacitor:
55    def __init__(self, participants):
56        self.participants = participants
57
58    def get_victim(self):
59        kids = [participants for participants in self.participants if isinstance(participants, Kid)]
60        hosts = [participants for participants in self.participants if isinstance(participants, Host)]
61        for host in hosts:
62            while kids:
63                serving_kids = [kid for kid in kids if kid.get_position() == host.get_position()]
64                if serving_kids:
65                    serving_kids.sort(key = lambda kid: (-kid.get_initiative(), kid.get_position()))
66                    chosen_kid = serving_kids[0]
67                    candy = host.remove_candy(lambda candies: max(candies, key = lambda candy: candy.get_mass()))
68                    if candy:
69                        chosen_kid.add_candy(candy)
70                        if chosen_kid.is_critical():
71                            return {chosen_kid}
72                    kids.remove(chosen_kid)
73                else:
74                    break
75        return None

.....F......
======================================================================
FAIL: test_real_case (test.FluxCapacitorTest)
Test with real case.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 82, in new_function
return function(*args, **kwargs)
File "/tmp/test.py", line 115, in test_real_case
self.assertEqual(FluxCapacitor({kid1, kid2, host1, host2}).get_victim(), {kid1, kid2})
AssertionError: None != {<solution.Kid object at 0x7f8064325420>,[36 chars]360>}

----------------------------------------------------------------------
Ran 12 tests in 0.001s

FAILED (failures=1)

Дискусия
Виктор Бечев
07.11.2023 20:24

По темата с фейващия тест: ``` serving_kids = [kid for kid in kids if kid.get_position() == host.get_position()] ``` Винаги връща прзен списък. Късмет, че повечето тестове са без жертва, но реално няма как някога да върнеш нещо различно от None. Фейлът е нормален, защото този ред филтрира само тези деца, които са на същата позиция като хостовете, което няма логика, тъй като всеки започва на различна позиция (в частният случай, където децата и хостовете започват на едни и същи позиции би работело, но само тогава).
Тихомир Божков
07.11.2023 07:49

``` import unittest from solution import Candy, Person, Kid, Host, FluxCapacitor class TestCandy(unittest.TestCase): def test_get_uranium_quantity(self): candy = Candy(20, 0.3) self.assertEqual(candy.get_uranium_quantity(), 6.0) def test_get_mass(self): candy = Candy(20, 0.3) self.assertEqual(candy.get_mass(), 20) class TestPerson(unittest.TestCase): def test_get_position(self): person = Person((1, 2)) self.assertEqual(person.get_position(), (1, 2)) def test_set_position(self): person = Person((1, 2)) person.set_position((3, 4)) self.assertEqual(person.get_position(), (3, 4)) class TestKid(unittest.TestCase): def test_add_candy(self): kid = Kid((0, 0), 123) candy1 = Candy(15, 0.2) kid.add_candy(candy1) self.assertIn(candy1, kid.candies) def test_is_critical(self): kid = Kid((0, 0), 123) candy1 = Candy(15, 0.2) kid.add_candy(candy1) self.assertFalse(kid.is_critical()) candy2 = Candy(10, 2.0) kid.add_candy(candy2) self.assertTrue(kid.is_critical()) class TestHost(unittest.TestCase): def test_remove_candy(self): host = Host((3, 4), [(10, 0.5), (15, 0.3), (12, 0.1)]) candy1 = host.remove_candy(lambda candies: max(candies, key = lambda candy: candy.get_mass())) self.assertEqual(candy1.get_mass(), 15) candy2 = host.remove_candy(lambda candies: max(candies, key = lambda candy: candy.get_mass())) self.assertEqual(candy2.get_mass(), 12) candy3 = host.remove_candy(lambda candies: max(candies, key = lambda candy: candy.get_mass())) self.assertEqual(candy3.get_mass(), 10) class TestFluxCapacitor(unittest.TestCase): def test_get_victim(self): kid1 = Kid((0, 0), 123) kid2 = Kid((1, 1), 150) host = Host((0, 0), [(10, 0.5)]) flux_capacitor = FluxCapacitor({kid1, kid2, host}) victims = flux_capacitor.get_victim() if victims is not None: self.assertEqual(len(victims), 1) else: self.assertIsNone(victims) if __name__ == "__main": unittest.main() ``` Сега май е по-добре. Единствено може би класовете не се форматират правилно.
Виктор Бечев
06.11.2023 14:53

Отвъд това - доста чисто решение, браво!
Георги Кунчев
06.11.2023 08:39

На мен не ми е нужен. За форматирането, виж в хелп секцията на сайта. Код, поставен в бектикове, се форматира и оцветява.
Тихомир Божков
06.11.2023 00:44

По принцип направих и unittest за кода, но като го paste-на форматирането е различно и не се получава добре. Мога да го изпратя като файл, ако искате.
История
Това решение има само една версия.