Домашни > Великденско домашно > Решения > Решението на Захари Янев

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

6 точки общо

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

  1class Egg:
  2    def __init__(self):
  3        self.top_side_paints = list()
  4        self.bottom_side_paints = list()
  5        self.painted_percentage = 0.0
  6        self.is_top_side_broken = False
  7        self.is_bottom_side_broken = False
  8        self._tournament = None
  9
 10    def paint(self, *args):
 11        total = sum(paint[1] for paint in args)
 12
 13        if self.painted_percentage + total > 100.0:
 14            raise ValueError
 15
 16        for color, percent in args:
 17            if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0:
 18                self.top_side_paints.append((color, percent))
 19                self.painted_percentage += percent
 20
 21            elif self.painted_percentage >= 50.0:
 22                self.bottom_side_paints.append((color, percent))
 23                self.painted_percentage += percent
 24
 25            else:
 26                remaining_top = 50.0 - self.painted_percentage
 27                self.top_side_paints.append((color, remaining_top))
 28                self.bottom_side_paints.append((color, percent - remaining_top))
 29                self.painted_percentage += percent
 30
 31    @staticmethod    
 32    def strength(paints):
 33        strength = 0
 34        for paint, amount in paints:
 35            strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100
 36        return strength
 37
 38    def __mul__(self, other):
 39        if not isinstance(other, Egg):
 40            return NotImplemented
 41        if self is other:
 42            return NotImplemented
 43        if self.is_top_side_broken or other.is_top_side_broken:
 44            raise TypeError("Махай се от тука загубеняк")
 45        if not self.top_side_paints:
 46            self.is_top_side_broken = True
 47            winner = other
 48        elif not other.top_side_paints:
 49            other.is_top_side_broken = True
 50            winner = self
 51        elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints):
 52            other.is_top_side_broken = True
 53            winner = self
 54        else:
 55            self.is_top_side_broken = True
 56            winner = other
 57        if self._tournament is not None and self._tournament is other._tournament:
 58            self._tournament._record_battle(self, other, "top", winner)
 59
 60        return winner
 61
 62    def __matmul__(self, other):
 63        if not isinstance(other, Egg):
 64            return NotImplemented
 65        if self is other:
 66            return NotImplemented
 67        if self.is_bottom_side_broken or other.is_bottom_side_broken:
 68            raise TypeError("Махай се от тука загубеняк")
 69        if not self.bottom_side_paints:
 70            self.is_bottom_side_broken = True
 71            winner = other
 72        elif not other.bottom_side_paints:
 73            other.is_bottom_side_broken = True
 74            winner = self
 75        elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints):
 76            other.is_bottom_side_broken = True
 77            winner = self
 78        else:
 79            self.is_bottom_side_broken = True
 80            winner = other
 81        if self._tournament is not None and self._tournament is other._tournament:
 82            self._tournament._record_battle(self, other, "bottom", winner)
 83
 84        return winner
 85
 86
 87class EggTournament:
 88    def __init__(self):
 89        self.history = dict()
 90        self.eggs = dict()
 91        self.names = dict()
 92        self.victories = dict()
 93        
 94
 95
 96    def _record_battle(self, egg1, egg2, side, winner):
 97        key = (frozenset((egg1, egg2)), side)
 98        self.history[key] = winner
 99        self.victories[winner] += 1
