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

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

4 точки общо

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

  1def чукай(part):
  2    def decorator(func):
  3        def wrapper(self, other):
  4            winner = None
  5            broken_part = f"_broken_{part}"
  6            if getattr(self, broken_part) or getattr(other, broken_part):
  7                raise TypeError(f"Счупена част: {part}")
  8            if not isinstance(other, Egg):
  9                raise AttributeError("Чукане само на две яйца")
 10            self_stren = self.calculate_strength(part)
 11            other_stren = other.calculate_strength(part)
 12            if self_stren > other_stren:
 13                setattr(other, broken_part, True)
 14                winner = self
 15            else:
 16                setattr(self, broken_part, True)
 17                winner = other
 18
 19            if hasattr(self, "registered") and self._tournament:
 20                self.registered._record_battle(self, other, part, winner)
 21
 22            return winner
 23        return wrapper
 24    return decorator
 25
 26class Egg:
 27    def __init__(self):
 28        self._colors = []
 29        self._fullness = 0.0
 30        self._broken_top = False
 31        self._broken_bottom = False
 32        self.registered = None
 33    
 34    def paint(self, *args):
 35        sum_percentages = sum(pair[1] for pair in args)
 36        if sum_percentages + self._fullness > 100.00:
 37            raise ValueError("Egg color is full")
 38        
 39        for color, percentage in args:
 40            self._colors.append((color.upper(), percentage))
 41        self._fullness += sum_percentages
 42
 43    def get_color_value(self, hex_color):
 44        """Преобразуване от 16-тична в инт"""
 45        r_value = int(hex_color[0:2], 16)
 46        g_value = int(hex_color[2:4], 16)
 47        b_value = int(hex_color[4:6], 16)
 48        return r_value + g_value + b_value
 49
 50    def calculate_strength(self, part):
 51        strength = 0.0
 52        curr_coverage = 0.0
 53        curr_perc = 0.0
 54
 55        if part == "top":
 56            left_index = 0.0
 57            right_index = 50.0
 58        else:
 59            left_index = 50.0
 60            right_index = 100.0
 61
 62        for pair in self._colors:
 63            starting_point = curr_perc
 64            ending_point = curr_perc + pair[1]
 65            overal_egg_start = max(starting_point, left_index)
 66            overall_egg_end = min(ending_point, right_index)
 67            if overal_egg_start < overall_egg_end:
 68                partitial_perc = overall_egg_end - overal_egg_start
 69                strength += partitial_perc * self.get_color_value(pair[0])
 70                curr_coverage += partitial_perc
 71            curr_perc = ending_point
 72        return (strength, curr_coverage)
 73    
 74    @чукай("top")
 75    def __mul__(self, other):
 76        pass
 77
 78    @чукай("bottom")
 79    def __matmul__(self, other):
 80        pass
 81
 82
 83class EggTournament:
 84    def __init__(self):
 85        #self.tournament_name
 86        self._participants = {}
 87        self._egss_in = {}
 88        self._battles = {}
 89        self._record = {}
 90
 91    def register(self, egg, pseudo):
 92        if not isinstance(egg, Egg):
 93            raise AttributeError("Only eggs allowed in tournament")
 94        if egg.registered:
 95            raise ValueError("An egg cannot be registered in multiple tournaments")
 96        if pseudo in self._participants.keys():
 97            raise ValueError(f"Egg with name {pseudo} has already been registered")
 98        if not pseudo.isidentifier():
 99            raise ValueError("Invalid registration name")
