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

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

6 точки общо

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

  1class Egg:
  2    HALF_PAINTED_LIMIT = 50.0
  3    FULL_PAINTED_LIMIT = 100.0
  4
  5    def __init__(self):
  6        self.color_counter = 0.0
  7        self._is_top_painted = False
  8        self._is_bottom_painted = False
  9        self.top_half = []
 10        self.bottom_half = []
 11        self.is_registered = False
 12        self.is_top_broken = False
 13        self.is_bottom_broken = False
 14        self.tournament = None
 15
 16    def __mul__(self, other):
 17        if not isinstance(other, Egg):
 18            raise TypeError("Parameter is not of type Egg")
 19        if other.is_top_broken or self.is_top_broken:
 20            raise TypeError("At least one of the eggs' top side is broken")
 21        if self.__get_half_painted(self.top_half) > self.__get_half_painted(other.top_half):
 22            other.is_top_broken = True
 23            winner = self
 24        else:
 25            self.is_top_broken = True
 26            winner = other
 27        if self.tournament is not None and self.tournament is other.tournament:
 28            self.tournament.save_fight(self, other, "top", winner)
 29        return winner
 30
 31    def __matmul__(self, other):
 32        if not isinstance(other, Egg):
 33            raise TypeError("Parameter is not of type Egg")
 34        if other.is_bottom_broken or self.is_bottom_broken:
 35            raise TypeError("At least one of the eggs' bottom side is broken")
 36        if self.__get_half_painted(self.bottom_half) > self.__get_half_painted(other.bottom_half):
 37            other.is_bottom_broken = True
 38            winner = self
 39        else:
 40            self.is_bottom_broken = True
 41            winner = other
 42        if self.tournament is not None and self.tournament is other.tournament:
 43            self.tournament.save_fight(self, other, "bottom", winner)
 44        return winner
 45
 46    def __get_half_painted(self, half):
 47        egg_strength = 0
 48        painted_percentage = 0
 49        for (hex_color, percentage) in half:
 50            half_painted_percentage = percentage / self.HALF_PAINTED_LIMIT
 51            egg_strength += Egg.convert_to_decimal(hex_color) * half_painted_percentage
 52            painted_percentage += half_painted_percentage
 53        return egg_strength, painted_percentage
 54
 55    @staticmethod
 56    def convert_to_decimal(color):
 57        r = int(color[0:2], 16)
 58        g = int(color[2:4], 16)
 59        b = int(color[4:6], 16)
 60        return r + g + b
 61
 62    def paint(self, *colors):
 63        if self.color_counter + sum(percentage for (_, percentage) in colors) > self.FULL_PAINTED_LIMIT:
 64            raise ValueError("The paint on this egg exceeds 100%.")
 65        for (hex_color, percentage) in colors:
 66            color = hex_color.upper()
 67            if self.color_counter + percentage <= self.HALF_PAINTED_LIMIT:
 68                self.top_half.append((color, percentage))
 69            elif self.color_counter + percentage > self.HALF_PAINTED_LIMIT and not self._is_top_painted:
 70                needed_percentage = self.HALF_PAINTED_LIMIT - self.color_counter
 71                part_for_top_half = min(percentage, needed_percentage)
 72                part_for_bottom_half = percentage - part_for_top_half
 73                self.top_half.append((color, part_for_top_half))
 74                self.bottom_half.append((color, part_for_bottom_half))
 75            elif self.color_counter + percentage <= self.FULL_PAINTED_LIMIT:
 76                self.bottom_half.append((color, percentage))
 77            if self.color_counter + percentage >= self.HALF_PAINTED_LIMIT:
 78                self._is_top_painted = True
 79            if self.color_counter + percentage >= self.FULL_PAINTED_LIMIT:
 80                self._is_bottom_painted = True
 81            self.color_counter += percentage
 82
 83
 84class EggTournament:
 85    def __init__(self):
 86        self.registered_eggs = {}
 87        self.fight_history = {}
 88
 89    def __getitem__(self, item):
 90        if isinstance(item, tuple):
 91            first_egg, second_egg, fight_side = item
 92        elif isinstance(item, slice):
 93            first_egg = item.start
 94            second_egg = item.stop
 95            fight_side = item.step
 96        else:
 97            raise TypeError("Parameter is not of type tuple or slice")
 98        if fight_side != "bottom" and fight_side != "top":
 99            raise KeyError(f"Invalid fight side {fight_side}")
100        return self.fight_history[(frozenset((first_egg, second_egg)), fight_side)]
101
102    def __contains__(self, egg):
103        return egg in self.registered_eggs.values()
104
105    def __getattr__(self, egg_name):
106        if egg_name not in self.registered_eggs:
107            raise AttributeError("Apologies, there is no such egg registered")
108        return {
109            "position": self._get_position(self.registered_eggs[egg_name]),
110            "victories": self._get_victories(self.registered_eggs[egg_name])
111        }
112
113    def __rmatmul__(self, position):
114        sorted_victories = self.__sort_by_victories()
115        ranking = list(sorted_victories.keys())
116        if position < 1 or position > len(ranking):
117            raise IndexError("The position is out of range")
118        if len(sorted_victories[ranking[position - 1]]) == 1:
119            return sorted_victories[ranking[position - 1]][0]
120        return set(sorted_victories[ranking[position - 1]])
121
122    def __sort_by_victories(self):
123        victories_by_egg = {}
124        for egg in self.registered_eggs.values():
125            victories = self._get_victories(egg)
126            if victories in victories_by_egg:
127                victories_by_egg[victories].append(egg)
128            else:
129                victories_by_egg[victories] = [egg]
130        return dict(sorted(victories_by_egg.items(), reverse = True))
131
132    def _get_victories(self, egg):
133        victories = 0
134        for winner in self.fight_history.values():
135            if winner is egg:
136                victories += 1
137        return victories
138
139    def _get_position(self, egg):
140        sorted_victories = self.__sort_by_victories()
141        ranking = list(sorted_victories.keys())
142        return ranking.index(self._get_victories(egg)) + 1
143
144    def save_fight(self, first_egg, second_egg, fight_side, winner):
145        self.fight_history[(frozenset((first_egg, second_egg)), fight_side)] = winner
146
147    def register(self, egg, name):
148        if egg.is_registered == True and egg.tournament is not None:
149            raise ValueError("An egg cannot be registered in multiple tournaments")
150        if not name.isidentifier():
151            raise ValueError("Invalid registration name")
152        if name in self.registered_eggs:
153            raise ValueError(f"Egg with name {name} has already been registered")
154        self.registered_eggs[name] = egg
155        egg.is_registered = True
156        egg.tournament = self

..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.001s

OK

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