Домашни > Великденско домашно > Решения > Решението на Нора Кирилова

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

6 точки общо

45 успешни теста
1 неуспешни теста
Код
Скрий всички коментари

  1class Egg:
  2    def __init__(self):
  3        self._pattern = []
  4        self._filled = 0.0
  5        self._broken_top = False
  6        self._broken_bottom = False
  7        self._tournament = None
  8
  9    def paint (self, *args):
 10        to_add = 0.0
 11        for hex_color, percentage in args:
 12            to_add += percentage
 13
 14        if to_add + self._filled > 100.0:
 15            raise ValueError("Too much paint! Cannot fill more than 100% of the egg.")
 16        
 17        for hex_color, percentage in args:
 18            self._pattern.append((hex_color.upper(), percentage))
 19
 20        self._filled += to_add
 21
 22    def _color_value(self, hex_color):
 23        r = int(hex_color[0:2], 16)
 24        g = int(hex_color[2:4], 16)
 25        b = int(hex_color[4:6], 16)
 26        return r + g + b
 27    
 28    def _side_strength(self, top=True):
 29        start = 0.0 if top else 50.0
 30        end = 50.0 if top else 100.0
 31        strength = 0.0
 32        painted_so_far = 0.0
 33
 34        for hex_color, percentage in self._pattern:
 35            seg_start = painted_so_far
 36            seg_end = painted_so_far + percentage
 37            overlap_start = max(seg_start, start)
 38            overlap_end = min(seg_end, end)
 39
 40            if overlap_start < overlap_end:
 41                overlap_percentage = overlap_end - overlap_start
 42                proportion = overlap_percentage / 50.0
 43                strength += self._color_value(hex_color) * proportion
 44
 45            painted_so_far = seg_end
 46
 47        return strength
 48    
 49    def _notify_tournament(self, other, winner, side):
 50        if (self._tournament is not None and self._tournament is other._tournament):
 51            self._tournament._record_match(self, other, winner, side)
 52
 53    def _duel(self, other, top):
 54        if top:
 55            if self._broken_top or other._broken_top:
 56                raise TypeError("Broken side cannot be used again")
 57        else:
 58            if self._broken_bottom or other._broken_bottom:
 59                raise TypeError("Broken side cannot be used again")
 60
 61        my_strength = self._side_strength(top=top)
 62        other_strength = other._side_strength(top=top)
 63
 64        if my_strength > other_strength:
 65            winner = self
 66            loser = other
 67        else:
 68            winner = other
 69            loser = self
 70
 71        if top:
 72            loser._broken_top = True
 73        else:
 74            loser._broken_bottom = True
 75
 76        self._notify_tournament(other, winner, "top" if top else "bottom")
 77        return winner
 78    
 79    def __mul__(self, other):
 80        return self._duel(other, top=True)
 81    
 82    def __matmul__(self, other):
 83        return self._duel(other, top=False)
 84        
 85class EggTournament:
 86    def __init__(self):
 87        self._eggs_by_name = {}
 88        self._names_by_egg = {}
 89        self._history = []
 90        self._wins = {}
 91
 92    def register(self, egg, name):
 93        if egg._tournament is not None:
 94            raise ValueError("An egg cannot be registered in multiple tournaments")
 95
 96        if not name.isidentifier():
 97            raise ValueError("Invalid registration name")
 98
 99        if name in self._eggs_by_name:
