Домашни > Хелоуин в Припят > Решения > Решението на Димитър Христов

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

9 точки общо

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

  1class Candy:
  2
  3    def __init__(self, mass, uranium):
  4        self._mass = mass
  5        self._uranium = uranium * mass
  6
  7    def get_uranium_quantity(self):
  8        return self._uranium
  9    
 10    def get_mass(self):
 11        return self._mass
 12    
 13    def __gt__(self, other):
 14        return self._mass > other._mass
 15    
 16
 17class Person:
 18    
 19    def __init__(self, position):
 20        self._position = position
 21    
 22    def get_position(self):
 23        return self._position
 24    
 25    def set_position(self, position):
 26        self._position = position
 27
 28    def get_distance_to(self, position):
 29        return (self._position[0] - position[0])**2 + (self._position[1] - position[1])**2
 30    
 31
 32class Kid(Person):
 33
 34    _CRITICAL_MASS = 20
 35
 36    def __init__(self, position, initiative):
 37        super().__init__(position)
 38        self._initiative = initiative
 39        self._candy_box = []
 40        self._current_uranium = 0
 41        self.hosts_to_visit = set()
 42    
 43    def get_initiative(self):
 44        return self._initiative
 45    
 46    def add_candy(self, candy):
 47        self._candy_box.append(candy)
 48        self._current_uranium += candy.get_uranium_quantity()
 49
 50    def is_critical(self):
 51        return self._current_uranium > self._CRITICAL_MASS
 52    
 53    def visit_closest_host(self):
 54        closest_host = min(self.hosts_to_visit, key = host_comparator(self._position))
 55        self.hosts_to_visit.remove(closest_host)
 56        self._position = closest_host.get_position()
 57        closest_host.kids.add(self)
 58    
 59    def __gt__(self, other):
 60        return self._initiative > other._initiative 
 61    
 62    
 63
 64class Host(Person):
 65
 66    def __init__(self, position, candy_info):
 67        super().__init__(position)
 68        self._candy_box = set(map(lambda info: Candy(*info), candy_info))
 69        self.kids = set()
 70
 71    def remove_candy(self, func):
 72        if not self._candy_box:
 73            return None
 74        result = func(self._candy_box)
 75        self._candy_box.remove(result)
 76        return result
 77    
 78    def give_candy(self):
 79        while self.kids:
 80            kid = max(self.kids)
 81            candy = self.remove_candy(max)
 82            kid.add_candy(candy)
 83            self.kids.remove(kid)
 84
 85
 86class FluxCapacitor:
 87
 88    def __init__(self, persons):
 89        self._kids = set(filter(lambda p: isinstance(p, Kid), persons))
 90        self._hosts = set(filter(lambda p: isinstance(p, Host), persons))
 91    
 92    def get_victim(self):
 93        for kid in self._kids:
 94            kid.hosts_to_visit = set(self._hosts)
 95        
 96        victims = set()
 97        for _ in self._hosts:
 98            for kid in self._kids:
 99                kid.visit_closest_host()
100            for host in self._hosts:
101                host.give_candy()
102            for kid in self._kids:
103                if kid.is_critical():
104                    victims.add(kid)
105            if victims:
106                return victims
107        return None
108    
109           
110def host_comparator(kid_position):
111    def compare(host):
112        return (host.get_distance_to(kid_position), host.get_position()[0])
113    return compare

....E.......
======================================================================
ERROR: test_no_candies (test.FluxCapacitorTest)
Test with no candies.
----------------------------------------------------------------------
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 106, in test_no_candies
self.assertEqual(flux_capacitor.get_victim(), None)
File "/tmp/solution.py", line 101, in get_victim
host.give_candy()
File "/tmp/solution.py", line 82, in give_candy
kid.add_candy(candy)
File "/tmp/solution.py", line 48, in add_candy
self._current_uranium += candy.get_uranium_quantity()
AttributeError: 'NoneType' object has no attribute 'get_uranium_quantity'

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

FAILED (errors=1)

Дискусия
Димитър Христов
05.11.2023 15:30

