Домашни > Великденско домашно > Решения > Решението на Велислава Спасова

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

6 точки общо

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

  1import keyword
  2
  3class Egg:
  4
  5    colored_percantage = 0
  6
  7    def __init__(self):
  8        self.colored_percantage = 0
  9        self.colors = []
 10        self.sideA=0
 11        self.sideB=0
 12        self.sideA_broken = False
 13        self.sideB_broken = False
 14        self.tournament = None
 15
 16    def paint(self, *args):
 17        total_percantage = sum(percentage for _, percentage in args)
 18
 19        if self.colored_percantage + total_percantage > 100:
 20            raise ValueError("Яйцето не може да бъде бядисано на повече от 100%!")
 21
 22        for hex_color, percentage in args:
 23            self.colors.append((hex_color.upper(),percentage))
 24            self.colored_percantage += percentage
 25        self.shell_strength()
 26
 27    def color_strength(self, color):
 28        sum_colors = 0
 29        while color != "":
 30            rgb = color[-2:]
 31            sum_colors += int(rgb,16)
 32            color = color[:-2]
 33        return sum_colors
 34
 35    def shell_strength(self):
 36        curr_perc = 0
 37        self.sideA = 0
 38        self.sideB = 0
 39        self.sideA_coverage = 0
 40        self.sideB_coverage = 0
 41
 42        for hex_color, percentage in self.colors:
 43            if curr_perc < 50 and curr_perc + percentage <= 50:
 44                self.sideA += self.color_strength(hex_color) * percentage / 50
 45                curr_perc += percentage
 46                self.sideA_coverage += percentage
 47            elif curr_perc < 50 and curr_perc + percentage >= 50:
 48                top = 50 - curr_perc
 49                bottom = percentage - top
 50                self.sideA += self.color_strength(hex_color) * top / 50
 51                self.sideA_coverage += top
 52                self.sideB += self.color_strength(hex_color) * bottom / 50
 53                self.sideB_coverage += bottom
 54                curr_perc += percentage
 55            else:
 56                self.sideB += self.color_strength(hex_color) * percentage / 50
 57                curr_perc += percentage
 58                self.sideB_coverage += percentage
 59
 60    def set_tournament(self, tournament):
 61        self.tournament = tournament
 62
 63    def top_power(self):
 64        if self.sideA_coverage == 0:
 65            return (-1, 0)
 66        return (0, self.sideA)
 67
 68    def bottom_power(self):
 69        if self.sideB_coverage == 0:
 70            return (-1, 0)
 71        return (0, self.sideB)
 72
 73    def __mul__(self, other):
 74        if self.sideA_broken or other.sideA_broken:
 75            raise TypeError("Някое яйце вече е счупено от тази страна")
 76        winner = None
 77        if self.top_power() > other.top_power():
 78            other.sideA_broken = True
 79            winner = self
 80        else: 
 81            self.sideA_broken = True
 82            winner = other
 83        if self.tournament is not None and self.tournament is other.tournament:
 84            self.tournament._register_battle(self, other, "top", winner)
 85        return winner
 86
 87    def __matmul__(self, other):
 88        if self.sideB_broken or other.sideB_broken:
 89            raise TypeError("Някое яйце вече е счупено от тази страна")
 90        winner = None
 91        if self.bottom_power() > other.bottom_power():
 92            other.sideB_broken = True
 93            winner = self
 94        else: 
 95            self.sideB_broken = True
 96            winner = other
 97        if self.tournament is not None and self.tournament is other.tournament:
 98            self.tournament._register_battle(self, other, "bottom", winner)
 99        return winner
100
101class EggTournament:
102    def __init__(self):
103        self.eggs = {}
104        self.history = {}
105        self.leaderboard = {}
106
107    def register(self, egg, nickname):
108        if nickname in self.eggs.values():
109            raise ValueError(f"Egg with name {nickname} has already been registered")
110        if egg.tournament is not None:
111            raise ValueError("An egg cannot be registered in multiple tournaments")
112        if not isinstance(nickname, str) or not nickname.isidentifier() or keyword.iskeyword(nickname):
113            raise ValueError("Invalid registration name")
114        self.eggs[egg] = nickname
115        self.leaderboard[egg] = 0
116        egg.set_tournament(self)
117    
118    def _battle_key(self, egg1, egg2, position):
119        if id(egg1) < id(egg2):
120            return (egg1, egg2, position)
121        return (egg2, egg1, position)
122    
123    def _register_battle(self, egg1, egg2, battle_type, winner):
124        if egg1 not in self.eggs or egg2 not in self.eggs:
125            return
126        key = self._battle_key(egg1, egg2, battle_type)
127        self.history[key] = winner
128        self.leaderboard[winner]+= 1
129    
130    def __getitem__(self, item):
131        if isinstance(item, tuple):
132            egg1, egg2, battle_type = item
133        elif isinstance(item, slice):
134            egg1 = item.start
135            egg2 = item.stop
136            battle_type = item.step
137        else:
138            raise KeyError("Not given in the right format")
139        key = self._battle_key(egg1, egg2, battle_type)
140        if key in self.history:
141            return self.history[key]
142        else:
143            raise KeyError("No such battle")
144        
145    def _ranking_by_position(self):
146        sorted_items = sorted( self.leaderboard.items(),
147                               key=lambda x: x[1],
148                               reverse=True
149        )
150
151        result = {}
152        current_rank = 0
153        last_score = None
154
155        for egg, wins in sorted_items:
156            if wins != last_score:
157                current_rank += 1
158                result[current_rank] = set()
159                last_score = wins
160
161            result[current_rank].add(egg)
162
163        return result
164    
165    def __rmatmul__(self, index):
166        sorted_leaderboard = self._ranking_by_position()
167        if index not in sorted_leaderboard:
168            raise IndexError("Index doesn't exist in the leaderboard")
169        ranked = sorted_leaderboard[index]
170        if len(ranked) == 1:
171            return next(iter(ranked))
172        return ranked
173    
174    def __getattr__(self, name):
175       for egg, nickname in self.eggs.items():
176            if nickname == name:
177                sorted_leaderboard = self._ranking_by_position()
178                vic = self.leaderboard[egg]
179                for position, eggs in sorted_leaderboard.items():
180                    if egg in eggs:
181                        return {"position": position, "victories": vic}
182        
183       raise AttributeError("Apologies, there is no such egg registered")
184    
185    def __contains__(self, item):
186        return item in self.eggs

.....................E........................
======================================================================
ERROR: 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 200, in test_unpainted_half_loses_to_half_painted_black
self.assertIs(unpainted_egg * black_egg, black_egg)
~~~~~~~~~~~~~~^~~~~~~~~~~
File "/tmp/solution.py", line 77, in __mul__
if self.top_power() > other.top_power():
~~~~~~~~~~~~~~^^
File "/tmp/solution.py", line 64, in top_power
if self.sideA_coverage == 0:
^^^^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute 'sideA_coverage'

----------------------------------------------------------------------
Ran 46 tests in 0.003s

FAILED (errors=1)

Дискусия
История
Това решение има само една версия.