100            raise ValueError(f"Egg with name {name} has already been registered")
101
102        self._eggs_by_name[name] = egg
103        self._names_by_egg[egg] = name
104        self._wins[egg] = 0
105        egg._tournament = self
106
107    def _record_match(self, egg1, egg2, winner, side):
108        self._history.append({
109            "eggs": frozenset((egg1, egg2)),
110            "winner": winner,
111            "side": side,
112        })
113        self._wins[winner] += 1
114
115    def __contains__(self, egg):
116        return egg in self._names_by_egg
117
118    def __getitem__(self, key):
119        egg1 = egg2 = side = None
120
121        if isinstance(key, tuple) and len(key) == 3:
122            egg1, egg2, side = key
123        elif isinstance(key, slice):
124            egg1 = key.start
125            egg2 = key.stop
126            side = key.step
127        else:
128            raise KeyError
129
130        pair = frozenset((egg1, egg2))
131
132        for record in reversed(self._history):
133            if record["eggs"] == pair and record["side"] == side:
134                return record["winner"]
135
136        raise KeyError
137
138    def _ranking_groups(self):
139        eggs = list(self._wins.keys())
140        eggs.sort(key=lambda egg: self._wins[egg], reverse=True)
141
142        groups = {}
143        current_position = 0
144        previous_wins = None
145
146        for index, egg in enumerate(eggs):
147            wins = self._wins[egg]
148
149            if previous_wins is None or wins < previous_wins:
150                current_position += 1
151
152            groups.setdefault(current_position, set()).add(egg)
153            previous_wins = wins
154
155        return groups
156
157    def _position_of_egg(self, target_egg):
158        groups = self._ranking_groups()
159
160        for position, eggs in groups.items():
161            if target_egg in eggs:
162                return position
163
164        raise AttributeError("Apologies, there is no such egg registered")
165
166    def __rmatmul__(self, position):
167        groups = self._ranking_groups()
168
169        if position not in groups:
170            raise IndexError
171
172        eggs = groups[position]
173        if len(eggs) == 1:
174            return next(iter(eggs))
175        return eggs
176
177    def __getattr__(self, name):
178        if name not in self._eggs_by_name:
179            raise AttributeError("Apologies, there is no such egg registered")
180
181        egg = self._eggs_by_name[name]
182        return {"position": self._position_of_egg(egg), "victories": self._wins[egg]}

