Домашни > Великденско домашно > Решения > Решението на Ариф Мехмедали

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

6 точки общо

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

  1class Egg:
  2    def __init__(self):
  3        self._percentage = 0
  4        self.top_pigment = None
  5        self.bot_pigment = None
  6        self.top_broken = False
  7        self.bot_broken = False
  8        self._tournament = None
  9
 10    def __mul__(self, other):
 11        if self.top_broken or other.top_broken:
 12            raise TypeError
 13        
 14        winner = self
 15        if self.top_pigment == None:
 16            self.top_broken = True
 17            winner = other
 18        elif other.top_pigment == None:
 19            other.top_broken = True
 20            winner = self
 21        elif self.top_pigment > other.top_pigment:
 22            other.top_broken = True
 23            winner = self
 24        else:
 25            self.top_broken = True
 26            winner = other
 27        
 28        if self._tournament and other._tournament and self._tournament == other._tournament:
 29            self._tournament.wins[winner] += 1
 30            self._tournament.fight_history["top"][(self, other)] = winner
 31
 32        return winner
 33
 34    
 35    def __matmul__(self, other):
 36        if self.bot_broken or other.bot_broken:
 37            raise TypeError
 38
 39        winner = self
 40        if self.bot_pigment == None:
 41            self.bot_broken = True
 42            winner = other
 43        elif other.bot_pigment == None:
 44            other.bot_broken = True
 45            winner = self
 46        elif self.bot_pigment > other.bot_pigment:
 47            other.bot_broken = True
 48            winner = self  
 49        else:
 50            self.bot_broken = True
 51            winner = other
 52
 53        if self._tournament and other._tournament and self._tournament == other._tournament:
 54            self._tournament.wins[winner] += 1
 55            self._tournament.fight_history["bottom"][(self, other)] = winner
 56
 57        return winner
 58
 59    def paint(self, *colors):
 60        total_percentage = self._percentage
 61        for _, percentage in colors:
 62            total_percentage += percentage
 63        if total_percentage > 100:
 64            raise ValueError
 65
 66        for color, percentage in colors:
 67            pigment = int(color[:2], 16) + int(color[2:4], 16) + int(color[4:], 16)
 68
 69            if self._percentage < 50:
 70                left = 50 - self._percentage
 71                if percentage <= left:
 72                    self._percentage += percentage
 73
 74                    # TOP
 75                    if self.top_pigment == None:
 76                        self.top_pigment = pigment * 2 * percentage / 100
 77                    else: 
 78                        self.top_pigment += pigment * 2 * percentage / 100
 79                else:
 80                    self._percentage += percentage
 81                    
 82                    #TOP
 83                    if self.top_pigment == None:
 84                        self.top_pigment = pigment * 2 * left / 100
 85                    else: 
 86                        self.top_pigment += pigment * 2 * left / 100
 87                    
 88                    #BOT
 89                    if self.bot_pigment == None:
 90                        self.bot_pigment = pigment * (percentage - left) / 100 * 2
 91                    else:
 92                        self.bot_pigment += pigment * (percentage - left) / 100 * 2
 93            else:
 94                self._percentage += percentage
 95                
 96                #BOT
 97                if self.bot_pigment == None:
 98                    self.bot_pigment = pigment * percentage / 100 * 2
 99                else:
100                    self.bot_pigment += pigment * percentage / 100 * 2
101
102
103class EggTournament:
104    all_registered_eggs = set()
105
106    def __init__(self):
107        self.eggs = {} #nick : egg, wins
108        self.egg_nick = {} #egg : nick
109        self.fight_history = {"top": {}, "bottom": {}} #(egg1, egg2) = winner
110        self.wins = {} #egg: wins
111
112    def register(self, egg, nick):
113        if not nick.isidentifier():
114            raise ValueError("Invalid registration name")
115        
116        if nick in self.eggs:
117            raise ValueError(f"Egg with name {nick} has already been registered")
118        
119        if egg in EggTournament.all_registered_eggs:
120            raise ValueError("An egg cannot be registered in multiple tournaments")
121
122        self.eggs[nick] = egg
123        self.egg_nick[egg] = nick
124        egg._tournament = self
125        self.wins[egg] = 0
126        EggTournament.all_registered_eggs.add(egg)
127
128    def __getitem__(self, key):
129        if isinstance(key, slice):
130            egg1 = key.start
131            egg2 = key.stop
132            pos = key.step
133        elif isinstance(key, tuple):
134            egg1, egg2, pos = key
135
136        fights = self.fight_history[pos]
137        try:
138            return fights[(egg1, egg2)]
139        except KeyError:
140            return fights[(egg2, egg1)]
141
142    def ranking(self):
143        result = {}
144        sorted_wins = sorted(self.wins.items(), key = lambda x : x[1], reverse=True)
145
146        rank = 1
147        last = -1
148        for egg, wins in sorted_wins:
149            if last == -1:
150                last = wins
151                result[rank] = {egg}
152            elif last == wins:
153                result[rank].add(egg)
154            elif last != wins:
155                rank += 1
156                result[rank] = {egg}
157                last = wins
158
159        return result
160    
161
162    def __rmatmul__(self, pos):
163        ranking = self.ranking()
164
165        if not pos in ranking:
166            raise IndexError
167        
168        return ranking[pos]
169    
170    def __getattr__(self, name):
171        if not name in self.eggs:
172            raise AttributeError("Apologies, there is no such egg registered")
173        
174        egg = self.eggs[name]
175
176        wins = self.wins.get(egg, 0)
177        ranking = self.ranking()
178        position = -1
179        for pos, eggs in ranking.items():
180            if egg in eggs:
181                position = pos
182                break
183
184        return {"position": position, "victories": wins}
185
186    def __contains__(self, egg):
187        return egg in self.egg_nick

........................F...............FF....
======================================================================
FAIL: test_collision_between_two_registered_eggs_is_recorded (test.TestEggTournament.test_collision_between_two_registered_eggs_is_recorded)
A collision between two registered eggs should be recorded in the tournament.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 373, in test_collision_between_two_registered_eggs_is_recorded
self.assertIs(1 @ tournament, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: {<solution.Egg object at 0x7aa0faf51d50>} is not <solution.Egg object at 0x7aa0faf51d50>

======================================================================
FAIL: test_ranking_unique_position_returns_single_egg (test.TestEggTournament.test_ranking_unique_position_returns_single_egg)
Looking up a unique ranking position should return a single egg.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 478, in test_ranking_unique_position_returns_single_egg
self.assertIs(1 @ tournament, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: {<solution.Egg object at 0x7aa0fad2ce50>} is not <solution.Egg object at 0x7aa0fad2ce50>

======================================================================
FAIL: test_ranking_uses_dense_ranking_without_skipping_places (test.TestEggTournament.test_ranking_uses_dense_ranking_without_skipping_places)
Looking up ranking positions should use dense ranking without skipping places.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 514, in test_ranking_uses_dense_ranking_without_skipping_places
self.assertIs(1 @ tournament, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: {<solution.Egg object at 0x7aa0fad2cf50>} is not <solution.Egg object at 0x7aa0fad2cf50>

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

FAILED (failures=3)

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