100
101        self._participants[pseudo] = egg
102        self._egss_in[egg] = pseudo
103        egg.registered = self
104        self._record[egg] = 0
105    
106    def _record_battle(self, egg1, egg2, part, winner):
107        if egg1 in self._egss_in and egg2 in self._egss_in:
108            battle_key = (frozenset([egg1, egg2]), part) #имах много ядове с това и накрая ai ми помогна с frozenset - признат грях, половин грях 
109            self._battles[battle_key] = winner
110            self._record[winner] += 1
111
112    def __contains__(self, egg):
113        return egg in self._egss_in
114    
115    def __getitem__(self, battle):
116        if isinstance(battle, slice):
117            egg1 = battle.start
118            egg2 = battle.stop
119            part = battle.step
120        else:
121            egg1 = battle[0]
122            egg2 = battle[1]
123            part = battle[2]
124        
125        battle_key = (frozenset([egg1, egg2]), part)
126        if battle_key in self._battles:
127            return self._battles[battle_key]
128        raise KeyError("No such match in tournament history")
129    
130    def __getattr__(self, name):
131        if name in self._participants:
132            egg = self._participants[name]
133            res = {}
134            res["position"] = self._get_rank(egg)
135            res["victories"] = self._record[egg]
136            return res
137        raise AttributeError("Apologies, there is no such egg registered")
138    
139    def _get_record(self, egg):
140        return self._record[egg]
141
142    def _rank_eggs(self):
143        if not self._participants:
144            return {}
145        eggs = []
146        for egg in self._participants.values():
147            eggs.append(egg)
148        
149        eggs.sort(key=self._get_record, reverse=True)
150        ranking = {}
151        curr_pos = 0
152        prev_win_cnt = -1
153        for egg in eggs:
154            wins = self._record[egg]
155            if wins != prev_win_cnt:
156                curr_pos += 1
157            ranking[egg] = curr_pos
158            prev_win_cnt = wins
159        return ranking
160
161    def _get_rank(self, egg):
162        return self._rank_eggs().get(egg)
163    
164    def __rmatmul__(self, rank):
165        if not isinstance(rank, int):
166            raise AttributeError("Ranks should be numbers")
167        ranks = self._rank_eggs()
168        curr_rank_winners = []
169        for egg in ranks:
170            if ranks[egg] == rank:
171                curr_rank_winners.append(egg)
172        if len(curr_rank_winners) == 0:
173            raise IndexError(f"No eggs at rank {rank}")
174        elif len(curr_rank_winners) == 1:
175            return curr_rank_winners[0]
176        return set(curr_rank_winners)

EEEEEEEEEEEEEE...EEEEEEEEE..E..E.EEEE.EEEE..EE
======================================================================
ERROR: 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)
~~~~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~^~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~^~~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
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 138, in test_paint_chunk_crossing_50_percent_boundary_is_split_correctly
self.assertIs(egg * opponent, egg)
~~~~^~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
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 41, in test_paint_exactly_to_100_percent_is_allowed
self.assertIs(egg @ opponent, egg)
~~~~^~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
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 150, in test_paint_multiple_calls_can_cross_50_percent_boundary
self.assertIs(egg * opponent, egg)
~~~~^~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~^~~~~~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~^~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: test_unpainted_half_loses_to_half_painted_black (test.TestEgg.test_unpainted_half_loses_to_half_painted_black)
An unpainted half should lose to a half painted in black.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 200, in test_unpainted_half_loses_to_half_painted_black
self.assertIs(unpainted_egg * black_egg, black_egg)
~~~~~~~~~~~~~~^~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~^~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~~^~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~~~~~^~~~~~~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~^~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~^~~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~^~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~^~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~^~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

======================================================================
ERROR: 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)
~~~~~~^~~~~~
File "/tmp/solution.py", line 19, in wrapper
if hasattr(self, "registered") and self._tournament:
^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute '_tournament'

----------------------------------------------------------------------
Ran 46 tests in 0.011s

FAILED (errors=35)

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

Имплементацията ти има един огромен проблем, и той е този ред: ```if hasattr(self, "registered") and self._tournament:``` Проблемът е, че `hasattr(self, "registered")` ще върне истина, дори `registered` да е `None` - `self.registered = None`. Предполагам само като четеш това ти става ясно защо. `hasattr` = има ли такъв атрибут. А не той истина ли е. И после става страшно, защоро нерегистрираните яйца нямат `self._tournament` и ти гърми с `AttributeError`. Има няколко опции, които оправят проблема - `if getattr(self, "registered") ..` или пък `... and getattr(self, "_tournament", None)`. Тъй като изрично сме казали, че дори и яйца, които не са регистрирани в даден турнир, трябва да могат да се чукат. И все пак, това е едно изискване от 20, не е редно това да ти струва много точки. При едно от горните решения би имал 31/46 теста, при другото - 35. И в двата случая това са 4/6 точки. За да не е безнаказана грешката ти, приемаме, че си -1 точка, и ти даваме бонус 2, така че да отговаря на реалните ти точки. П.П. В момента не знаеш, че имаш 1 точка, и може би сметките изглеждат странно. Вече знаеш. И ще имаш 3. Освен ако не видя проблемен или страхотен код когато допрочета решението ти.
История
Това решение има само една версия.