Мисля, че частните атрибути са по-добре описани така. Също така имам и custom comparator за host относно позицията на дете, с оглед на забележката от миналото решение за намирането на следващ host, намирам това за най-удачно.
Георги Кунчев
04.11.2023 15:26

Опитай да дефинираш частните атрибути на класовете с долна черта. Доста от атрибутите ти са частни и се използват само от самите инстанции. Нека се опитаме да го покажем, като следваме конвенцията.
История

f1class Candy:f1class Candy:
22
3    def __init__(self, mass, uranium):3    def __init__(self, mass, uranium):
4        self._mass = mass4        self._mass = mass
5        self._uranium = uranium * mass5        self._uranium = uranium * mass
66
7    def get_uranium_quantity(self):7    def get_uranium_quantity(self):
8        return self._uranium8        return self._uranium
9    9    
10    def get_mass(self):10    def get_mass(self):
11        return self._mass11        return self._mass
12    12    
13    def __gt__(self, other):13    def __gt__(self, other):
14        return self._mass > other._mass14        return self._mass > other._mass
15    15    
1616
17class Person:17class Person:
18    18    
19    def __init__(self, position):19    def __init__(self, position):
20        self._position = position20        self._position = position
21    21    
22    def get_position(self):22    def get_position(self):
23        return self._position23        return self._position
24    24    
25    def set_position(self, position):25    def set_position(self, position):
26        self._position = position26        self._position = position
2727
28    def get_distance_to(self, position):28    def get_distance_to(self, position):
29        return (self._position[0] - position[0])**2 + (self._position[1] - position[1])**229        return (self._position[0] - position[0])**2 + (self._position[1] - position[1])**2
30    30    
3131
32class Kid(Person):32class Kid(Person):
3333
34    _CRITICAL_MASS = 2034    _CRITICAL_MASS = 20
3535
36    def __init__(self, position, initiative):36    def __init__(self, position, initiative):
37        super().__init__(position)37        super().__init__(position)
38        self._initiative = initiative38        self._initiative = initiative
39        self._candy_box = []39        self._candy_box = []
40        self._current_uranium = 040        self._current_uranium = 0
41        self.hosts_to_visit = set()41        self.hosts_to_visit = set()
42    42    
43    def get_initiative(self):43    def get_initiative(self):
44        return self._initiative44        return self._initiative
45    45    
46    def add_candy(self, candy):46    def add_candy(self, candy):
47        self._candy_box.append(candy)47        self._candy_box.append(candy)
48        self._current_uranium += candy.get_uranium_quantity()48        self._current_uranium += candy.get_uranium_quantity()
4949
50    def is_critical(self):50    def is_critical(self):
51        return self._current_uranium > self._CRITICAL_MASS51        return self._current_uranium > self._CRITICAL_MASS
52    52    
53    def visit_closest_host(self):53    def visit_closest_host(self):
n54        print(self._position)n
55        closest_host = min(self.hosts_to_visit, key = host_comparator(self._position))54        closest_host = min(self.hosts_to_visit, key = host_comparator(self._position))
56        self.hosts_to_visit.remove(closest_host)55        self.hosts_to_visit.remove(closest_host)
57        self._position = closest_host.get_position()56        self._position = closest_host.get_position()
58        closest_host.kids.add(self)57        closest_host.kids.add(self)
t59        print(list(map(lambda c: c.get_uranium_quantity(), self._candy_box)))t58    
60        print(self._position)
61 
62    def __gt__(self, other):59    def __gt__(self, other):
63        return self._initiative > other._initiative 60        return self._initiative > other._initiative 
64    61    
65    62    
6663
67class Host(Person):64class Host(Person):
6865
69    def __init__(self, position, candy_info):66    def __init__(self, position, candy_info):
70        super().__init__(position)67        super().__init__(position)
71        self._candy_box = set(map(lambda info: Candy(*info), candy_info))68        self._candy_box = set(map(lambda info: Candy(*info), candy_info))
72        self.kids = set()69        self.kids = set()
7370
74    def remove_candy(self, func):71    def remove_candy(self, func):
75        if not self._candy_box:72        if not self._candy_box:
76            return None73            return None
77        result = func(self._candy_box)74        result = func(self._candy_box)
78        self._candy_box.remove(result)75        self._candy_box.remove(result)
79        return result76        return result
80    77    
81    def give_candy(self):78    def give_candy(self):
82        while self.kids:79        while self.kids:
83            kid = max(self.kids)80            kid = max(self.kids)
84            candy = self.remove_candy(max)81            candy = self.remove_candy(max)
85            kid.add_candy(candy)82            kid.add_candy(candy)
86            self.kids.remove(kid)83            self.kids.remove(kid)
8784
8885
89class FluxCapacitor:86class FluxCapacitor:
9087
91    def __init__(self, persons):88    def __init__(self, persons):
92        self._kids = set(filter(lambda p: isinstance(p, Kid), persons))89        self._kids = set(filter(lambda p: isinstance(p, Kid), persons))
93        self._hosts = set(filter(lambda p: isinstance(p, Host), persons))90        self._hosts = set(filter(lambda p: isinstance(p, Host), persons))
94    91    
95    def get_victim(self):92    def get_victim(self):
96        for kid in self._kids:93        for kid in self._kids:
97            kid.hosts_to_visit = set(self._hosts)94            kid.hosts_to_visit = set(self._hosts)
98        95        
99        victims = set()96        victims = set()
100        for _ in self._hosts:97        for _ in self._hosts:
101            for kid in self._kids:98            for kid in self._kids:
102                kid.visit_closest_host()99                kid.visit_closest_host()
103            for host in self._hosts:100            for host in self._hosts:
104                host.give_candy()101                host.give_candy()
105            for kid in self._kids:102            for kid in self._kids:
106                if kid.is_critical():103                if kid.is_critical():
107                    victims.add(kid)104                    victims.add(kid)
108            if victims:105            if victims:
109                return victims106                return victims
110        return None107        return None
111    108    
112           109           
113def host_comparator(kid_position):110def host_comparator(kid_position):
114    def compare(host):111    def compare(host):
115        return (host.get_distance_to(kid_position), host.get_position()[0])112        return (host.get_distance_to(kid_position), host.get_position()[0])
116    return compare113    return compare
117114
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Candy:f1class Candy:
22
3    def __init__(self, mass, uranium):3    def __init__(self, mass, uranium):
n4        self.mass = massn4        self._mass = mass
5        self.uranium = uranium * mass5        self._uranium = uranium * mass
66
7    def get_uranium_quantity(self):7    def get_uranium_quantity(self):
n8        return self.uraniumn8        return self._uranium
9    9    
10    def get_mass(self):10    def get_mass(self):
n11        return self.massn11        return self._mass
12    12    
13    def __gt__(self, other):13    def __gt__(self, other):
n14        return self.mass > other.massn14        return self._mass > other._mass
15    15    
1616
17class Person:17class Person:
18    18    
19    def __init__(self, position):19    def __init__(self, position):
n20        self.position = positionn20        self._position = position
21    21    
22    def get_position(self):22    def get_position(self):
n23        return self.positionn23        return self._position
24    24    
25    def set_position(self, position):25    def set_position(self, position):
n26        self.position = positionn26        self._position = position
2727
n28    def _get_distance_to_(self, position):n28    def get_distance_to(self, position):
29        return abs(self.position[0] - position[0])**2 + abs(self.position[1] - position[1])**229        return (self._position[0] - position[0])**2 + (self._position[1] - position[1])**2
30    30    
n31 n
3231
33class Kid(Person):32class Kid(Person):
3433
nn34    _CRITICAL_MASS = 20
35 
35    def __init__(self, position, initiative):36    def __init__(self, position, initiative):
36        super().__init__(position)37        super().__init__(position)
n37        self.initiative = initiativen38        self._initiative = initiative
38        self.candy_box = []39        self._candy_box = []
39        self.current_uranium = 040        self._current_uranium = 0
40        self.hosts_to_visit = set()41        self.hosts_to_visit = set()
41    42    
42    def get_initiative(self):43    def get_initiative(self):
n43        return self.initiativen44        return self._initiative
44    45    
45    def add_candy(self, candy):46    def add_candy(self, candy):
n46        self.candy_box.append(candy)n47        self._candy_box.append(candy)
47        self.current_uranium += candy.get_uranium_quantity()48        self._current_uranium += candy.get_uranium_quantity()
4849
49    def is_critical(self):50    def is_critical(self):
n50        return self.current_uranium > 20n51        return self._current_uranium > self._CRITICAL_MASS
51    52    
52    def visit_closest_host(self):53    def visit_closest_host(self):
n53        current_min_distance = 100000000n54        print(self._position)
54        current_min_x = 10000000055        closest_host = min(self.hosts_to_visit, key = host_comparator(self._position))
55        closest_host = None
56        for host in self.hosts_to_visit:
57            if (current_min_distance > self._get_distance_to_(host.position)) or (current_min_distance == self._get_distance_to_(host.position) and host.positon[0] < current_min_x):
58                current_min_distance = self._get_distance_to_(host.position)
59                closest_host = host
60                current_min_x = host.position[0]
61        self.hosts_to_visit.remove(closest_host)56        self.hosts_to_visit.remove(closest_host)
nn57        self._position = closest_host.get_position()
62        closest_host.kids.add(self)58        closest_host.kids.add(self)
nn59        print(list(map(lambda c: c.get_uranium_quantity(), self._candy_box)))
60        print(self._position)
6361
64    def __gt__(self, other):62    def __gt__(self, other):
n65        return self.initiative > other.initiative n63        return self._initiative > other._initiative 
66    64    
67    65    
n68 n
6966
70class Host(Person):67class Host(Person):
7168
72    def __init__(self, position, candy_info):69    def __init__(self, position, candy_info):
73        super().__init__(position)70        super().__init__(position)
n74        self.candy_box = set(map(lambda info : Candy(info[0], info[1]), candy_info))n71        self._candy_box = set(map(lambda info: Candy(*info), candy_info))
75        self.kids = set()72        self.kids = set()
7673
77    def remove_candy(self, func):74    def remove_candy(self, func):
n78        if len(self.candy_box) == 0:n75        if not self._candy_box:
79            return None76            return None
n80        result = func(self.candy_box)n77        result = func(self._candy_box)
81        self.candy_box.remove(result)78        self._candy_box.remove(result)
82        return result79        return result
83    80    
84    def give_candy(self):81    def give_candy(self):
n85        while len(self.kids) > 0:n82        while self.kids:
86            kid = max(self.kids)83            kid = max(self.kids)
n87            candy = self.remove_candy(get_max_mass_candy)n84            candy = self.remove_candy(max)
88            kid.add_candy(candy)85            kid.add_candy(candy)
89            self.kids.remove(kid)86            self.kids.remove(kid)
9087
9188
92class FluxCapacitor:89class FluxCapacitor:
9390
94    def __init__(self, persons):91    def __init__(self, persons):
n95        self.kids = set(filter(lambda p: isinstance(p, Kid), persons))n92        self._kids = set(filter(lambda p: isinstance(p, Kid), persons))
96        self.hosts = set(filter(lambda p: isinstance(p, Host), persons))93        self._hosts = set(filter(lambda p: isinstance(p, Host), persons))
97    94    
98    def get_victim(self):95    def get_victim(self):
n99        for kid in self.kids:n96        for kid in self._kids:
100            kid.hosts_to_visit = set(self.hosts)97            kid.hosts_to_visit = set(self._hosts)
101        98        
102        victims = set()99        victims = set()
n103        for i in range(0, len(self.hosts)):n100        for _ in self._hosts:
104            for kid in self.kids:101            for kid in self._kids:
105                kid.visit_closest_host()102                kid.visit_closest_host()
n106            for host in self.hosts:n103            for host in self._hosts:
107                host.give_candy()104                host.give_candy()
n108            for kid in self.kids:n105            for kid in self._kids:
109                if kid.is_critical():106                if kid.is_critical():
110                    victims.add(kid)107                    victims.add(kid)
n111            if len(victims) > 0:n108            if victims:
112                return victims109                return victims
113        return None110        return None
114    111    
115           112           
t116def get_max_mass_candy(candy_box):t113def host_comparator(kid_position):
117    return max(candy_box)114    def compare(host):
115        return (host.get_distance_to(kid_position), host.get_position()[0])
116    return compare
117 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op