100
101    def register(self, egg, name):
102        if egg._tournament is not None:
103            raise ValueError("An egg cannot be registered in multiple tournaments")
104
105        if not name.isidentifier():
106            raise ValueError("Invalid registration name")
107
108        if name in self.names:
109            raise ValueError(f"Egg with name {name} has already been registered")
110
111        egg._tournament = self
112        self.names[name] = egg
113        self.eggs[egg] = name
114        self.victories[egg] = 0
115
116    def __getitem__(self, key):
117        if isinstance(key, tuple):
118            if len(key) != 3:
119                raise KeyError("Wrong access")
120            else:
121                egg1 = key[0]
122                egg2 = key[1]
123                side = key[2]
124        elif isinstance(key, slice):
125            egg1 = key.start
126            egg2 = key.stop
127            side = key.step
128        else:
129            raise KeyError("Wrong access")
130        
131        if side not in ("top", "bottom"):
132            raise KeyError("Wrong access")
133        
134        lookup_key = (frozenset((egg1, egg2)), side)
135
136        if lookup_key not in self.history:
137            raise KeyError("No such battle recorded")
138        
139        return self.history[lookup_key]
140    
141    def get_ranking(self):  
142        sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True)
143        ranking = {}
144        current_rank = 0
145        last_victory_count = None
146
147        for egg, victory_count in sorted_victories:
148            if victory_count != last_victory_count:
149                current_rank += 1
150                last_victory_count = victory_count
151            ranking[egg] = current_rank
152
153        return ranking
154    
155    def __rmatmul__(self, index):
156        if not isinstance(index, int):
157            return NotImplemented
158        ranking = self.get_ranking()
159        
160        eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index}
161        if not eggs_at_rank:
162            raise IndexError("No eggs at this rank")
163        
164        if len(eggs_at_rank) == 1:
165            return eggs_at_rank.pop()
166        
167        return eggs_at_rank
168    
169    def __getattr__(self, name):
170        if name not in self.names:
171            raise AttributeError("Apologies, there is no such egg registered")
172
173        egg = self.names[name]
174        ranking = self.get_ranking()
175
176        return {"position": ranking[egg], "victories": self.victories[egg]}
177    
178    def __contains__(self, egg):
179        return egg in self.eggs
180    
181
182    
183
184        
185
186        
187
188
189
190# my_egg = Egg()
191# my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0))
192
193# your_egg = Egg()
194# your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0))
195
196# print(my_egg)
197# print(your_egg)
198
199
200# #my_egg = Egg()
201# #your_egg = Egg()
202# tournament = EggTournament()
203
204# tournament.register(my_egg, "the_monster")
205# tournament.register(your_egg, "the_pink_princess123")
206
207# print(my_egg * your_egg)
208# print(my_egg @ your_egg)
209
210# print(tournament[your_egg, my_egg, "bottom"])
211# print(tournament[my_egg, your_egg, "bottom"])
212# print(tournament.the_monster)
213# print(tournament.the_pink_princess123)
214# print(1 @ tournament)

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

OK

Дискусия
История

