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

Резултати
1 точки от тестове
2 точки от учител

3 точки общо

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

  1from collections import defaultdict
  2
  3class Egg:
  4    __MAX_SPACE = 50.0
  5    __BASE_HARDNESS = 0.0
  6
  7    def __init__(self):
  8        self.tournament = None
  9        self.victories_in_tournament = 0
 10        self.battles_history = []
 11        self.top_hardness = Egg.__BASE_HARDNESS
 12        self.bottom_hardness = Egg.__BASE_HARDNESS
 13        self.__colors = []
 14        self.__top_not_painted_space = Egg.__MAX_SPACE
 15        self.__bottom_not_painted_space = Egg.__MAX_SPACE
 16
 17    def lost(self, which_half):
 18        setattr(self, which_half, None)
 19
 20    def __to_numeric_rgb(self, color):
 21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))
 22
 23    def __give_hardness(self, which_half, *color):
 24        if which_half == "top":
 25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
 26        elif which_half == "bottom":
 27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
 28
 29    def paint(self, *colors):
 30        for color in colors:
 31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:
 32                raise ValueError("Not enough space to paint the egg with the given color.")
 33            elif self.__top_not_painted_space >= color[1]:
 34                self.__give_hardness("top", color[0].upper(), color[1])
 35                self.__top_not_painted_space -= color[1]
 36                self.__colors.append(color)
 37            elif self.__top_not_painted_space < color[1]:
 38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)
 39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)
 40                self.__top_not_painted_space = 0.0
 41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)
 42                self.__colors.append(color)
 43            elif self.__top_not_painted_space == 0.0:
 44                self.__give_hardness("bottom", color[0].upper(), color[1])
 45                self.__bottom_not_painted_space -= color[1]
 46                self.__colors.append(color)
 47
 48    def __add_battle(self, opponent, which_half, result):
 49        self.battles_history.append((opponent, which_half, result))
 50        if result == "win":
 51            self.victories_in_tournament += 1
 52
 53    def return_battle_winner(self, opponent, which_half):
 54        for battle in self.battles_history:
 55            if battle[0] is opponent and battle[1] == which_half:
 56                return self if battle[2] == "win" else opponent
 57        else:
 58            return None
 59
 60    def __mul__(self, other):
 61        if not isinstance(other, Egg):
 62            raise ValueError("Can only multiply with another Egg instance.")
 63        
 64        if self.top_hardness is None or other.top_hardness is None:
 65            raise TypeError("Спукана работа :(")
 66        
 67        if self.top_hardness > other.top_hardness:
 68            if self.tournament is other.tournament and self.tournament:
 69                self.__add_battle(other, "top", "win")
 70                other.__add_battle(self, "top", "lose")
 71            other.lost("top_hardness")
 72        elif self.top_hardness < other.top_hardness:
 73            if self.tournament is other.tournament and self.tournament:
 74                self.__add_battle(other, "top", "lose")
 75                other.__add_battle(self, "top", "win")
 76            self.lost("top_hardness")
 77        elif self.top_hardness == 0.0:
 78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:
 79                if self.tournament is other.tournament and self.tournament:
 80                    self.__add_battle(other, "top", "win")
 81                    other.__add_battle(self, "top", "lose")
 82                other.lost("top_hardness")
 83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:
 84                if self.tournament is other.tournament and self.tournament:
 85                    self.__add_battle(other, "top", "lose")
 86                    other.__add_battle(self, "top", "win")
 87                self.lost("top_hardness")
 88
 89    def __matmul__(self, other):
 90        if not isinstance(other, Egg):
 91            raise ValueError("Can only multiply with another Egg instance.")
 92        
 93        if self.bottom_hardness is None or other.bottom_hardness is None:
 94            raise TypeError("Спукана работа :(")
 95        
 96        if self.bottom_hardness > other.bottom_hardness:
 97            if self.tournament is other.tournament and self.tournament:
 98                self.__add_battle(other, "bottom", "win")
 99                other.__add_battle(self, "bottom", "lose")
100            other.lost("bottom_hardness")
101        elif self.bottom_hardness < other.bottom_hardness:
102            if self.tournament is other.tournament and self.tournament:
103                self.__add_battle(other, "bottom", "lose")
104                other.__add_battle(self, "bottom", "win")
105            self.lost("bottom_hardness")
106        elif self.bottom_hardness == 0.0:
107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:
108                if self.tournament is other.tournament and self.tournament:
109                    self.__add_battle(other, "bottom", "win")
110                    other.__add_battle(self, "bottom", "lose")
111                other.lost("bottom_hardness")
112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:
113                if self.tournament is other.tournament and self.tournament:
114                    self.__add_battle(other, "bottom", "lose")
115                    other.__add_battle(self, "bottom", "win")
116                self.lost("bottom_hardness")
117
118
119class EggTournament:
120
121    def __init__(self):
122        self.__registered_eggs = {}
123
124    @property
125    def __ranking(self):
126        grouped_by_victories = defaultdict(list)
127        for name, egg in self.__registered_eggs.items():
128            grouped_by_victories[egg.victories_in_tournament].append(name)
129
130        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)
131        result = {}
132        position = 1
133        for victories in sorted_victories:
134            result[position] = grouped_by_victories[victories]
135            position += 1
136        return result
137
138    def register(self, egg, name):
139        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):
140            raise ValueError(f"Egg with name {name} has already been registered")
141        elif egg.tournament:
142            raise ValueError(f"An egg cannot be registered in multiple tournaments")
143        elif not name.isidentifier():
144            raise ValueError(f"Invalid registration name")
145        else:
146            self.__registered_eggs[name] = egg
147            egg.tournament = self
148
149    def __getitem__(self, key):
150        if isinstance(key, slice):
151            egg1, egg2, which_half = key.start, key.stop, key.step
152        else:
153            egg1, egg2, which_half = key
154        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():
155            raise KeyError("There is no such battle in the tournament")
156        if egg1.return_battle_winner(egg2, which_half) is None:
157            raise KeyError("There is no such battle in the tournament")
158        return egg1.return_battle_winner(egg2, which_half)
159            
160    def __rmatmul__(self, position):
161        if position in self.__ranking.keys():
162            return {self.__registered_eggs[name] for name in self.__ranking[position]}
163        else:
164            raise IndexError("There is no such position in the ranking table")
165        
166    def __getattr__(self, name):
167        for pos in self.__ranking.keys():
168            if name in self.__ranking[pos]:
169                rank = pos
170                break
171        else:
172            raise AttributeError("Apologies, there is no such egg registered")
173        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")
174    
175    def __contains__(self, egg):
176        return egg in self.__registered_eggs.values()

FFFFFFFFFEEFEF...FFFFFFFFF..F..F.FFFF.FFFF..FF
======================================================================
ERROR: test_paint_chunk_crossing_50_percent_boundary_is_split_correctly (test.TestEgg.test_paint_chunk_crossing_50_percent_boundary_is_split_correctly)
Painting a chunk across the half boundary should split it correctly between the two halves.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 135, in test_paint_chunk_crossing_50_percent_boundary_is_split_correctly
egg = self.make_egg(("FFFFFF", 40.0), ("000000", 20.0), ("FF0000", 40.0))
File "/tmp/test.py", line 11, in make_egg
egg.paint(*paint_chunks)
~~~~~~~~~^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 32, in paint
raise ValueError("Not enough space to paint the egg with the given color.")
ValueError: Not enough space to paint the egg with the given color.