.....................F........................
======================================================================
FAIL: test_unpainted_half_loses_to_half_painted_black (test.TestEgg.test_unpainted_half_loses_to_half_painted_black)
An unpainted half should lose to a half painted in black.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 205, in test_unpainted_half_loses_to_half_painted_black
self.assertIs(black_egg * unpainted_egg, black_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: <solution.Egg object at 0x71135aa61010> is not <solution.Egg object at 0x71135aa60ec0>

----------------------------------------------------------------------
Ran 46 tests in 0.002s

FAILED (failures=1)

Дискусия
История

f1class Egg:f1class Egg:
2    def __init__(self):2    def __init__(self):
3        self._pattern = []3        self._pattern = []
4        self._filled = 0.04        self._filled = 0.0
5        self._broken_top = False5        self._broken_top = False
6        self._broken_bottom = False6        self._broken_bottom = False
7        self._tournament = None7        self._tournament = None
nn8 
8    def paint (self, *args):9    def paint (self, *args):
9        to_add = 0.010        to_add = 0.0
10        for hex_color, percentage in args:11        for hex_color, percentage in args:
11            to_add += percentage12            to_add += percentage
1213
13        if to_add + self._filled > 100.0:14        if to_add + self._filled > 100.0:
14            raise ValueError("Too much paint! Cannot fill more than 100% of the egg.")15            raise ValueError("Too much paint! Cannot fill more than 100% of the egg.")
15        16        
16        for hex_color, percentage in args:17        for hex_color, percentage in args:
n17            self._pattern.append((hex_color, percentage))n18            self._pattern.append((hex_color.upper(), percentage))
1819
19        self._filled += to_add20        self._filled += to_add
nn21 
20    def _color_value(self, hex_color):22    def _color_value(self, hex_color):
21        r = int(hex_color[0:2], 16)23        r = int(hex_color[0:2], 16)
22        g = int(hex_color[2:4], 16)24        g = int(hex_color[2:4], 16)
23        b = int(hex_color[4:6], 16)25        b = int(hex_color[4:6], 16)
24        return r + g + b26        return r + g + b
nn27    
25    def _side_strength(self, top=True):28    def _side_strength(self, top=True):
26        start = 0.0 if top else 50.029        start = 0.0 if top else 50.0
27        end = 50.0 if top else 100.030        end = 50.0 if top else 100.0
28        strength = 0.031        strength = 0.0
29        painted_so_far = 0.032        painted_so_far = 0.0
3033
31        for hex_color, percentage in self._pattern:34        for hex_color, percentage in self._pattern:
32            seg_start = painted_so_far35            seg_start = painted_so_far
33            seg_end = painted_so_far + percentage36            seg_end = painted_so_far + percentage
34            overlap_start = max(seg_start, start)37            overlap_start = max(seg_start, start)
35            overlap_end = min(seg_end, end)38            overlap_end = min(seg_end, end)
3639
37            if overlap_start < overlap_end:40            if overlap_start < overlap_end:
38                overlap_percentage = overlap_end - overlap_start41                overlap_percentage = overlap_end - overlap_start
39                proportion = overlap_percentage / 50.042                proportion = overlap_percentage / 50.0
40                strength += self._color_value(hex_color) * proportion43                strength += self._color_value(hex_color) * proportion
4144
42            painted_so_far = seg_end45            painted_so_far = seg_end
4346
44        return strength47        return strength
nn48    
45    def _notify_tournament(self, other, winner, side):49    def _notify_tournament(self, other, winner, side):
46        if (self._tournament is not None and self._tournament is other._tournament):50        if (self._tournament is not None and self._tournament is other._tournament):
47            self._tournament._record_match(self, other, winner, side)51            self._tournament._record_match(self, other, winner, side)
nn52 
48    def _duel(self, other, top):53    def _duel(self, other, top):
49        if top:54        if top:
50            if self._broken_top or other._broken_top:55            if self._broken_top or other._broken_top:
51                raise TypeError("Broken side cannot be used again")56                raise TypeError("Broken side cannot be used again")
52        else:57        else:
53            if self._broken_bottom or other._broken_bottom:58            if self._broken_bottom or other._broken_bottom:
54                raise TypeError("Broken side cannot be used again")59                raise TypeError("Broken side cannot be used again")
5560
56        my_strength = self._side_strength(top=top)61        my_strength = self._side_strength(top=top)
57        other_strength = other._side_strength(top=top)62        other_strength = other._side_strength(top=top)
5863
59        if my_strength > other_strength:64        if my_strength > other_strength:
60            winner = self65            winner = self
61            loser = other66            loser = other
62        else:67        else:
63            winner = other68            winner = other
64            loser = self69            loser = self
6570
66        if top:71        if top:
67            loser._broken_top = True72            loser._broken_top = True
68        else:73        else:
69            loser._broken_bottom = True74            loser._broken_bottom = True
7075
71        self._notify_tournament(other, winner, "top" if top else "bottom")76        self._notify_tournament(other, winner, "top" if top else "bottom")
72        return winner77        return winner
nn78    
73    def __mul__(self, other):79    def __mul__(self, other):
74        return self._duel(other, top=True)80        return self._duel(other, top=True)
nn81    
75    def __matmul__(self, other):82    def __matmul__(self, other):
76        return self._duel(other, top=False)83        return self._duel(other, top=False)
nn84        
77class EggTournament:85class EggTournament:
78    def __init__(self):86    def __init__(self):
79        self._eggs_by_name = {}87        self._eggs_by_name = {}
80        self._names_by_egg = {}88        self._names_by_egg = {}
81        self._history = []89        self._history = []
82        self._wins = {}90        self._wins = {}
8391
84    def register(self, egg, name):92    def register(self, egg, name):
85        if egg._tournament is not None:93        if egg._tournament is not None:
86            raise ValueError("An egg cannot be registered in multiple tournaments")94            raise ValueError("An egg cannot be registered in multiple tournaments")
8795
88        if not name.isidentifier():96        if not name.isidentifier():
89            raise ValueError("Invalid registration name")97            raise ValueError("Invalid registration name")
9098
91        if name in self._eggs_by_name:99        if name in self._eggs_by_name:
92            raise ValueError(f"Egg with name {name} has already been registered")100            raise ValueError(f"Egg with name {name} has already been registered")
93101
94        self._eggs_by_name[name] = egg102        self._eggs_by_name[name] = egg
95        self._names_by_egg[egg] = name103        self._names_by_egg[egg] = name
96        self._wins[egg] = 0104        self._wins[egg] = 0
97        egg._tournament = self105        egg._tournament = self
98106
99    def _record_match(self, egg1, egg2, winner, side):107    def _record_match(self, egg1, egg2, winner, side):
100        self._history.append({108        self._history.append({
101            "eggs": frozenset((egg1, egg2)),109            "eggs": frozenset((egg1, egg2)),
102            "winner": winner,110            "winner": winner,
103            "side": side,111            "side": side,
104        })112        })
105        self._wins[winner] += 1113        self._wins[winner] += 1
106114
107    def __contains__(self, egg):115    def __contains__(self, egg):
108        return egg in self._names_by_egg116        return egg in self._names_by_egg
109117
110    def __getitem__(self, key):118    def __getitem__(self, key):
111        egg1 = egg2 = side = None119        egg1 = egg2 = side = None
112120
113        if isinstance(key, tuple) and len(key) == 3:121        if isinstance(key, tuple) and len(key) == 3:
114            egg1, egg2, side = key122            egg1, egg2, side = key
115        elif isinstance(key, slice):123        elif isinstance(key, slice):
116            egg1 = key.start124            egg1 = key.start
117            egg2 = key.stop125            egg2 = key.stop
118            side = key.step126            side = key.step
119        else:127        else:
120            raise KeyError128            raise KeyError
121129
122        pair = frozenset((egg1, egg2))130        pair = frozenset((egg1, egg2))
123131
124        for record in reversed(self._history):132        for record in reversed(self._history):
125            if record["eggs"] == pair and record["side"] == side:133            if record["eggs"] == pair and record["side"] == side:
126                return record["winner"]134                return record["winner"]
127135
128        raise KeyError136        raise KeyError
129137
130    def _ranking_groups(self):138    def _ranking_groups(self):
131        eggs = list(self._wins.keys())139        eggs = list(self._wins.keys())
132        eggs.sort(key=lambda egg: self._wins[egg], reverse=True)140        eggs.sort(key=lambda egg: self._wins[egg], reverse=True)
133141
134        groups = {}142        groups = {}
135        current_position = 0143        current_position = 0
136        previous_wins = None144        previous_wins = None
137145
138        for index, egg in enumerate(eggs):146        for index, egg in enumerate(eggs):
139            wins = self._wins[egg]147            wins = self._wins[egg]
140148
141            if previous_wins is None or wins < previous_wins:149            if previous_wins is None or wins < previous_wins:
142                current_position += 1150                current_position += 1
143151
144            groups.setdefault(current_position, set()).add(egg)152            groups.setdefault(current_position, set()).add(egg)
145            previous_wins = wins153            previous_wins = wins
146154
147        return groups155        return groups
148156
149    def _position_of_egg(self, target_egg):157    def _position_of_egg(self, target_egg):
150        groups = self._ranking_groups()158        groups = self._ranking_groups()
151159
152        for position, eggs in groups.items():160        for position, eggs in groups.items():
153            if target_egg in eggs:161            if target_egg in eggs:
154                return position162                return position
155163
156        raise AttributeError("Apologies, there is no such egg registered")164        raise AttributeError("Apologies, there is no such egg registered")
157165
158    def __rmatmul__(self, position):166    def __rmatmul__(self, position):
159        groups = self._ranking_groups()167        groups = self._ranking_groups()
160168
161        if position not in groups:169        if position not in groups:
162            raise IndexError170            raise IndexError
163171
164        eggs = groups[position]172        eggs = groups[position]
165        if len(eggs) == 1:173        if len(eggs) == 1:
166            return next(iter(eggs))174            return next(iter(eggs))
167        return eggs175        return eggs
168176
169    def __getattr__(self, name):177    def __getattr__(self, name):
170        if name not in self._eggs_by_name:178        if name not in self._eggs_by_name:
171            raise AttributeError("Apologies, there is no such egg registered")179            raise AttributeError("Apologies, there is no such egg registered")
172180
173        egg = self._eggs_by_name[name]181        egg = self._eggs_by_name[name]
n174        return {n182        return {"position": self._position_of_egg(egg), "victories": self._wins[egg]}
175            "position": self._position_of_egg(egg),
176            "victories": self._wins[egg],
177        }
178183
179184
180185
tt186 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op