f1f1
2class Egg:2class Egg:
3    def __init__(self):3    def __init__(self):
4        self.top_side_paints = list()4        self.top_side_paints = list()
5        self.bottom_side_paints = list()5        self.bottom_side_paints = list()
6        self.painted_percentage = 0.06        self.painted_percentage = 0.0
7        self.is_top_side_broken = False7        self.is_top_side_broken = False
8        self.is_bottom_side_broken = False8        self.is_bottom_side_broken = False
9        self._tournament = None9        self._tournament = None
1010
11    def paint(self, *args):11    def paint(self, *args):
12        total = sum(paint[1] for paint in args)12        total = sum(paint[1] for paint in args)
1313
14        if self.painted_percentage + total > 100.0:14        if self.painted_percentage + total > 100.0:
15            raise ValueError15            raise ValueError
1616
17        for color, percent in args:17        for color, percent in args:
18            if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0:18            if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0:
19                self.top_side_paints.append((color, percent))19                self.top_side_paints.append((color, percent))
20                self.painted_percentage += percent20                self.painted_percentage += percent
2121
22            elif self.painted_percentage >= 50.0:22            elif self.painted_percentage >= 50.0:
23                self.bottom_side_paints.append((color, percent))23                self.bottom_side_paints.append((color, percent))
24                self.painted_percentage += percent24                self.painted_percentage += percent
2525
26            else:26            else:
27                remaining_top = 50.0 - self.painted_percentage27                remaining_top = 50.0 - self.painted_percentage
28                self.top_side_paints.append((color, remaining_top))28                self.top_side_paints.append((color, remaining_top))
29                self.bottom_side_paints.append((color, percent - remaining_top))29                self.bottom_side_paints.append((color, percent - remaining_top))
30                self.painted_percentage += percent30                self.painted_percentage += percent
3131
32    @staticmethod    32    @staticmethod    
33    def strength(paints):33    def strength(paints):
34        strength = 034        strength = 0
35        for paint, amount in paints:35        for paint, amount in paints:
36            strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 10036            strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100
37        return strength37        return strength
3838
39    def __mul__(self, other):39    def __mul__(self, other):
40        if not isinstance(other, Egg):40        if not isinstance(other, Egg):
41            return NotImplemented41            return NotImplemented
42        if self is other:42        if self is other:
43            return NotImplemented43            return NotImplemented
44        if self.is_top_side_broken or other.is_top_side_broken:44        if self.is_top_side_broken or other.is_top_side_broken:
45            raise TypeError("Махай се от тука загубеняк")45            raise TypeError("Махай се от тука загубеняк")
46        if not self.top_side_paints:46        if not self.top_side_paints:
47            self.is_top_side_broken = True47            self.is_top_side_broken = True
48            winner = other48            winner = other
49        elif not other.top_side_paints:49        elif not other.top_side_paints:
50            other.is_top_side_broken = True50            other.is_top_side_broken = True
51            winner = self51            winner = self
52        elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints):52        elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints):
53            other.is_top_side_broken = True53            other.is_top_side_broken = True
54            winner = self54            winner = self
55        else:55        else:
56            self.is_top_side_broken = True56            self.is_top_side_broken = True
57            winner = other57            winner = other
58        if self._tournament is not None and self._tournament is other._tournament:58        if self._tournament is not None and self._tournament is other._tournament:
59            self._tournament._record_battle(self, other, "top", winner)59            self._tournament._record_battle(self, other, "top", winner)
6060
61        return winner61        return winner
6262
63    def __matmul__(self, other):63    def __matmul__(self, other):
64        if not isinstance(other, Egg):64        if not isinstance(other, Egg):
65            return NotImplemented65            return NotImplemented
66        if self is other:66        if self is other:
67            return NotImplemented67            return NotImplemented
68        if self.is_bottom_side_broken or other.is_bottom_side_broken:68        if self.is_bottom_side_broken or other.is_bottom_side_broken:
69            raise TypeError("Махай се от тука загубеняк")69            raise TypeError("Махай се от тука загубеняк")
70        if not self.bottom_side_paints:70        if not self.bottom_side_paints:
71            self.is_bottom_side_broken = True71            self.is_bottom_side_broken = True
72            winner = other72            winner = other
73        elif not other.bottom_side_paints:73        elif not other.bottom_side_paints:
74            other.is_bottom_side_broken = True74            other.is_bottom_side_broken = True
75            winner = self75            winner = self
76        elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints):76        elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints):
77            other.is_bottom_side_broken = True77            other.is_bottom_side_broken = True
78            winner = self78            winner = self
79        else:79        else:
80            self.is_bottom_side_broken = True80            self.is_bottom_side_broken = True
81            winner = other81            winner = other
82        if self._tournament is not None and self._tournament is other._tournament:82        if self._tournament is not None and self._tournament is other._tournament:
83            self._tournament._record_battle(self, other, "bottom", winner)83            self._tournament._record_battle(self, other, "bottom", winner)
8484
85        return winner85        return winner
8686
8787
88class EggTournament:88class EggTournament:
89    def __init__(self):89    def __init__(self):
90        self.history = dict()90        self.history = dict()
91        self.eggs = dict()91        self.eggs = dict()
92        self.names = dict()92        self.names = dict()
93        self.victories = dict()93        self.victories = dict()
94        94        
9595
9696
97    def _record_battle(self, egg1, egg2, side, winner):97    def _record_battle(self, egg1, egg2, side, winner):
98        key = (frozenset((egg1, egg2)), side)98        key = (frozenset((egg1, egg2)), side)
99        self.history[key] = winner99        self.history[key] = winner
100        self.victories[winner] += 1100        self.victories[winner] += 1
101101
102    def register(self, egg, name):102    def register(self, egg, name):
103        if egg._tournament is not None:103        if egg._tournament is not None:
104            raise ValueError("An egg cannot be registered in multiple tournaments")104            raise ValueError("An egg cannot be registered in multiple tournaments")
105105
106        if not name.isidentifier():106        if not name.isidentifier():
107            raise ValueError("Invalid registration name")107            raise ValueError("Invalid registration name")
108108
109        if name in self.names:109        if name in self.names:
110            raise ValueError(f"Egg with name {name} has already been registered")110            raise ValueError(f"Egg with name {name} has already been registered")
111111
112        egg._tournament = self112        egg._tournament = self
113        self.names[name] = egg113        self.names[name] = egg
114        self.eggs[egg] = name114        self.eggs[egg] = name
115        self.victories[egg] = 0115        self.victories[egg] = 0
116116
117    def __getitem__(self, key):117    def __getitem__(self, key):
118        if isinstance(key, tuple):118        if isinstance(key, tuple):
119            if len(key) != 3:119            if len(key) != 3:
120                raise KeyError("Wrong access")120                raise KeyError("Wrong access")
121            else:121            else:
122                egg1 = key[0]122                egg1 = key[0]
123                egg2 = key[1]123                egg2 = key[1]
124                side = key[2]124                side = key[2]
125        elif isinstance(key, slice):125        elif isinstance(key, slice):
126            egg1 = key.start126            egg1 = key.start
127            egg2 = key.stop127            egg2 = key.stop
128            side = key.step128            side = key.step
129        else:129        else:
130            raise KeyError("Wrong access")130            raise KeyError("Wrong access")
131        131        
132        if side not in ("top", "bottom"):132        if side not in ("top", "bottom"):
133            raise KeyError("Wrong access")133            raise KeyError("Wrong access")
134        134        
135        lookup_key = (frozenset((egg1, egg2)), side)135        lookup_key = (frozenset((egg1, egg2)), side)
136136
137        if lookup_key not in self.history:137        if lookup_key not in self.history:
138            raise KeyError("No such battle recorded")138            raise KeyError("No such battle recorded")
139        139        
140        return self.history[lookup_key]140        return self.history[lookup_key]
141    141    
142    def get_ranking(self):  142    def get_ranking(self):  
143        sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True)143        sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True)
144        ranking = {}144        ranking = {}
145        current_rank = 0145        current_rank = 0
146        last_victory_count = None146        last_victory_count = None
147147
148        for egg, victory_count in sorted_victories:148        for egg, victory_count in sorted_victories:
149            if victory_count != last_victory_count:149            if victory_count != last_victory_count:
150                current_rank += 1150                current_rank += 1
151                last_victory_count = victory_count151                last_victory_count = victory_count
152            ranking[egg] = current_rank152            ranking[egg] = current_rank
153153
154        return ranking154        return ranking
155    155    
156    def __rmatmul__(self, index):156    def __rmatmul__(self, index):
157        if not isinstance(index, int):157        if not isinstance(index, int):
158            return NotImplemented158            return NotImplemented
159        ranking = self.get_ranking()159        ranking = self.get_ranking()
160        160        
161        eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index}161        eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index}
162        if not eggs_at_rank:162        if not eggs_at_rank:
163            raise IndexError("No eggs at this rank")163            raise IndexError("No eggs at this rank")
164        164        
165        if len(eggs_at_rank) == 1:165        if len(eggs_at_rank) == 1:
166            return eggs_at_rank.pop()166            return eggs_at_rank.pop()
167        167        
168        return eggs_at_rank168        return eggs_at_rank
169    169    
170    def __getattr__(self, name):170    def __getattr__(self, name):
171        if name not in self.names:171        if name not in self.names:
172            raise AttributeError("Apologies, there is no such egg registered")172            raise AttributeError("Apologies, there is no such egg registered")
173173
174        egg = self.names[name]174        egg = self.names[name]
175        ranking = self.get_ranking()175        ranking = self.get_ranking()
176176
177        return {"position": ranking[egg], "victories": self.victories[egg]}177        return {"position": ranking[egg], "victories": self.victories[egg]}
178    178    
179    def __contains__(self, egg):179    def __contains__(self, egg):
180        return egg in self.eggs180        return egg in self.eggs
181    181    
182182
183    183    
184184
185        185        
186186
187        187        
188188
189189
190190
n191my_egg = Egg()n
192my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0))
193 
194your_egg = Egg()
195your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0))
196 
197print(my_egg)
198print(your_egg)
199 
200 
201#my_egg = Egg()191# my_egg = Egg()
192# my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0))
193 
202#your_egg = Egg()194# your_egg = Egg()
203tournament = EggTournament()195# your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0))
204196
n205tournament.register(my_egg, "the_monster")n197# print(my_egg)
206tournament.register(your_egg, "the_pink_princess123")198# print(your_egg)
207199
n208print(my_egg * your_egg)n
209print(my_egg @ your_egg)
210200
tt201# #my_egg = Egg()
202# #your_egg = Egg()
203# tournament = EggTournament()
204 
205# tournament.register(my_egg, "the_monster")
206# tournament.register(your_egg, "the_pink_princess123")
207 
208# print(my_egg * your_egg)
209# print(my_egg @ your_egg)
210 
211print(tournament[your_egg, my_egg, "bottom"])211print(tournament[your_egg, my_egg, "bottom"])
212print(tournament[my_egg, your_egg, "bottom"])212print(tournament[my_egg, your_egg, "bottom"])
213print(tournament.the_monster)213print(tournament.the_monster)
214print(tournament.the_pink_princess123)214print(tournament.the_pink_princess123)
215print(1 @ tournament)215print(1 @ tournament)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1f1
2class Egg:2class Egg:
3    def __init__(self):3    def __init__(self):
4        self.top_side_paints = list()4        self.top_side_paints = list()
5        self.bottom_side_paints = list()5        self.bottom_side_paints = list()
6        self.painted_percentage = 0.06        self.painted_percentage = 0.0
7        self.is_top_side_broken = False7        self.is_top_side_broken = False
8        self.is_bottom_side_broken = False8        self.is_bottom_side_broken = False
9        self._tournament = None9        self._tournament = None
1010
n11    n
12    def paint(self, *args):11    def paint(self, *args):
n13        for paint in args:n12        total = sum(paint[1] for paint in args)
14            if self.painted_percentage < 50.0 and paint[1] + self.painted_percentage <= 50.0:13 
15                self.top_side_paints.append(paint)
16                self.painted_percentage += paint[1]
17            elif self.painted_percentage >= 50.0 and paint[1] + self.painted_percentage <= 100.0:
18                self.bottom_side_paints.append(paint)
19                self.painted_percentage += paint[1]
20            elif self.painted_percentage < 50.0 and paint[1] + self.painted_percentage > 50.0 and paint[1] + self.painted_percentage <= 100.0:
21                remaining_top_paint = 50.0 - self.painted_percentage
22                self.top_side_paints.append((paint[0], remaining_top_paint))
23                self.bottom_side_paints.append((paint[0], paint[1] - remaining_top_paint))
24                self.painted_percentage += paint[1]
25            elif self.painted_percentage + paint[1] > 100.0:14        if self.painted_percentage + total > 100.0:
26                raise ValueError15            raise ValueError
16 
17        for color, percent in args:
18            if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0:
19                self.top_side_paints.append((color, percent))
20                self.painted_percentage += percent
21 
22            elif self.painted_percentage >= 50.0:
23                self.bottom_side_paints.append((color, percent))
24                self.painted_percentage += percent
25 
26            else:
27                remaining_top = 50.0 - self.painted_percentage
28                self.top_side_paints.append((color, remaining_top))
29                self.bottom_side_paints.append((color, percent - remaining_top))
30                self.painted_percentage += percent
2731
28    @staticmethod    32    @staticmethod    
29    def strength(paints):33    def strength(paints):
30        strength = 034        strength = 0
31        for paint, amount in paints:35        for paint, amount in paints:
32            strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 10036            strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100
33        return strength37        return strength
3438
35    def __mul__(self, other):39    def __mul__(self, other):
36        if not isinstance(other, Egg):40        if not isinstance(other, Egg):
37            return NotImplemented41            return NotImplemented
38        if self is other:42        if self is other:
39            return NotImplemented43            return NotImplemented
40        if self.is_top_side_broken or other.is_top_side_broken:44        if self.is_top_side_broken or other.is_top_side_broken:
41            raise TypeError("Махай се от тука загубеняк")45            raise TypeError("Махай се от тука загубеняк")
42        if not self.top_side_paints:46        if not self.top_side_paints:
43            self.is_top_side_broken = True47            self.is_top_side_broken = True
44            winner = other48            winner = other
45        elif not other.top_side_paints:49        elif not other.top_side_paints:
46            other.is_top_side_broken = True50            other.is_top_side_broken = True
47            winner = self51            winner = self
48        elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints):52        elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints):
49            other.is_top_side_broken = True53            other.is_top_side_broken = True
50            winner = self54            winner = self
51        else:55        else:
52            self.is_top_side_broken = True56            self.is_top_side_broken = True
53            winner = other57            winner = other
54        if self._tournament is not None and self._tournament is other._tournament:58        if self._tournament is not None and self._tournament is other._tournament:
55            self._tournament._record_battle(self, other, "top", winner)59            self._tournament._record_battle(self, other, "top", winner)
5660
57        return winner61        return winner
5862
59    def __matmul__(self, other):63    def __matmul__(self, other):
60        if not isinstance(other, Egg):64        if not isinstance(other, Egg):
61            return NotImplemented65            return NotImplemented
62        if self is other:66        if self is other:
63            return NotImplemented67            return NotImplemented
64        if self.is_bottom_side_broken or other.is_bottom_side_broken:68        if self.is_bottom_side_broken or other.is_bottom_side_broken:
65            raise TypeError("Махай се от тука загубеняк")69            raise TypeError("Махай се от тука загубеняк")
66        if not self.bottom_side_paints:70        if not self.bottom_side_paints:
67            self.is_bottom_side_broken = True71            self.is_bottom_side_broken = True
68            winner = other72            winner = other
69        elif not other.bottom_side_paints:73        elif not other.bottom_side_paints:
70            other.is_bottom_side_broken = True74            other.is_bottom_side_broken = True
71            winner = self75            winner = self
72        elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints):76        elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints):
73            other.is_bottom_side_broken = True77            other.is_bottom_side_broken = True
74            winner = self78            winner = self
75        else:79        else:
76            self.is_bottom_side_broken = True80            self.is_bottom_side_broken = True
77            winner = other81            winner = other
78        if self._tournament is not None and self._tournament is other._tournament:82        if self._tournament is not None and self._tournament is other._tournament:
79            self._tournament._record_battle(self, other, "bottom", winner)83            self._tournament._record_battle(self, other, "bottom", winner)
8084
81        return winner85        return winner
8286
8387
84class EggTournament:88class EggTournament:
85    def __init__(self):89    def __init__(self):
86        self.history = dict()90        self.history = dict()
87        self.eggs = dict()91        self.eggs = dict()
88        self.names = dict()92        self.names = dict()
89        self.victories = dict()93        self.victories = dict()
90        94        
9195
9296
93    def _record_battle(self, egg1, egg2, side, winner):97    def _record_battle(self, egg1, egg2, side, winner):
94        key = (frozenset((egg1, egg2)), side)98        key = (frozenset((egg1, egg2)), side)
95        self.history[key] = winner99        self.history[key] = winner
96        self.victories[winner] += 1100        self.victories[winner] += 1
97101
98    def register(self, egg, name):102    def register(self, egg, name):
99        if egg._tournament is not None:103        if egg._tournament is not None:
100            raise ValueError("An egg cannot be registered in multiple tournaments")104            raise ValueError("An egg cannot be registered in multiple tournaments")
101105
102        if not name.isidentifier():106        if not name.isidentifier():
103            raise ValueError("Invalid registration name")107            raise ValueError("Invalid registration name")
104108
105        if name in self.names:109        if name in self.names:
106            raise ValueError(f"Egg with name {name} has already been registered")110            raise ValueError(f"Egg with name {name} has already been registered")
107111
108        egg._tournament = self112        egg._tournament = self
109        self.names[name] = egg113        self.names[name] = egg
110        self.eggs[egg] = name114        self.eggs[egg] = name
111        self.victories[egg] = 0115        self.victories[egg] = 0
112116
113    def __getitem__(self, key):117    def __getitem__(self, key):
114        if isinstance(key, tuple):118        if isinstance(key, tuple):
115            if len(key) != 3:119            if len(key) != 3:
116                raise KeyError("Wrong access")120                raise KeyError("Wrong access")
117            else:121            else:
118                egg1 = key[0]122                egg1 = key[0]
119                egg2 = key[1]123                egg2 = key[1]
120                side = key[2]124                side = key[2]
121        elif isinstance(key, slice):125        elif isinstance(key, slice):
122            egg1 = key.start126            egg1 = key.start
123            egg2 = key.stop127            egg2 = key.stop
124            side = key.step128            side = key.step
125        else:129        else:
126            raise KeyError("Wrong access")130            raise KeyError("Wrong access")
127        131        
128        if side not in ("top", "bottom"):132        if side not in ("top", "bottom"):
129            raise KeyError("Wrong access")133            raise KeyError("Wrong access")
130        134        
131        lookup_key = (frozenset((egg1, egg2)), side)135        lookup_key = (frozenset((egg1, egg2)), side)
132136
133        if lookup_key not in self.history:137        if lookup_key not in self.history:
134            raise KeyError("No such battle recorded")138            raise KeyError("No such battle recorded")
135        139        
136        return self.history[lookup_key]140        return self.history[lookup_key]
137    141    
138    def get_ranking(self):  142    def get_ranking(self):  
139        sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True)143        sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True)
140        ranking = {}144        ranking = {}
141        current_rank = 0145        current_rank = 0
142        last_victory_count = None146        last_victory_count = None
143147
144        for egg, victory_count in sorted_victories:148        for egg, victory_count in sorted_victories:
145            if victory_count != last_victory_count:149            if victory_count != last_victory_count:
146                current_rank += 1150                current_rank += 1
147                last_victory_count = victory_count151                last_victory_count = victory_count
148            ranking[egg] = current_rank152            ranking[egg] = current_rank
149153
150        return ranking154        return ranking
151    155    
152    def __rmatmul__(self, index):156    def __rmatmul__(self, index):
153        if not isinstance(index, int):157        if not isinstance(index, int):
154            return NotImplemented158            return NotImplemented
155        ranking = self.get_ranking()159        ranking = self.get_ranking()
156        160        
157        eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index}161        eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index}
158        if not eggs_at_rank:162        if not eggs_at_rank:
159            raise IndexError("No eggs at this rank")163            raise IndexError("No eggs at this rank")
160        164        
161        if len(eggs_at_rank) == 1:165        if len(eggs_at_rank) == 1:
162            return eggs_at_rank.pop()166            return eggs_at_rank.pop()
163        167        
164        return eggs_at_rank168        return eggs_at_rank
165    169    
166    def __getattr__(self, name):170    def __getattr__(self, name):
167        if name not in self.names:171        if name not in self.names:
168            raise AttributeError("Apologies, there is no such egg registered")172            raise AttributeError("Apologies, there is no such egg registered")
169173
170        egg = self.names[name]174        egg = self.names[name]
171        ranking = self.get_ranking()175        ranking = self.get_ranking()
172176
173        return {"position": ranking[egg], "victories": self.victories[egg]}177        return {"position": ranking[egg], "victories": self.victories[egg]}
174    178    
175    def __contains__(self, egg):179    def __contains__(self, egg):
176        return egg in self.eggs180        return egg in self.eggs
177    181    
178182
179    183    
180184
181        185        
182186
183        187        
184188
185189
186190
n187my_egg = Egg()n191my_egg = Egg()
188my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0))192my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0))
189193
n190your_egg = Egg()n194your_egg = Egg()
191your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0))195your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0))
192196
n193print(my_egg)n197print(my_egg)
194print(your_egg)198print(your_egg)
195199
196200
n197#my_egg = Egg()n201#my_egg = Egg()
198#your_egg = Egg()202#your_egg = Egg()
199tournament = EggTournament()203tournament = EggTournament()
200204
n201tournament.register(my_egg, "the_monster")n205tournament.register(my_egg, "the_monster")
202tournament.register(your_egg, "the_pink_princess123")206tournament.register(your_egg, "the_pink_princess123")
203207
n204print(my_egg * your_egg)n208print(my_egg * your_egg)
205print(my_egg @ your_egg)209print(my_egg @ your_egg)
206210
t207print(tournament[your_egg, my_egg, "bottom"])t211print(tournament[your_egg, my_egg, "bottom"])
208print(tournament[my_egg, your_egg, "bottom"])212print(tournament[my_egg, your_egg, "bottom"])
209print(tournament.the_monster)213print(tournament.the_monster)
210print(tournament.the_pink_princess123)214print(tournament.the_pink_princess123)
211print(1 @ tournament)215print(1 @ tournament)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op