Домашни > Великденско домашно > Решения > Решението на Гергана Панделиева

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

5 точки общо

40 успешни теста
6 неуспешни теста
Код (Моля следващата лекция да преговорим за СРЕДИ)
Скрий всички коментари

  1class Egg:
  2    def __init__(self):
  3        self.paint_layers = [] 
  4        self.total = 0.0
  5        self.broken_top = False
  6        self.broken_bottom = False
  7        self.tournament = None
  8
  9    def _color_value(self, hex_color):
 10        hex_color = hex_color.upper()
 11        r = int(hex_color[0:2], 16)
 12        g = int(hex_color[2:4], 16)
 13        b = int(hex_color[4:6], 16)
 14        return r + g + b
 15
 16    def paint(self, *args):
 17        total_new = sum(p for c, p in args)
 18
 19        if self.total + total_new > 100:
 20            raise ValueError("Overpaint")
 21
 22        for color, perc in args:
 23            val = self._color_value(color)
 24            self.paint_layers.append((val, perc))
 25            self.total += perc
 26
 27    def _half_strength(self, half):
 28        limit = 50.0
 29        current = 0.0
 30        strength = 0.0
 31
 32        for val, perc in self.paint_layers:
 33            if half == "top":
 34                if current >= 50:
 35                    break
 36                usable = min(perc, 50 - current)
 37                strength += val * (usable / 100)
 38                current += perc
 39            else:
 40                if current + perc <= 50:
 41                    current += perc
 42                    continue
 43                overlap_start = max(current, 50)
 44                overlap = min(current + perc, 100) - overlap_start
 45                if overlap > 0:
 46                    strength += val * (overlap / 100)
 47                current += perc
 48
 49        return strength
 50
 51    def _fight(self, other, side):
 52        if side == "top":
 53            if self.broken_top or other.broken_top:
 54                raise TypeError("Broken egg")
 55        else:
 56            if self.broken_bottom or other.broken_bottom:
 57                raise TypeError("Broken egg")
 58
 59        s1 = self._half_strength(side)
 60        s2 = other._half_strength(side)
 61
 62        winner = self if s1 > s2 else other
 63        loser = other if winner is self else self
 64
 65        if side == "top":
 66            loser.broken_top = True
 67        else:
 68            loser.broken_bottom = True
 69        if self.tournament and self.tournament is other.tournament:
 70            self.tournament._record(self, other, side, winner)
 71
 72        return winner
 73
 74    def __mul__(self, other): 
 75        #*
 76        return self._fight(other, "top")
 77
 78    def __matmul__(self, other):
 79        #@
 80        return self._fight(other, "bottom")
 81
 82
 83class EggTournament:
 84    def __init__(self):
 85        self.eggs = {}
 86        self.reverse = {}
 87        self.history = {}  
 88        self.wins = {}
 89
 90    def register(self, egg, name):
 91        if not name.isidentifier():
 92            raise ValueError("Invalid registration name")
 93        if egg.tournament:
 94            raise ValueError("An egg cannot be registered in more than one tournament")
 95        if name in self.eggs:
 96            raise ValueError(f"Egg with name {name} has already been registered")
 97        self.eggs[name] = egg
 98        self.reverse[egg] = name
 99        self.wins[egg] = 0
100        egg.tournament = self
101
102    def _record(self, e1, e2, side, winner):
103        key = (frozenset([e1, e2]), side)
104        #I saw that it would be better than just "set" in this case
105        self.history[key] = winner
106        self.wins[winner] += 1
107
108    def __getitem__(self, key):
109        if isinstance(key, tuple):
110            e1, e2, side = key
111        else:
112            e1, e2, side = key.start, key.stop, key.step
113        #I searched extra for reading with ':' as a separator
114        k = (frozenset([e1, e2]), side)
115        if k not in self.history:
116            raise KeyError
117
118        return self.history[k]
119
120    def __rmatmul__(self, pos):
121        sorted_eggs = sorted(self.wins.items(), key=lambda x: -x[1])
122
123        result = {}
124        rank = 1
125        prev = None
126        group = []
127
128        for egg, w in sorted_eggs:
129            if prev is None or w == prev:
130                group.append(egg)
131            else:
132                result[rank] = set(group)
133                rank += 1
134                group = [egg]
135            prev = w
136
137        if group:
138            result[rank] = set(group)
139        if pos not in result:
140            raise IndexError
141
142        return result[pos]
143
144    def __getattr__(self, name):
145        if name not in self.eggs:
146            raise AttributeError("There is no such egg registered")
147        egg = self.eggs[name]
148        wins = self.wins[egg]
149
150        sorted_eggs = sorted(self.wins.items(), key=lambda x: -x[1])
151        rank = 1
152        prev = None
153
154        for i, (e, w) in enumerate(sorted_eggs):
155            if prev is not None and w < prev:
156                rank += 1
157            if e == egg:
158                return {"position": rank, "victories": wins}
159            prev = w
160
161    def __contains__(self, egg):
162        return egg in self.reverse

.....................F..F....F.......F..FF....
======================================================================
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 0x7e086bb8cde0> is not <solution.Egg object at 0x7e086bb8cc90>

======================================================================
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 0x7e086bb8cd70>} is not <solution.Egg object at 0x7e086bb8cd70>

======================================================================
FAIL: test_egg_cannot_be_registered_in_second_tournament (test.TestEggTournament.test_egg_cannot_be_registered_in_second_tournament)
Registering an egg in a second tournament should raise a ValueError.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 344, in test_egg_cannot_be_registered_in_second_tournament
self.assertEqual(
~~~~~~~~~~~~~~~~^
str(context.exception),
^^^^^^^^^^^^^^^^^^^^^^^
"An egg cannot be registered in multiple tournaments",
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
AssertionError: 'An egg cannot be registered in more than one tournament' != 'An egg cannot be registered in multiple tournaments'
- An egg cannot be registered in more than one tournament
? ^^ ---------
+ An egg cannot be registered in multiple tournaments
? ^^^^^^ +

======================================================================
FAIL: test_missing_egg_attribute_raises_attribute_error (test.TestEggTournament.test_missing_egg_attribute_raises_attribute_error)
Accessing an unregistered egg as an attribute should raise an AttributeError.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 586, in test_missing_egg_attribute_raises_attribute_error
self.assertEqual(
~~~~~~~~~~~~~~~~^
str(context.exception),
^^^^^^^^^^^^^^^^^^^^^^^
"Apologies, there is no such egg registered",
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
AssertionError: 'There is no such egg registered' != 'Apologies, there is no such egg registered'
- There is no such egg registered
? ^
+ Apologies, there is no such egg registered
? ^^^^^^^^^^^^

======================================================================
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 0x7e086b8a11d0>} is not <solution.Egg object at 0x7e086b8a11d0>

======================================================================
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 0x7e086b8a12b0>} is not <solution.Egg object at 0x7e086b8a12b0>

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

FAILED (failures=6)

Дискусия
Гергана Панделиева
14.04.2026 23:00

Така ми дойде за коментара под домашното. А за гадните имена на променливите така очевидно съм забравила да ги оставя от пишенето и рънването на отделни функции уж само за “тестването”, ама излезе че така съм си ги оставила щом съм видяла, че работи, за друг път ще внимавам 🫡
Виктор Бечев
12.04.2026 22:18

Отвъд имената на променливите е добре - използвала си правилните питонизми и не си прекалила с `if`-овете и `for`-овете. И най-важното - предала си го **дни** преди крайния срок.
Виктор Бечев
12.04.2026 22:10

Интересно място да ни оставиш коментар за това какво да преговорим. 😂
История
Това решение има само една версия.