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-на форматирането е различно и не се получава добре. Мога да го изпратя като файл, ако искате.
|