======================================================================
ERROR: test_paint_exactly_to_100_percent_is_allowed (test.TestEgg.test_paint_exactly_to_100_percent_is_allowed)
Painting an egg exactly to 100 percent should not raise an error.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 37, in test_paint_exactly_to_100_percent_is_allowed
egg.paint(("FFFFFF", 1.0))
~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 32, in paint
raise ValueError("Not enough space to paint the egg with the given color.")
ValueError: Not enough space to paint the egg with the given color.

======================================================================
ERROR: test_paint_multiple_calls_can_cross_50_percent_boundary (test.TestEgg.test_paint_multiple_calls_can_cross_50_percent_boundary)
Painting an egg across the half boundary in multiple calls should split the halves correctly.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 146, in test_paint_multiple_calls_can_cross_50_percent_boundary
egg.paint(("FF0000", 40.0))
~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 32, in paint
raise ValueError("Not enough space to paint the egg with the given color.")
ValueError: Not enough space to paint the egg with the given color.

======================================================================
FAIL: test_bottom_collision_returns_egg_with_greater_bottom_strength (test.TestEgg.test_bottom_collision_returns_egg_with_greater_bottom_strength)
A bottom collision should return the egg with the greater bottom strength.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 177, in test_bottom_collision_returns_egg_with_greater_bottom_strength
self.assertIs(stronger_egg @ weaker_egg, stronger_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f852ba0>

======================================================================
FAIL: test_breaking_one_side_does_not_prevent_using_the_other_side (test.TestEgg.test_breaking_one_side_does_not_prevent_using_the_other_side)
Breaking one side of an egg should not prevent using the other side.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 287, in test_breaking_one_side_does_not_prevent_using_the_other_side
self.assertIs(first_egg * second_egg, second_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f82f490>

======================================================================
FAIL: test_broken_side_raises_type_error_regardless_of_operand_position (test.TestEgg.test_broken_side_raises_type_error_regardless_of_operand_position)
Using a broken side in a collision should raise a TypeError regardless of operand position.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 257, in test_broken_side_raises_type_error_regardless_of_operand_position
self.assertIs(broken_top_egg * top_winner, top_winner)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f680950>

======================================================================
FAIL: test_collision_result_is_independent_of_operand_order (test.TestEgg.test_collision_result_is_independent_of_operand_order)
Swapping the egg operands should not change the collision winner.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 212, in test_collision_result_is_independent_of_operand_order
self.assertIs(top_first_egg * top_second_egg, top_first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f7fb9b0>

======================================================================
FAIL: test_collision_with_partially_painted_eggs (test.TestEgg.test_collision_with_partially_painted_eggs)
Partially painted eggs should collide correctly from both sides.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 192, in test_collision_with_partially_painted_eggs
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f83da50>

======================================================================
FAIL: test_failed_paint_overflow_does_not_change_egg_state (test.TestEgg.test_failed_paint_overflow_does_not_change_egg_state)
Failing to paint an egg because of overflow should not change its state.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 91, in test_failed_paint_overflow_does_not_change_egg_state
self.assertIs(reference_egg * reference_top_opponent, reference_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f7d2990>

======================================================================
FAIL: test_losing_side_becomes_unusable (test.TestEgg.test_losing_side_becomes_unusable)
Losing a collision should make the losing side unusable.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 238, in test_losing_side_becomes_unusable
self.assertIs(top_loser * top_winner, top_winner)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f89d490>

======================================================================
FAIL: test_paint_boundary_exactly_at_50_percent (test.TestEgg.test_paint_boundary_exactly_at_50_percent)
Painting an egg exactly to the half boundary should keep the two halves separate.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 130, in test_paint_boundary_exactly_at_50_percent
self.assertIs(egg * opponent, egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6749f0>

======================================================================
FAIL: test_paint_can_be_called_multiple_times (test.TestEgg.test_paint_can_be_called_multiple_times)
Painting an egg in multiple calls should preserve the full painting order.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 54, in test_paint_can_be_called_multiple_times
self.assertIs(egg * top_opponent, egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6749f0>

======================================================================
FAIL: test_paint_is_case_insensitive_for_hex_colors (test.TestEgg.test_paint_is_case_insensitive_for_hex_colors)
Painting an egg with lowercase and uppercase hex colors should produce the same behavior.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 111, in test_paint_is_case_insensitive_for_hex_colors
self.assertIs(lower_case_egg * lower_case_top_opponent, lower_case_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6749f0>

======================================================================
FAIL: test_paint_order_of_color_chunks_matters (test.TestEgg.test_paint_order_of_color_chunks_matters)
Painting the same colors in different orders should change the collision result.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 122, in test_paint_order_of_color_chunks_matters
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f674e10>

======================================================================
FAIL: test_paint_overflow_with_multiple_colors_should_not_change_the_egg (test.TestEgg.test_paint_overflow_with_multiple_colors_should_not_change_the_egg)
Failing to overpaint an egg with multiple colors should not change the egg.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 163, in test_paint_overflow_with_multiple_colors_should_not_change_the_egg
self.assertIs(egg @ bottom_opponent, bottom_opponent)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f674c00>

======================================================================
FAIL: test_paint_single_color_full_egg (test.TestEgg.test_paint_single_color_full_egg)
A fully painted single-color egg should win collisions against a weaker egg from both sides.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 30, in test_paint_single_color_full_egg
self.assertIs(egg * opponent, egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6750d0>

======================================================================
FAIL: test_same_two_eggs_can_have_different_winners_for_top_and_bottom (test.TestEgg.test_same_two_eggs_can_have_different_winners_for_top_and_bottom)
The same two eggs should be able to have different winners for top and bottom collisions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 184, in test_same_two_eggs_can_have_different_winners_for_top_and_bottom
self.assertIs(first_egg * second_egg, second_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6750d0>

======================================================================
FAIL: test_top_collision_returns_egg_with_greater_top_strength (test.TestEgg.test_top_collision_returns_egg_with_greater_top_strength)
A top collision should return the egg with the greater top strength.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 170, in test_top_collision_returns_egg_with_greater_top_strength
self.assertIs(stronger_egg * weaker_egg, stronger_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f674f70>

======================================================================
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 200, in test_unpainted_half_loses_to_half_painted_black
self.assertIs(unpainted_egg * black_egg, black_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6747e0>

======================================================================
FAIL: test_winner_side_does_not_become_broken (test.TestEgg.test_winner_side_does_not_become_broken)
Winning a collision should not break the winning side.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 302, in test_winner_side_does_not_become_broken
self.assertIs(winner_egg * first_loser, winner_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6750d0>

======================================================================
FAIL: test_collision_between_registered_and_unregistered_egg_is_not_recorded (test.TestEggTournament.test_collision_between_registered_and_unregistered_egg_is_not_recorded)
A collision between a registered and an unregistered egg should not be recorded in the tournament.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 392, in test_collision_between_registered_and_unregistered_egg_is_not_recorded
self.assertIs(registered_egg * unregistered_egg, registered_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6750d0>

======================================================================
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 371, in test_collision_between_two_registered_eggs_is_recorded
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6747e0>

======================================================================
FAIL: test_collision_between_unregistered_eggs_is_not_recorded (test.TestEggTournament.test_collision_between_unregistered_eggs_is_not_recorded)
A collision between unregistered eggs should not be recorded in the tournament.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 381, in test_collision_between_unregistered_eggs_is_not_recorded
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f674c00>

======================================================================
FAIL: test_egg_broken_outside_tournament_remains_broken_inside_tournament (test.TestEggTournament.test_egg_broken_outside_tournament_remains_broken_inside_tournament)
Breaking an egg outside the tournament should preserve its broken state inside the tournament.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 404, in test_egg_broken_outside_tournament_remains_broken_inside_tournament
self.assertIs(broken_egg * outsider, outsider)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f675230>

======================================================================
FAIL: test_history_lookup_is_symmetric_with_respect_to_egg_order (test.TestEggTournament.test_history_lookup_is_symmetric_with_respect_to_egg_order)
Looking up a recorded collision in reversed egg order should return the same winner.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 445, in test_history_lookup_is_symmetric_with_respect_to_egg_order
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f675020>

======================================================================
FAIL: test_history_lookup_returns_winner_for_top_and_bottom (test.TestEggTournament.test_history_lookup_returns_winner_for_top_and_bottom)
Looking up recorded top and bottom collisions should return the correct winners.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 415, in test_history_lookup_returns_winner_for_top_and_bottom
self.assertIs(first_egg * second_egg, second_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f675910>

======================================================================
FAIL: test_history_lookup_top_and_bottom_are_distinct (test.TestEggTournament.test_history_lookup_top_and_bottom_are_distinct)
Looking up top and bottom collisions should treat them as distinct entries.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 456, in test_history_lookup_top_and_bottom_are_distinct
self.assertIs(first_egg * second_egg, second_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f675440>

======================================================================
FAIL: test_history_lookup_with_slice_key (test.TestEggTournament.test_history_lookup_with_slice_key)
Looking up a recorded collision with a slice key should return the winner.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 436, in test_history_lookup_with_slice_key
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6759c0>

======================================================================
FAIL: test_history_lookup_with_tuple_key (test.TestEggTournament.test_history_lookup_with_tuple_key)
Looking up a recorded collision with a tuple key should return the winner.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 427, in test_history_lookup_with_tuple_key
self.assertIs(first_egg * second_egg, first_egg)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f675ff0>

======================================================================
FAIL: test_ranking_missing_position_raises_index_error (test.TestEggTournament.test_ranking_missing_position_raises_index_error)
Looking up a missing ranking position should raise an IndexError.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 533, in test_ranking_missing_position_raises_index_error
self.assertIs(alpha * beta, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6760a0>

======================================================================
FAIL: test_ranking_tied_position_returns_set_of_eggs (test.TestEggTournament.test_ranking_tied_position_returns_set_of_eggs)
Looking up a tied ranking position should return a set of eggs.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 489, in test_ranking_tied_position_returns_set_of_eggs
self.assertIs(alpha * gamma, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f6764c0>

======================================================================
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 477, in test_ranking_unique_position_returns_single_egg
self.assertIs(alpha * beta, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f676a40>

======================================================================
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 509, in test_ranking_uses_dense_ranking_without_skipping_places
self.assertIs(alpha * beta, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f676af0>

======================================================================
FAIL: test_registered_egg_attribute_returns_position_and_victories (test.TestEggTournament.test_registered_egg_attribute_returns_position_and_victories)
Accessing a registered egg as an attribute should return its position and victories.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 556, in test_registered_egg_attribute_returns_position_and_victories
self.assertIs(alpha * beta, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f676d00>

======================================================================
FAIL: test_registered_egg_attribute_with_zero_victories_is_accessible (test.TestEggTournament.test_registered_egg_attribute_with_zero_victories_is_accessible)
Accessing a registered egg with zero victories should return its position and victories.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 572, in test_registered_egg_attribute_with_zero_victories_is_accessible
self.assertIs(alpha * beta, alpha)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: None is not <solution.Egg object at 0x7bf66f677490>

----------------------------------------------------------------------
Ran 46 tests in 0.008s

FAILED (failures=32, errors=3)

Дискусия
Виктор Бечев
15.04.2026 16:02

Като цяло местата, на които не си решил проблем с `if-elif-else` са супер. И употребата на такива условия не е сама по себе си грешна. Просто си тръгнал в някаква посока и в даден момент си стигнал до ситуация, в която си бил с вързани ръце и това е било логичното решение. Ако ти е любопитно - можеш да разгледаш други решения, за да видиш по-различен подход. Защото за обемен код - `if`-oвете стигат само до един момент.
Иван Грозданов
15.04.2026 15:31

Fuuuck! Наистина сте го споменали в примерите просто не съм му обърнал внимание. Благодаря за точките все пак! 😁
Виктор Бечев
15.04.2026 14:41

Важно е да е да връщаш победител при сблъсък на яйца, както в примерите. Ако го беше имплементирал - би имал доста повече точки. Получаваш бонус точка, защото все пак си се постарал. Просто си пропуснал ключова част от задачата, без която няма как да минат повечето тестове. Вероятно би могъл _(резонно)_ да ни репликираш, че не сме упоменали изрично, че трябва нещо да бъде върнато. И ще си наполовина прав. Имаме това: ```# my_egg @ your_egg би върнало същото, но повече за това в следващия абзац``` Но трябва да признаем, че е малко скришно. Затова ще ти дадем още една от точките, които иначе би заслужил. Cheers.
История

f1from collections import defaultdictf1from collections import defaultdict
22
3class Egg:3class Egg:
4    __MAX_SPACE = 50.04    __MAX_SPACE = 50.0
5    __BASE_HARDNESS = 0.05    __BASE_HARDNESS = 0.0
66
7    def __init__(self):7    def __init__(self):
8        self.tournament = None8        self.tournament = None
9        self.victories_in_tournament = 09        self.victories_in_tournament = 0
10        self.battles_history = []10        self.battles_history = []
11        self.top_hardness = Egg.__BASE_HARDNESS11        self.top_hardness = Egg.__BASE_HARDNESS
12        self.bottom_hardness = Egg.__BASE_HARDNESS12        self.bottom_hardness = Egg.__BASE_HARDNESS
13        self.__colors = []13        self.__colors = []
14        self.__top_not_painted_space = Egg.__MAX_SPACE14        self.__top_not_painted_space = Egg.__MAX_SPACE
15        self.__bottom_not_painted_space = Egg.__MAX_SPACE15        self.__bottom_not_painted_space = Egg.__MAX_SPACE
1616
17    def lost(self, which_half):17    def lost(self, which_half):
18        setattr(self, which_half, None)18        setattr(self, which_half, None)
1919
20    def __to_numeric_rgb(self, color):20    def __to_numeric_rgb(self, color):
21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))
2222
23    def __give_hardness(self, which_half, *color):23    def __give_hardness(self, which_half, *color):
24        if which_half == "top":24        if which_half == "top":
25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
26        elif which_half == "bottom":26        elif which_half == "bottom":
27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
2828
29    def paint(self, *colors):29    def paint(self, *colors):
30        for color in colors:30        for color in colors:
31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:
32                raise ValueError("Not enough space to paint the egg with the given color.")32                raise ValueError("Not enough space to paint the egg with the given color.")
33            elif self.__top_not_painted_space >= color[1]:33            elif self.__top_not_painted_space >= color[1]:
34                self.__give_hardness("top", color[0].upper(), color[1])34                self.__give_hardness("top", color[0].upper(), color[1])
35                self.__top_not_painted_space -= color[1]35                self.__top_not_painted_space -= color[1]
36                self.__colors.append(color)36                self.__colors.append(color)
37            elif self.__top_not_painted_space < color[1]:37            elif self.__top_not_painted_space < color[1]:
38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)
39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)
40                self.__top_not_painted_space = 0.040                self.__top_not_painted_space = 0.0
41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)
42                self.__colors.append(color)42                self.__colors.append(color)
43            elif self.__top_not_painted_space == 0.0:43            elif self.__top_not_painted_space == 0.0:
44                self.__give_hardness("bottom", color[0].upper(), color[1])44                self.__give_hardness("bottom", color[0].upper(), color[1])
45                self.__bottom_not_painted_space -= color[1]45                self.__bottom_not_painted_space -= color[1]
46                self.__colors.append(color)46                self.__colors.append(color)
4747
48    def __add_battle(self, opponent, which_half, result):48    def __add_battle(self, opponent, which_half, result):
49        self.battles_history.append((opponent, which_half, result))49        self.battles_history.append((opponent, which_half, result))
50        if result == "win":50        if result == "win":
51            self.victories_in_tournament += 151            self.victories_in_tournament += 1
5252
53    def return_battle_winner(self, opponent, which_half):53    def return_battle_winner(self, opponent, which_half):
54        for battle in self.battles_history:54        for battle in self.battles_history:
55            if battle[0] is opponent and battle[1] == which_half:55            if battle[0] is opponent and battle[1] == which_half:
56                return self if battle[2] == "win" else opponent56                return self if battle[2] == "win" else opponent
57        else:57        else:
58            return None58            return None
5959
60    def __mul__(self, other):60    def __mul__(self, other):
61        if not isinstance(other, Egg):61        if not isinstance(other, Egg):
62            raise ValueError("Can only multiply with another Egg instance.")62            raise ValueError("Can only multiply with another Egg instance.")
63        63        
64        if self.top_hardness is None or other.top_hardness is None:64        if self.top_hardness is None or other.top_hardness is None:
65            raise TypeError("Спукана работа :(")65            raise TypeError("Спукана работа :(")
66        66        
67        if self.top_hardness > other.top_hardness:67        if self.top_hardness > other.top_hardness:
68            if self.tournament is other.tournament and self.tournament:68            if self.tournament is other.tournament and self.tournament:
69                self.__add_battle(other, "top", "win")69                self.__add_battle(other, "top", "win")
70                other.__add_battle(self, "top", "lose")70                other.__add_battle(self, "top", "lose")
71            other.lost("top_hardness")71            other.lost("top_hardness")
72        elif self.top_hardness < other.top_hardness:72        elif self.top_hardness < other.top_hardness:
73            if self.tournament is other.tournament and self.tournament:73            if self.tournament is other.tournament and self.tournament:
74                self.__add_battle(other, "top", "lose")74                self.__add_battle(other, "top", "lose")
75                other.__add_battle(self, "top", "win")75                other.__add_battle(self, "top", "win")
76            self.lost("top_hardness")76            self.lost("top_hardness")
77        elif self.top_hardness == 0.0:77        elif self.top_hardness == 0.0:
78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:
79                if self.tournament is other.tournament and self.tournament:79                if self.tournament is other.tournament and self.tournament:
80                    self.__add_battle(other, "top", "win")80                    self.__add_battle(other, "top", "win")
81                    other.__add_battle(self, "top", "lose")81                    other.__add_battle(self, "top", "lose")
82                other.lost("top_hardness")82                other.lost("top_hardness")
83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:
84                if self.tournament is other.tournament and self.tournament:84                if self.tournament is other.tournament and self.tournament:
85                    self.__add_battle(other, "top", "lose")85                    self.__add_battle(other, "top", "lose")
86                    other.__add_battle(self, "top", "win")86                    other.__add_battle(self, "top", "win")
87                self.lost("top_hardness")87                self.lost("top_hardness")
8888
89    def __matmul__(self, other):89    def __matmul__(self, other):
90        if not isinstance(other, Egg):90        if not isinstance(other, Egg):
91            raise ValueError("Can only multiply with another Egg instance.")91            raise ValueError("Can only multiply with another Egg instance.")
92        92        
93        if self.bottom_hardness is None or other.bottom_hardness is None:93        if self.bottom_hardness is None or other.bottom_hardness is None:
94            raise TypeError("Спукана работа :(")94            raise TypeError("Спукана работа :(")
95        95        
96        if self.bottom_hardness > other.bottom_hardness:96        if self.bottom_hardness > other.bottom_hardness:
97            if self.tournament is other.tournament and self.tournament:97            if self.tournament is other.tournament and self.tournament:
98                self.__add_battle(other, "bottom", "win")98                self.__add_battle(other, "bottom", "win")
99                other.__add_battle(self, "bottom", "lose")99                other.__add_battle(self, "bottom", "lose")
100            other.lost("bottom_hardness")100            other.lost("bottom_hardness")
101        elif self.bottom_hardness < other.bottom_hardness:101        elif self.bottom_hardness < other.bottom_hardness:
102            if self.tournament is other.tournament and self.tournament:102            if self.tournament is other.tournament and self.tournament:
103                self.__add_battle(other, "bottom", "lose")103                self.__add_battle(other, "bottom", "lose")
104                other.__add_battle(self, "bottom", "win")104                other.__add_battle(self, "bottom", "win")
105            self.lost("bottom_hardness")105            self.lost("bottom_hardness")
106        elif self.bottom_hardness == 0.0:106        elif self.bottom_hardness == 0.0:
107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:
108                if self.tournament is other.tournament and self.tournament:108                if self.tournament is other.tournament and self.tournament:
109                    self.__add_battle(other, "bottom", "win")109                    self.__add_battle(other, "bottom", "win")
110                    other.__add_battle(self, "bottom", "lose")110                    other.__add_battle(self, "bottom", "lose")
111                other.lost("bottom_hardness")111                other.lost("bottom_hardness")
112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:
113                if self.tournament is other.tournament and self.tournament:113                if self.tournament is other.tournament and self.tournament:
114                    self.__add_battle(other, "bottom", "lose")114                    self.__add_battle(other, "bottom", "lose")
115                    other.__add_battle(self, "bottom", "win")115                    other.__add_battle(self, "bottom", "win")
116                self.lost("bottom_hardness")116                self.lost("bottom_hardness")
117117
118118
119class EggTournament:119class EggTournament:
120120
121    def __init__(self):121    def __init__(self):
122        self.__registered_eggs = {}122        self.__registered_eggs = {}
123123
124    @property124    @property
125    def __ranking(self):125    def __ranking(self):
126        grouped_by_victories = defaultdict(list)126        grouped_by_victories = defaultdict(list)
127        for name, egg in self.__registered_eggs.items():127        for name, egg in self.__registered_eggs.items():
128            grouped_by_victories[egg.victories_in_tournament].append(name)128            grouped_by_victories[egg.victories_in_tournament].append(name)
129129
130        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)130        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)
131        result = {}131        result = {}
132        position = 1132        position = 1
133        for victories in sorted_victories:133        for victories in sorted_victories:
134            result[position] = grouped_by_victories[victories]134            result[position] = grouped_by_victories[victories]
135            position += 1135            position += 1
136        return result136        return result
137137
138    def register(self, egg, name):138    def register(self, egg, name):
139        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):139        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):
140            raise ValueError(f"Egg with name {name} has already been registered")140            raise ValueError(f"Egg with name {name} has already been registered")
141        elif egg.tournament:141        elif egg.tournament:
142            raise ValueError(f"An egg cannot be registered in multiple tournaments")142            raise ValueError(f"An egg cannot be registered in multiple tournaments")
143        elif not name.isidentifier():143        elif not name.isidentifier():
144            raise ValueError(f"Invalid registration name")144            raise ValueError(f"Invalid registration name")
145        else:145        else:
146            self.__registered_eggs[name] = egg146            self.__registered_eggs[name] = egg
147            egg.tournament = self147            egg.tournament = self
148148
149    def __getitem__(self, key):149    def __getitem__(self, key):
150        if isinstance(key, slice):150        if isinstance(key, slice):
151            egg1, egg2, which_half = key.start, key.stop, key.step151            egg1, egg2, which_half = key.start, key.stop, key.step
152        else:152        else:
153            egg1, egg2, which_half = key153            egg1, egg2, which_half = key
154        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():154        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():
155            raise KeyError("There is no such battle in the tournament")155            raise KeyError("There is no such battle in the tournament")
156        if egg1.return_battle_winner(egg2, which_half) is None:156        if egg1.return_battle_winner(egg2, which_half) is None:
157            raise KeyError("There is no such battle in the tournament")157            raise KeyError("There is no such battle in the tournament")
158        return egg1.return_battle_winner(egg2, which_half)158        return egg1.return_battle_winner(egg2, which_half)
159            159            
160    def __rmatmul__(self, position):160    def __rmatmul__(self, position):
161        if position in self.__ranking.keys():161        if position in self.__ranking.keys():
162            return {self.__registered_eggs[name] for name in self.__ranking[position]}162            return {self.__registered_eggs[name] for name in self.__ranking[position]}
163        else:163        else:
164            raise IndexError("There is no such position in the ranking table")164            raise IndexError("There is no such position in the ranking table")
165        165        
166    def __getattr__(self, name):166    def __getattr__(self, name):
167        for pos in self.__ranking.keys():167        for pos in self.__ranking.keys():
168            if name in self.__ranking[pos]:168            if name in self.__ranking[pos]:
169                rank = pos169                rank = pos
170                break170                break
nn171        else:
172            raise AttributeError("Apologies, there is no such egg registered")
171        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")173        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")
172    174    
173    def __contains__(self, egg):175    def __contains__(self, egg):
t174        if egg in self.__registered_eggs.values():t176        return egg in self.__registered_eggs.values()
175            return True
176        else:
177            raise AttributeError("Apologies, there is no such egg registered")
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1from collections import defaultdictf1from collections import defaultdict
22
3class Egg:3class Egg:
4    __MAX_SPACE = 50.04    __MAX_SPACE = 50.0
5    __BASE_HARDNESS = 0.05    __BASE_HARDNESS = 0.0
66
7    def __init__(self):7    def __init__(self):
8        self.tournament = None8        self.tournament = None
9        self.victories_in_tournament = 09        self.victories_in_tournament = 0
10        self.battles_history = []10        self.battles_history = []
11        self.top_hardness = Egg.__BASE_HARDNESS11        self.top_hardness = Egg.__BASE_HARDNESS
12        self.bottom_hardness = Egg.__BASE_HARDNESS12        self.bottom_hardness = Egg.__BASE_HARDNESS
13        self.__colors = []13        self.__colors = []
14        self.__top_not_painted_space = Egg.__MAX_SPACE14        self.__top_not_painted_space = Egg.__MAX_SPACE
15        self.__bottom_not_painted_space = Egg.__MAX_SPACE15        self.__bottom_not_painted_space = Egg.__MAX_SPACE
1616
17    def lost(self, which_half):17    def lost(self, which_half):
18        setattr(self, which_half, None)18        setattr(self, which_half, None)
1919
20    def __to_numeric_rgb(self, color):20    def __to_numeric_rgb(self, color):
21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))
2222
23    def __give_hardness(self, which_half, *color):23    def __give_hardness(self, which_half, *color):
24        if which_half == "top":24        if which_half == "top":
25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
26        elif which_half == "bottom":26        elif which_half == "bottom":
27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
2828
29    def paint(self, *colors):29    def paint(self, *colors):
30        for color in colors:30        for color in colors:
31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:
32                raise ValueError("Not enough space to paint the egg with the given color.")32                raise ValueError("Not enough space to paint the egg with the given color.")
33            elif self.__top_not_painted_space >= color[1]:33            elif self.__top_not_painted_space >= color[1]:
34                self.__give_hardness("top", color[0].upper(), color[1])34                self.__give_hardness("top", color[0].upper(), color[1])
35                self.__top_not_painted_space -= color[1]35                self.__top_not_painted_space -= color[1]
36                self.__colors.append(color)36                self.__colors.append(color)
37            elif self.__top_not_painted_space < color[1]:37            elif self.__top_not_painted_space < color[1]:
38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)
39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)
40                self.__top_not_painted_space = 0.040                self.__top_not_painted_space = 0.0
41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)
42                self.__colors.append(color)42                self.__colors.append(color)
43            elif self.__top_not_painted_space == 0.0:43            elif self.__top_not_painted_space == 0.0:
44                self.__give_hardness("bottom", color[0].upper(), color[1])44                self.__give_hardness("bottom", color[0].upper(), color[1])
45                self.__bottom_not_painted_space -= color[1]45                self.__bottom_not_painted_space -= color[1]
46                self.__colors.append(color)46                self.__colors.append(color)
4747
48    def __add_battle(self, opponent, which_half, result):48    def __add_battle(self, opponent, which_half, result):
49        self.battles_history.append((opponent, which_half, result))49        self.battles_history.append((opponent, which_half, result))
50        if result == "win":50        if result == "win":
51            self.victories_in_tournament += 151            self.victories_in_tournament += 1
5252
53    def return_battle_winner(self, opponent, which_half):53    def return_battle_winner(self, opponent, which_half):
54        for battle in self.battles_history:54        for battle in self.battles_history:
55            if battle[0] is opponent and battle[1] == which_half:55            if battle[0] is opponent and battle[1] == which_half:
56                return self if battle[2] == "win" else opponent56                return self if battle[2] == "win" else opponent
57        else:57        else:
58            return None58            return None
5959
60    def __mul__(self, other):60    def __mul__(self, other):
61        if not isinstance(other, Egg):61        if not isinstance(other, Egg):
62            raise ValueError("Can only multiply with another Egg instance.")62            raise ValueError("Can only multiply with another Egg instance.")
63        63        
64        if self.top_hardness is None or other.top_hardness is None:64        if self.top_hardness is None or other.top_hardness is None:
65            raise TypeError("Спукана работа :(")65            raise TypeError("Спукана работа :(")
66        66        
67        if self.top_hardness > other.top_hardness:67        if self.top_hardness > other.top_hardness:
68            if self.tournament is other.tournament and self.tournament:68            if self.tournament is other.tournament and self.tournament:
69                self.__add_battle(other, "top", "win")69                self.__add_battle(other, "top", "win")
70                other.__add_battle(self, "top", "lose")70                other.__add_battle(self, "top", "lose")
71            other.lost("top_hardness")71            other.lost("top_hardness")
72        elif self.top_hardness < other.top_hardness:72        elif self.top_hardness < other.top_hardness:
73            if self.tournament is other.tournament and self.tournament:73            if self.tournament is other.tournament and self.tournament:
74                self.__add_battle(other, "top", "lose")74                self.__add_battle(other, "top", "lose")
75                other.__add_battle(self, "top", "win")75                other.__add_battle(self, "top", "win")
76            self.lost("top_hardness")76            self.lost("top_hardness")
77        elif self.top_hardness == 0.0:77        elif self.top_hardness == 0.0:
78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:
79                if self.tournament is other.tournament and self.tournament:79                if self.tournament is other.tournament and self.tournament:
80                    self.__add_battle(other, "top", "win")80                    self.__add_battle(other, "top", "win")
81                    other.__add_battle(self, "top", "lose")81                    other.__add_battle(self, "top", "lose")
82                other.lost("top_hardness")82                other.lost("top_hardness")
83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:
84                if self.tournament is other.tournament and self.tournament:84                if self.tournament is other.tournament and self.tournament:
85                    self.__add_battle(other, "top", "lose")85                    self.__add_battle(other, "top", "lose")
86                    other.__add_battle(self, "top", "win")86                    other.__add_battle(self, "top", "win")
87                self.lost("top_hardness")87                self.lost("top_hardness")
8888
89    def __matmul__(self, other):89    def __matmul__(self, other):
90        if not isinstance(other, Egg):90        if not isinstance(other, Egg):
91            raise ValueError("Can only multiply with another Egg instance.")91            raise ValueError("Can only multiply with another Egg instance.")
92        92        
93        if self.bottom_hardness is None or other.bottom_hardness is None:93        if self.bottom_hardness is None or other.bottom_hardness is None:
94            raise TypeError("Спукана работа :(")94            raise TypeError("Спукана работа :(")
95        95        
96        if self.bottom_hardness > other.bottom_hardness:96        if self.bottom_hardness > other.bottom_hardness:
97            if self.tournament is other.tournament and self.tournament:97            if self.tournament is other.tournament and self.tournament:
98                self.__add_battle(other, "bottom", "win")98                self.__add_battle(other, "bottom", "win")
99                other.__add_battle(self, "bottom", "lose")99                other.__add_battle(self, "bottom", "lose")
100            other.lost("bottom_hardness")100            other.lost("bottom_hardness")
101        elif self.bottom_hardness < other.bottom_hardness:101        elif self.bottom_hardness < other.bottom_hardness:
102            if self.tournament is other.tournament and self.tournament:102            if self.tournament is other.tournament and self.tournament:
103                self.__add_battle(other, "bottom", "lose")103                self.__add_battle(other, "bottom", "lose")
104                other.__add_battle(self, "bottom", "win")104                other.__add_battle(self, "bottom", "win")
105            self.lost("bottom_hardness")105            self.lost("bottom_hardness")
106        elif self.bottom_hardness == 0.0:106        elif self.bottom_hardness == 0.0:
107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:
108                if self.tournament is other.tournament and self.tournament:108                if self.tournament is other.tournament and self.tournament:
109                    self.__add_battle(other, "bottom", "win")109                    self.__add_battle(other, "bottom", "win")
110                    other.__add_battle(self, "bottom", "lose")110                    other.__add_battle(self, "bottom", "lose")
111                other.lost("bottom_hardness")111                other.lost("bottom_hardness")
112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:
113                if self.tournament is other.tournament and self.tournament:113                if self.tournament is other.tournament and self.tournament:
114                    self.__add_battle(other, "bottom", "lose")114                    self.__add_battle(other, "bottom", "lose")
115                    other.__add_battle(self, "bottom", "win")115                    other.__add_battle(self, "bottom", "win")
116                self.lost("bottom_hardness")116                self.lost("bottom_hardness")
117117
118118
119class EggTournament:119class EggTournament:
120120
121    def __init__(self):121    def __init__(self):
122        self.__registered_eggs = {}122        self.__registered_eggs = {}
123123
124    @property124    @property
125    def __ranking(self):125    def __ranking(self):
126        grouped_by_victories = defaultdict(list)126        grouped_by_victories = defaultdict(list)
127        for name, egg in self.__registered_eggs.items():127        for name, egg in self.__registered_eggs.items():
128            grouped_by_victories[egg.victories_in_tournament].append(name)128            grouped_by_victories[egg.victories_in_tournament].append(name)
129129
130        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)130        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)
131        result = {}131        result = {}
132        position = 1132        position = 1
133        for victories in sorted_victories:133        for victories in sorted_victories:
134            result[position] = grouped_by_victories[victories]134            result[position] = grouped_by_victories[victories]
135            position += 1135            position += 1
136        return result136        return result
137137
138    def register(self, egg, name):138    def register(self, egg, name):
139        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):139        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):
140            raise ValueError(f"Egg with name {name} has already been registered")140            raise ValueError(f"Egg with name {name} has already been registered")
141        elif egg.tournament:141        elif egg.tournament:
142            raise ValueError(f"An egg cannot be registered in multiple tournaments")142            raise ValueError(f"An egg cannot be registered in multiple tournaments")
143        elif not name.isidentifier():143        elif not name.isidentifier():
144            raise ValueError(f"Invalid registration name")144            raise ValueError(f"Invalid registration name")
145        else:145        else:
146            self.__registered_eggs[name] = egg146            self.__registered_eggs[name] = egg
147            egg.tournament = self147            egg.tournament = self
148148
149    def __getitem__(self, key):149    def __getitem__(self, key):
150        if isinstance(key, slice):150        if isinstance(key, slice):
151            egg1, egg2, which_half = key.start, key.stop, key.step151            egg1, egg2, which_half = key.start, key.stop, key.step
152        else:152        else:
153            egg1, egg2, which_half = key153            egg1, egg2, which_half = key
154        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():154        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():
155            raise KeyError("There is no such battle in the tournament")155            raise KeyError("There is no such battle in the tournament")
156        if egg1.return_battle_winner(egg2, which_half) is None:156        if egg1.return_battle_winner(egg2, which_half) is None:
157            raise KeyError("There is no such battle in the tournament")157            raise KeyError("There is no such battle in the tournament")
158        return egg1.return_battle_winner(egg2, which_half)158        return egg1.return_battle_winner(egg2, which_half)
159            159            
160    def __rmatmul__(self, position):160    def __rmatmul__(self, position):
161        if position in self.__ranking.keys():161        if position in self.__ranking.keys():
162            return {self.__registered_eggs[name] for name in self.__ranking[position]}162            return {self.__registered_eggs[name] for name in self.__ranking[position]}
163        else:163        else:
164            raise IndexError("There is no such position in the ranking table")164            raise IndexError("There is no such position in the ranking table")
165        165        
166    def __getattr__(self, name):166    def __getattr__(self, name):
167        for pos in self.__ranking.keys():167        for pos in self.__ranking.keys():
168            if name in self.__ranking[pos]:168            if name in self.__ranking[pos]:
169                rank = pos169                rank = pos
170                break170                break
171        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")171        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")
172    172    
173    def __contains__(self, egg):173    def __contains__(self, egg):
t174        return egg in self.__registered_eggs.values()t174        if egg in self.__registered_eggs.values():
175            return True
176        else:
177            raise AttributeError("Apologies, there is no such egg registered")
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1from collections import defaultdictf1from collections import defaultdict
22
3class Egg:3class Egg:
4    __MAX_SPACE = 50.04    __MAX_SPACE = 50.0
5    __BASE_HARDNESS = 0.05    __BASE_HARDNESS = 0.0
66
7    def __init__(self):7    def __init__(self):
8        self.tournament = None8        self.tournament = None
9        self.victories_in_tournament = 09        self.victories_in_tournament = 0
10        self.battles_history = []10        self.battles_history = []
11        self.top_hardness = Egg.__BASE_HARDNESS11        self.top_hardness = Egg.__BASE_HARDNESS
12        self.bottom_hardness = Egg.__BASE_HARDNESS12        self.bottom_hardness = Egg.__BASE_HARDNESS
13        self.__colors = []13        self.__colors = []
14        self.__top_not_painted_space = Egg.__MAX_SPACE14        self.__top_not_painted_space = Egg.__MAX_SPACE
15        self.__bottom_not_painted_space = Egg.__MAX_SPACE15        self.__bottom_not_painted_space = Egg.__MAX_SPACE
1616
17    def lost(self, which_half):17    def lost(self, which_half):
18        setattr(self, which_half, None)18        setattr(self, which_half, None)
1919
20    def __to_numeric_rgb(self, color):20    def __to_numeric_rgb(self, color):
21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))21        return tuple(int(color[i:i+2].upper(), 16) for i in (0, 2, 4))
2222
23    def __give_hardness(self, which_half, *color):23    def __give_hardness(self, which_half, *color):
24        if which_half == "top":24        if which_half == "top":
25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))25            self.top_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
26        elif which_half == "bottom":26        elif which_half == "bottom":
27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))27            self.bottom_hardness += (color[1] / self.__MAX_SPACE) * sum(self.__to_numeric_rgb(color[0].upper()))
2828
29    def paint(self, *colors):29    def paint(self, *colors):
30        for color in colors:30        for color in colors:
31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:31            if self.__top_not_painted_space + self.__bottom_not_painted_space < color[1]:
32                raise ValueError("Not enough space to paint the egg with the given color.")32                raise ValueError("Not enough space to paint the egg with the given color.")
33            elif self.__top_not_painted_space >= color[1]:33            elif self.__top_not_painted_space >= color[1]:
34                self.__give_hardness("top", color[0].upper(), color[1])34                self.__give_hardness("top", color[0].upper(), color[1])
35                self.__top_not_painted_space -= color[1]35                self.__top_not_painted_space -= color[1]
36                self.__colors.append(color)36                self.__colors.append(color)
37            elif self.__top_not_painted_space < color[1]:37            elif self.__top_not_painted_space < color[1]:
38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)38                self.__give_hardness("top", color[0].upper(), self.__top_not_painted_space)
39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)39                self.__give_hardness("bottom", color[0].upper(), color[1] - self.__top_not_painted_space)
40                self.__top_not_painted_space = 0.040                self.__top_not_painted_space = 0.0
41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)41                self.__bottom_not_painted_space -= (color[1] - self.__top_not_painted_space)
42                self.__colors.append(color)42                self.__colors.append(color)
43            elif self.__top_not_painted_space == 0.0:43            elif self.__top_not_painted_space == 0.0:
44                self.__give_hardness("bottom", color[0].upper(), color[1])44                self.__give_hardness("bottom", color[0].upper(), color[1])
45                self.__bottom_not_painted_space -= color[1]45                self.__bottom_not_painted_space -= color[1]
46                self.__colors.append(color)46                self.__colors.append(color)
4747
48    def __add_battle(self, opponent, which_half, result):48    def __add_battle(self, opponent, which_half, result):
49        self.battles_history.append((opponent, which_half, result))49        self.battles_history.append((opponent, which_half, result))
50        if result == "win":50        if result == "win":
51            self.victories_in_tournament += 151            self.victories_in_tournament += 1
5252
53    def return_battle_winner(self, opponent, which_half):53    def return_battle_winner(self, opponent, which_half):
54        for battle in self.battles_history:54        for battle in self.battles_history:
55            if battle[0] is opponent and battle[1] == which_half:55            if battle[0] is opponent and battle[1] == which_half:
56                return self if battle[2] == "win" else opponent56                return self if battle[2] == "win" else opponent
57        else:57        else:
58            return None58            return None
5959
60    def __mul__(self, other):60    def __mul__(self, other):
61        if not isinstance(other, Egg):61        if not isinstance(other, Egg):
62            raise ValueError("Can only multiply with another Egg instance.")62            raise ValueError("Can only multiply with another Egg instance.")
63        63        
64        if self.top_hardness is None or other.top_hardness is None:64        if self.top_hardness is None or other.top_hardness is None:
65            raise TypeError("Спукана работа :(")65            raise TypeError("Спукана работа :(")
66        66        
67        if self.top_hardness > other.top_hardness:67        if self.top_hardness > other.top_hardness:
68            if self.tournament is other.tournament and self.tournament:68            if self.tournament is other.tournament and self.tournament:
69                self.__add_battle(other, "top", "win")69                self.__add_battle(other, "top", "win")
70                other.__add_battle(self, "top", "lose")70                other.__add_battle(self, "top", "lose")
71            other.lost("top_hardness")71            other.lost("top_hardness")
72        elif self.top_hardness < other.top_hardness:72        elif self.top_hardness < other.top_hardness:
73            if self.tournament is other.tournament and self.tournament:73            if self.tournament is other.tournament and self.tournament:
74                self.__add_battle(other, "top", "lose")74                self.__add_battle(other, "top", "lose")
75                other.__add_battle(self, "top", "win")75                other.__add_battle(self, "top", "win")
76            self.lost("top_hardness")76            self.lost("top_hardness")
77        elif self.top_hardness == 0.0:77        elif self.top_hardness == 0.0:
78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:78            if self.__top_not_painted_space < self.__MAX_SPACE and other.__top_not_painted_space == self.__MAX_SPACE:
79                if self.tournament is other.tournament and self.tournament:79                if self.tournament is other.tournament and self.tournament:
80                    self.__add_battle(other, "top", "win")80                    self.__add_battle(other, "top", "win")
81                    other.__add_battle(self, "top", "lose")81                    other.__add_battle(self, "top", "lose")
82                other.lost("top_hardness")82                other.lost("top_hardness")
83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:83            elif self.__top_not_painted_space == self.__MAX_SPACE and other.__top_not_painted_space < self.__MAX_SPACE:
84                if self.tournament is other.tournament and self.tournament:84                if self.tournament is other.tournament and self.tournament:
85                    self.__add_battle(other, "top", "lose")85                    self.__add_battle(other, "top", "lose")
86                    other.__add_battle(self, "top", "win")86                    other.__add_battle(self, "top", "win")
87                self.lost("top_hardness")87                self.lost("top_hardness")
8888
89    def __matmul__(self, other):89    def __matmul__(self, other):
90        if not isinstance(other, Egg):90        if not isinstance(other, Egg):
91            raise ValueError("Can only multiply with another Egg instance.")91            raise ValueError("Can only multiply with another Egg instance.")
92        92        
93        if self.bottom_hardness is None or other.bottom_hardness is None:93        if self.bottom_hardness is None or other.bottom_hardness is None:
94            raise TypeError("Спукана работа :(")94            raise TypeError("Спукана работа :(")
95        95        
96        if self.bottom_hardness > other.bottom_hardness:96        if self.bottom_hardness > other.bottom_hardness:
97            if self.tournament is other.tournament and self.tournament:97            if self.tournament is other.tournament and self.tournament:
98                self.__add_battle(other, "bottom", "win")98                self.__add_battle(other, "bottom", "win")
99                other.__add_battle(self, "bottom", "lose")99                other.__add_battle(self, "bottom", "lose")
100            other.lost("bottom_hardness")100            other.lost("bottom_hardness")
101        elif self.bottom_hardness < other.bottom_hardness:101        elif self.bottom_hardness < other.bottom_hardness:
102            if self.tournament is other.tournament and self.tournament:102            if self.tournament is other.tournament and self.tournament:
103                self.__add_battle(other, "bottom", "lose")103                self.__add_battle(other, "bottom", "lose")
104                other.__add_battle(self, "bottom", "win")104                other.__add_battle(self, "bottom", "win")
105            self.lost("bottom_hardness")105            self.lost("bottom_hardness")
106        elif self.bottom_hardness == 0.0:106        elif self.bottom_hardness == 0.0:
107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:107            if self.__bottom_not_painted_space < self.__MAX_SPACE and other.__bottom_not_painted_space == self.__MAX_SPACE:
108                if self.tournament is other.tournament and self.tournament:108                if self.tournament is other.tournament and self.tournament:
109                    self.__add_battle(other, "bottom", "win")109                    self.__add_battle(other, "bottom", "win")
110                    other.__add_battle(self, "bottom", "lose")110                    other.__add_battle(self, "bottom", "lose")
111                other.lost("bottom_hardness")111                other.lost("bottom_hardness")
112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:112            elif self.__bottom_not_painted_space == self.__MAX_SPACE and other.__bottom_not_painted_space < self.__MAX_SPACE:
113                if self.tournament is other.tournament and self.tournament:113                if self.tournament is other.tournament and self.tournament:
114                    self.__add_battle(other, "bottom", "lose")114                    self.__add_battle(other, "bottom", "lose")
115                    other.__add_battle(self, "bottom", "win")115                    other.__add_battle(self, "bottom", "win")
116                self.lost("bottom_hardness")116                self.lost("bottom_hardness")
117117
t118    t
119 
120118
121class EggTournament:119class EggTournament:
122120
123    def __init__(self):121    def __init__(self):
124        self.__registered_eggs = {}122        self.__registered_eggs = {}
125123
126    @property124    @property
127    def __ranking(self):125    def __ranking(self):
128        grouped_by_victories = defaultdict(list)126        grouped_by_victories = defaultdict(list)
129        for name, egg in self.__registered_eggs.items():127        for name, egg in self.__registered_eggs.items():
130            grouped_by_victories[egg.victories_in_tournament].append(name)128            grouped_by_victories[egg.victories_in_tournament].append(name)
131129
132        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)130        sorted_victories = sorted(grouped_by_victories.keys(), reverse=True)
133        result = {}131        result = {}
134        position = 1132        position = 1
135        for victories in sorted_victories:133        for victories in sorted_victories:
136            result[position] = grouped_by_victories[victories]134            result[position] = grouped_by_victories[victories]
137            position += 1135            position += 1
138        return result136        return result
139137
140    def register(self, egg, name):138    def register(self, egg, name):
141        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):139        if any(name == reg_egg_name for reg_egg_name in self.__registered_eggs.keys()):
142            raise ValueError(f"Egg with name {name} has already been registered")140            raise ValueError(f"Egg with name {name} has already been registered")
143        elif egg.tournament:141        elif egg.tournament:
144            raise ValueError(f"An egg cannot be registered in multiple tournaments")142            raise ValueError(f"An egg cannot be registered in multiple tournaments")
145        elif not name.isidentifier():143        elif not name.isidentifier():
146            raise ValueError(f"Invalid registration name")144            raise ValueError(f"Invalid registration name")
147        else:145        else:
148            self.__registered_eggs[name] = egg146            self.__registered_eggs[name] = egg
149            egg.tournament = self147            egg.tournament = self
150148
151    def __getitem__(self, key):149    def __getitem__(self, key):
152        if isinstance(key, slice):150        if isinstance(key, slice):
153            egg1, egg2, which_half = key.start, key.stop, key.step151            egg1, egg2, which_half = key.start, key.stop, key.step
154        else:152        else:
155            egg1, egg2, which_half = key153            egg1, egg2, which_half = key
156        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():154        if egg1 not in self.__registered_eggs.values() or egg2 not in self.__registered_eggs.values():
157            raise KeyError("There is no such battle in the tournament")155            raise KeyError("There is no such battle in the tournament")
158        if egg1.return_battle_winner(egg2, which_half) is None:156        if egg1.return_battle_winner(egg2, which_half) is None:
159            raise KeyError("There is no such battle in the tournament")157            raise KeyError("There is no such battle in the tournament")
160        return egg1.return_battle_winner(egg2, which_half)158        return egg1.return_battle_winner(egg2, which_half)
161            159            
162    def __rmatmul__(self, position):160    def __rmatmul__(self, position):
163        if position in self.__ranking.keys():161        if position in self.__ranking.keys():
164            return {self.__registered_eggs[name] for name in self.__ranking[position]}162            return {self.__registered_eggs[name] for name in self.__ranking[position]}
165        else:163        else:
166            raise IndexError("There is no such position in the ranking table")164            raise IndexError("There is no such position in the ranking table")
167        165        
168    def __getattr__(self, name):166    def __getattr__(self, name):
169        for pos in self.__ranking.keys():167        for pos in self.__ranking.keys():
170            if name in self.__ranking[pos]:168            if name in self.__ranking[pos]:
171                rank = pos169                rank = pos
172                break170                break
173        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")171        return {"position": rank, "victories": self.__registered_eggs[name].victories_in_tournament} if name in self.__registered_eggs else AttributeError(f"Apologies, there is no such egg registered")
174    172    
175    def __contains__(self, egg):173    def __contains__(self, egg):
176        return egg in self.__registered_eggs.values()174        return egg in self.__registered_eggs.values()
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op