Домашни > Работилница за отвари! > Решения > Решението на Добромир Пеев

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

8 точки общо

15 успешни теста
5 неуспешни теста
Код

  1import math
  2import copy
  3
  4def once(func):
  5    def wrapper(target):
  6        if wrapper.called:
  7            raise TypeError("Effect is depleted.")
  8        wrapper.called = True
  9        func(target)
 10    wrapper.called = False
 11    return wrapper
 12
 13def calling_function_decorator(function, times):
 14    @once
 15    def decorator(target):
 16        for _ in range(times):
 17            function(target)
 18    return decorator
 19
 20class Potion:
 21
 22    def __hash__(self):
 23        hash_value = 0
 24        for effect_name, intensity in self.intensity.items():
 25            hash_value ^= hash((effect_name, intensity))
 26        return hash_value
 27
 28    def round_intensity(self,to_return,effect_name):
 29         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name])
 30
 31    def is_depleted(self):
 32         is_depleted_var = True
 33         for effect_name,effect in self.effects.items():
 34            function = getattr(self, effect_name)
 35            try:
 36                function(None)               
 37            except TypeError:
 38                is_depleted_var = True
 39                continue
 40            finally:
 41                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
 42                return False
 43         return is_depleted_var
 44    
 45    @staticmethod
 46    def already_used(target):
 47        raise TypeError("Potion is now part of something bigger than itself.")
 48    
 49    def __init__(self,effects, duration):
 50        self.effects = copy.copy(effects)
 51        self.was_used = False
 52        self.intensity = {}
 53        for effect_name in self.effects:
 54            self.intensity[effect_name] = 1
 55        for effect_name,effect in effects.items():
 56             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
 57             self.effects[effect_name] = effect
 58        self.duration = duration
 59
 60    def __add__(self, other):
 61        if self.is_depleted() or other.is_depleted():
 62            raise TypeError("Potion is depleted.")
 63        if self.was_used == True or other.was_used == True:
 64            raise TypeError("Potion is now part of something bigger than itself.")
 65        to_return = Potion(self.effects, max(self.duration, other.duration)) 
 66        for effect_name,effect in to_return.effects.items():
 67            to_return.intensity[effect_name]=self.intensity[effect_name]
 68            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
 69        for effect_name,effect in other.effects.items():
 70            if effect_name in to_return.effects:
 71                to_return.intensity[effect_name] += 1       
 72                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
 73            else:
 74                to_return.intensity[effect_name] = other.intensity[effect_name]   
 75                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
 76                to_return.effects[effect_name] = effect
 77        for effect_name in self.effects:
 78            setattr(self, effect_name, self.already_used)
 79        for effect_name in other.effects:
 80            setattr(other, effect_name, other.already_used)
 81        self.was_used = other.was_used = True
 82        return to_return
 83    
 84    def __mul__(self, value):
 85        if self.is_depleted():
 86            raise TypeError("Potion is depleted.")
 87        if self.was_used == True:
 88            raise TypeError("Potion is now part of something bigger than itself.")
 89        if value >= 0 and value <= 1:
 90            to_return = Potion(self.effects, self.duration)
 91            for effect_name in to_return.effects:
 92                to_return.intensity[effect_name] = self.intensity[effect_name]
 93            for effect_name,effect in to_return.effects.items():
 94                to_return.intensity[effect_name] *= value
 95                self.round_intensity(to_return,effect_name)
 96                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
 97               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])              
 98            for effect_name in self.effects:
 99                setattr(self, effect_name, self.already_used)
100            self.was_used = True
101            return to_return
102        to_return = Potion(self.effects, self.duration)
103        for effect_name in to_return.effects:
104            to_return.intensity[effect_name] = self.intensity[effect_name]
105        for effect_name in to_return.effects:
106            to_return.intensity[effect_name] *= value
107        for effect_name,effect in to_return.effects.items():
108             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
109        for effect_name in self.effects:
110            setattr(self, effect_name, self.already_used)
111        self.was_used = True
112        return to_return
113    
114    def __sub__(self, other):
115        if self.is_depleted() or other.is_depleted():
116            raise TypeError("Potion is depleted.")
117        if self.was_used == True or other.was_used == True:
118            raise TypeError("Potion is now part of something bigger than itself.")
119        to_return = Potion(self.effects, self.duration)
120        for effect_name,effect in to_return.effects.items():
121            to_return.intensity[effect_name] = self.intensity[effect_name]
122            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))
123        for effect_name in other.effects:
124            if effect_name not in to_return.effects:
125                raise TypeError("Error")
126        for effect_name, effect in other.effects.items():
127            if to_return.intensity[effect_name] > other.intensity[effect_name]:
128                to_return.intensity[effect_name] -= other.intensity[effect_name]
129                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
130            else:
131                delattr(to_return, effect_name)
132                del to_return.effects[effect_name]
133                del to_return.intensity[effect_name]
134        for effect_name in self.effects:
135            setattr(self, effect_name, self.already_used)
136        for effect_name in other.effects:
137            setattr(other, effect_name, other.already_used)
138        self.was_used = other.was_used = True
139        return to_return
140
141    def __truediv__(self, value):
142        if self.is_depleted():
143            raise TypeError("Potion is depleted.")
144        if self.was_used == True:
145            raise TypeError("Potion is now part of something bigger than itself.")
146        copy_potion=Potion(self.effects,self.duration)
147        for effect_name in self.intensity:
148            copy_potion.intensity[effect_name] = self.intensity[effect_name]
149        for effect_name,effect in copy_potion.effects.items():
150            copy_potion.intensity[effect_name] /= value
151            self.round_intensity(copy_potion,effect_name)
152            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])
153            setattr(copy_potion,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name]))        
154        potion_list=[]
155        for _ in range(value):
156            copy=Potion(copy_potion.effects,copy_potion.duration)
157            for effect_name in copy_potion.intensity:
158                copy.intensity[effect_name] = copy_potion.intensity[effect_name]
159            for effect_name,effect in copy_potion.effects.items():
160                setattr(copy,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name]))
161            potion_list.append(copy)
162        for effect_name in self.effects:
163            setattr(self, effect_name, self.already_used)
164        self.was_used = True
165        return tuple(potion_list)
166 
167    def __eq__(self,other):
168        if self.is_depleted() or other.is_depleted():
169            raise TypeError("Potion is depleted.")
170        if self.was_used == True or other.was_used == True:
171            raise TypeError("Potion is now part of something bigger than itself.")
172        for effect_name in self.effects:
173            if effect_name not in other.effects:
174                return False
175        for effect_name in self.effects:
176            if self.intensity[effect_name] != other.intensity[effect_name]:
177                return False
178        return True
179    
180    def __gt__(self,other):
181        if self.is_depleted() or other.is_depleted():
182            raise TypeError("Potion is depleted.")
183        if self.was_used == True or other.was_used == True:
184            raise TypeError("Potion is now part of something bigger than itself.")
185        sum_of_self = 0
186        for effect_name in self.intensity:
187            sum_of_self+=self.intensity[effect_name]
188        sum_of_other = 0
189        for effect_name in other.intensity:
190            sum_of_other += other.intensity[effect_name]
191        return sum_of_self > sum_of_other
192        
193
194def sorting_potions(potion):
195        name = potion[0]
196        sum_of_potion_name = 0
197        for letter in name:
198            sum_of_potion_name += ord(letter)
199        return sum_of_potion_name
200
201
202class ГоспожатаПоХимия:
203    def __init__(self):
204        self.used_potions = []
205        self.targets_copies = {}
206        self.targets_buffed_copies = {}
207
208    def apply(self, target, potion):
209        if potion.duration == 0:
210            return
211        if potion.is_depleted():
212            raise TypeError("Potion is depleted.")
213        if potion.was_used:
214            raise TypeError("Potion is now part of something bigger than itself.")
215        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)
216        potion.effects = dict(sorted_potions)
217        if target not in self.targets_buffed_copies.values():
218            self.targets_copies[potion] = copy.copy(target)
219        else:
220            for potion_loop in self.used_potions:
221                potion_loop.was_used = False
222                if self.targets_buffed_copies[potion_loop] == target:
223                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])
224                potion_loop.was_used = True
225        self.used_potions.append(potion)
226        for effect_name in potion.effects:
227            function = getattr(potion, effect_name)
228            try:
229                function(target)
230            except TypeError:
231                continue
232        for potion_iter in self.used_potions:
233            potion_iter.was_used = False
234        self.targets_buffed_copies[potion] = target
235        potion.was_used = True
236        for potion_iter in self.used_potions:
237            potion_iter.was_used = True
238    
239    def tick(self):
240        for potion in self.used_potions:
241            potion.duration -= 1
242            if potion.duration == 0:
243                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])
244                for potion_inner in self.used_potions:
245                    potion_inner.was_used = False
246                    potion.was_used = False
247                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:
248                        potion_inner.was_used = True
249                        potion.was_used = True
250                        continue
251                    potion_inner.was_used = True
252                    potion.was_used = True
253                    copy = Potion(potion_inner.effects,potion_inner.duration)
254                    for effect_name,effect in  copy.effects.items():
255                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]
256                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))
257                    for effect_name in  copy.effects:
258                        function = getattr(copy, effect_name)
259                        function(self.targets_buffed_copies[potion])

...F........F..F.F.F
======================================================================
FAIL: test_equal (test.TestPotionComparison)
Test equality of potions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 304, in test_equal
self.assertNotEqual(potion1, potion2)
AssertionError: <solution.Potion object at 0x7fa9ee5a8d60> == <solution.Potion object at 0x7fa9ee5a8dc0>

======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
TypeError: Potion is now part of something bigger than itself.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/tmp/test.py", line 380, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
AssertionError: "Potion is depleted\." does not match "Potion is now part of something bigger than itself."

======================================================================
FAIL: test_applying_part_of_potion (test.TestГоспожатаПоХимия)
Test applying only a part of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 366, in test_applying_part_of_potion
self.assertEqual(self._target.int_attr, 5) # This should be the original value
AssertionError: 50 != 5

======================================================================
FAIL: test_ticking_multiple_potions (test.TestГоспожатаПоХимия)
Test ticking after applying multiple potions which affect the same attribute.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 458, in test_ticking_multiple_potions
self.assertEqual(self._target.int_attr, 50)
AssertionError: 5 != 50

======================================================================
FAIL: test_ticking_mutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 446, in test_ticking_mutable
self.assertEqual(self._target.list_attr, [1, 2, 3])
AssertionError: Lists differ: [1, 2, 3, 4] != [1, 2, 3]

First list contains 1 additional elements.
First extra element 3:
4

- [1, 2, 3, 4]
? ---

+ [1, 2, 3]

----------------------------------------------------------------------
Ran 20 tests in 0.003s

FAILED (failures=5)

Дискусия
Георги Кунчев
04.12.2023 11:18

Знам, че пишеш на още няколко езика и трудно се сменят стилове ден за ден. Или опитай да следваш интервалите към PEP8, или си свали някакъв линтер да го прави вместо теб. Много трудно се чете без наличието на интервали около оператори и запетая, особено за човек, който е свиканл да чете Python и очаква да са там. Все едно чета текст, написан на шльокавица - разбирам го, но ме боли да го чета. Няма да отнемам точки, но ако пишеш професионално Питонски код така, няма да мине код ревю.
История

f1import mathf1import math
2import copy2import copy
33
4def once(func):4def once(func):
5    def wrapper(target):5    def wrapper(target):
6        if wrapper.called:6        if wrapper.called:
7            raise TypeError("Effect is depleted.")7            raise TypeError("Effect is depleted.")
8        wrapper.called = True8        wrapper.called = True
9        func(target)9        func(target)
10    wrapper.called = False10    wrapper.called = False
11    return wrapper11    return wrapper
1212
13def calling_function_decorator(function, times):13def calling_function_decorator(function, times):
14    @once14    @once
15    def decorator(target):15    def decorator(target):
16        for _ in range(times):16        for _ in range(times):
17            function(target)17            function(target)
18    return decorator18    return decorator
1919
20class Potion:20class Potion:
2121
nn22    def __hash__(self):
23        hash_value = 0
24        for effect_name, intensity in self.intensity.items():
25            hash_value ^= hash((effect_name, intensity))
26        return hash_value
27 
22    def round_intensity(self,to_return,effect_name):28    def round_intensity(self,to_return,effect_name):
23         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name])29         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name])
2430
25    def is_depleted(self):31    def is_depleted(self):
n26         is_depleted = Truen32         is_depleted_var = True
27         for effect_name,effect in self.effects.items():33         for effect_name,effect in self.effects.items():
28            function = getattr(self, effect_name)34            function = getattr(self, effect_name)
29            try:35            try:
30                function(None)               36                function(None)               
31            except TypeError:37            except TypeError:
n32                is_depleted = Truen38                is_depleted_var = True
33            except AttributeError:39                continue
34                is_depleted = False40            finally:
35                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))41                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
nn42                return False
36         return is_depleted43         return is_depleted_var
37    44    
38    @staticmethod45    @staticmethod
39    def already_used(target):46    def already_used(target):
40        raise TypeError("Potion is now part of something bigger than itself.")47        raise TypeError("Potion is now part of something bigger than itself.")
41    48    
42    def __init__(self,effects, duration):49    def __init__(self,effects, duration):
43        self.effects = copy.copy(effects)50        self.effects = copy.copy(effects)
44        self.was_used = False51        self.was_used = False
45        self.intensity = {}52        self.intensity = {}
46        for effect_name in self.effects:53        for effect_name in self.effects:
47            self.intensity[effect_name] = 154            self.intensity[effect_name] = 1
48        for effect_name,effect in effects.items():55        for effect_name,effect in effects.items():
49             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))56             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
50             self.effects[effect_name] = effect57             self.effects[effect_name] = effect
51        self.duration = duration58        self.duration = duration
5259
53    def __add__(self, other):60    def __add__(self, other):
54        if self.is_depleted() or other.is_depleted():61        if self.is_depleted() or other.is_depleted():
55            raise TypeError("Potion is depleted.")62            raise TypeError("Potion is depleted.")
56        if self.was_used == True or other.was_used == True:63        if self.was_used == True or other.was_used == True:
57            raise TypeError("Potion is now part of something bigger than itself.")64            raise TypeError("Potion is now part of something bigger than itself.")
58        to_return = Potion(self.effects, max(self.duration, other.duration)) 65        to_return = Potion(self.effects, max(self.duration, other.duration)) 
59        for effect_name,effect in to_return.effects.items():66        for effect_name,effect in to_return.effects.items():
60            to_return.intensity[effect_name]=self.intensity[effect_name]67            to_return.intensity[effect_name]=self.intensity[effect_name]
61            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))68            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
62        for effect_name,effect in other.effects.items():69        for effect_name,effect in other.effects.items():
63            if effect_name in to_return.effects:70            if effect_name in to_return.effects:
64                to_return.intensity[effect_name] += 1       71                to_return.intensity[effect_name] += 1       
65                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))72                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
66            else:73            else:
67                to_return.intensity[effect_name] = other.intensity[effect_name]   74                to_return.intensity[effect_name] = other.intensity[effect_name]   
68                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))75                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
69                to_return.effects[effect_name] = effect76                to_return.effects[effect_name] = effect
70        for effect_name in self.effects:77        for effect_name in self.effects:
71            setattr(self, effect_name, self.already_used)78            setattr(self, effect_name, self.already_used)
72        for effect_name in other.effects:79        for effect_name in other.effects:
73            setattr(other, effect_name, other.already_used)80            setattr(other, effect_name, other.already_used)
74        self.was_used = other.was_used = True81        self.was_used = other.was_used = True
75        return to_return82        return to_return
76    83    
77    def __mul__(self, value):84    def __mul__(self, value):
78        if self.is_depleted():85        if self.is_depleted():
79            raise TypeError("Potion is depleted.")86            raise TypeError("Potion is depleted.")
80        if self.was_used == True:87        if self.was_used == True:
81            raise TypeError("Potion is now part of something bigger than itself.")88            raise TypeError("Potion is now part of something bigger than itself.")
82        if value >= 0 and value <= 1:89        if value >= 0 and value <= 1:
83            to_return = Potion(self.effects, self.duration)90            to_return = Potion(self.effects, self.duration)
84            for effect_name in to_return.effects:91            for effect_name in to_return.effects:
85                to_return.intensity[effect_name] = self.intensity[effect_name]92                to_return.intensity[effect_name] = self.intensity[effect_name]
86            for effect_name,effect in to_return.effects.items():93            for effect_name,effect in to_return.effects.items():
87                to_return.intensity[effect_name] *= value94                to_return.intensity[effect_name] *= value
88                self.round_intensity(to_return,effect_name)95                self.round_intensity(to_return,effect_name)
89                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))96                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
90               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])              97               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])              
91            for effect_name in self.effects:98            for effect_name in self.effects:
92                setattr(self, effect_name, self.already_used)99                setattr(self, effect_name, self.already_used)
93            self.was_used = True100            self.was_used = True
94            return to_return101            return to_return
95        to_return = Potion(self.effects, self.duration)102        to_return = Potion(self.effects, self.duration)
96        for effect_name in to_return.effects:103        for effect_name in to_return.effects:
97            to_return.intensity[effect_name] = self.intensity[effect_name]104            to_return.intensity[effect_name] = self.intensity[effect_name]
98        for effect_name in to_return.effects:105        for effect_name in to_return.effects:
99            to_return.intensity[effect_name] *= value106            to_return.intensity[effect_name] *= value
100        for effect_name,effect in to_return.effects.items():107        for effect_name,effect in to_return.effects.items():
101             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))108             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
102        for effect_name in self.effects:109        for effect_name in self.effects:
103            setattr(self, effect_name, self.already_used)110            setattr(self, effect_name, self.already_used)
104        self.was_used = True111        self.was_used = True
105        return to_return112        return to_return
106    113    
107    def __sub__(self, other):114    def __sub__(self, other):
108        if self.is_depleted() or other.is_depleted():115        if self.is_depleted() or other.is_depleted():
109            raise TypeError("Potion is depleted.")116            raise TypeError("Potion is depleted.")
110        if self.was_used == True or other.was_used == True:117        if self.was_used == True or other.was_used == True:
111            raise TypeError("Potion is now part of something bigger than itself.")118            raise TypeError("Potion is now part of something bigger than itself.")
112        to_return = Potion(self.effects, self.duration)119        to_return = Potion(self.effects, self.duration)
113        for effect_name,effect in to_return.effects.items():120        for effect_name,effect in to_return.effects.items():
114            to_return.intensity[effect_name] = self.intensity[effect_name]121            to_return.intensity[effect_name] = self.intensity[effect_name]
115            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))122            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))
n116        for effect in other.effects.values():n123        for effect_name in other.effects:
117            if effect not in to_return.effects.values():124            if effect_name not in to_return.effects:
118                raise TypeError("Error")125                raise TypeError("Error")
119        for effect_name, effect in other.effects.items():126        for effect_name, effect in other.effects.items():
120            if to_return.intensity[effect_name] > other.intensity[effect_name]:127            if to_return.intensity[effect_name] > other.intensity[effect_name]:
121                to_return.intensity[effect_name] -= other.intensity[effect_name]128                to_return.intensity[effect_name] -= other.intensity[effect_name]
122                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))129                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
123            else:130            else:
124                delattr(to_return, effect_name)131                delattr(to_return, effect_name)
125                del to_return.effects[effect_name]132                del to_return.effects[effect_name]
126                del to_return.intensity[effect_name]133                del to_return.intensity[effect_name]
127        for effect_name in self.effects:134        for effect_name in self.effects:
128            setattr(self, effect_name, self.already_used)135            setattr(self, effect_name, self.already_used)
129        for effect_name in other.effects:136        for effect_name in other.effects:
130            setattr(other, effect_name, other.already_used)137            setattr(other, effect_name, other.already_used)
131        self.was_used = other.was_used = True138        self.was_used = other.was_used = True
132        return to_return139        return to_return
133140
134    def __truediv__(self, value):141    def __truediv__(self, value):
135        if self.is_depleted():142        if self.is_depleted():
136            raise TypeError("Potion is depleted.")143            raise TypeError("Potion is depleted.")
137        if self.was_used == True:144        if self.was_used == True:
138            raise TypeError("Potion is now part of something bigger than itself.")145            raise TypeError("Potion is now part of something bigger than itself.")
n139        copy=Potion(self.effects,self.duration)n146        copy_potion=Potion(self.effects,self.duration)
140        for effect_name in self.intensity:147        for effect_name in self.intensity:
n141            copy.intensity[effect_name] = self.intensity[effect_name]n148            copy_potion.intensity[effect_name] = self.intensity[effect_name]
142        for effect_name,effect in copy.effects.items():149        for effect_name,effect in copy_potion.effects.items():
143            copy.intensity[effect_name] /= value150            copy_potion.intensity[effect_name] /= value
144            self.round_intensity(copy,effect_name)151            self.round_intensity(copy_potion,effect_name)
145            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])152            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])
n146            setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))        n153            setattr(copy_potion,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name]))        
147        potion_list=[]154        potion_list=[]
148        for _ in range(value):155        for _ in range(value):
nn156            copy=Potion(copy_potion.effects,copy_potion.duration)
157            for effect_name in copy_potion.intensity:
158                copy.intensity[effect_name] = copy_potion.intensity[effect_name]
159            for effect_name,effect in copy_potion.effects.items():
160                setattr(copy,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name]))
149            potion_list.append(copy)161            potion_list.append(copy)
150        for effect_name in self.effects:162        for effect_name in self.effects:
151            setattr(self, effect_name, self.already_used)163            setattr(self, effect_name, self.already_used)
152        self.was_used = True164        self.was_used = True
153        return tuple(potion_list)165        return tuple(potion_list)
154 166 
n155    def __bool__(self,other):n167    def __eq__(self,other):
156        if self.is_depleted() or other.is_depleted():168        if self.is_depleted() or other.is_depleted():
157            raise TypeError("Potion is depleted.")169            raise TypeError("Potion is depleted.")
158        if self.was_used == True or other.was_used == True:170        if self.was_used == True or other.was_used == True:
159            raise TypeError("Potion is now part of something bigger than itself.")171            raise TypeError("Potion is now part of something bigger than itself.")
160        for effect_name in self.effects:172        for effect_name in self.effects:
161            if effect_name not in other.effects:173            if effect_name not in other.effects:
162                return False174                return False
n163        for effect_name in self.effect:n175        for effect_name in self.effects:
164            if self.intensity[effect_name] != other.intensity[effect_name]:176            if self.intensity[effect_name] != other.intensity[effect_name]:
165                return False177                return False
166        return True178        return True
167    179    
168    def __gt__(self,other):180    def __gt__(self,other):
169        if self.is_depleted() or other.is_depleted():181        if self.is_depleted() or other.is_depleted():
170            raise TypeError("Potion is depleted.")182            raise TypeError("Potion is depleted.")
171        if self.was_used == True or other.was_used == True:183        if self.was_used == True or other.was_used == True:
172            raise TypeError("Potion is now part of something bigger than itself.")184            raise TypeError("Potion is now part of something bigger than itself.")
173        sum_of_self = 0185        sum_of_self = 0
174        for effect_name in self.intensity:186        for effect_name in self.intensity:
175            sum_of_self+=self.intensity[effect_name]187            sum_of_self+=self.intensity[effect_name]
176        sum_of_other = 0188        sum_of_other = 0
177        for effect_name in other.intensity:189        for effect_name in other.intensity:
178            sum_of_other += other.intensity[effect_name]190            sum_of_other += other.intensity[effect_name]
179        return sum_of_self > sum_of_other191        return sum_of_self > sum_of_other
nn192        
180193
181def sorting_potions(potion):194def sorting_potions(potion):
182        name = potion[0]195        name = potion[0]
183        sum_of_potion_name = 0196        sum_of_potion_name = 0
184        for letter in name:197        for letter in name:
185            sum_of_potion_name += ord(letter)198            sum_of_potion_name += ord(letter)
186        return sum_of_potion_name199        return sum_of_potion_name
187200
188201
189class ГоспожатаПоХимия:202class ГоспожатаПоХимия:
190    def __init__(self):203    def __init__(self):
191        self.used_potions = []204        self.used_potions = []
192        self.targets_copies = {}205        self.targets_copies = {}
193        self.targets_buffed_copies = {}206        self.targets_buffed_copies = {}
194207
195    def apply(self, target, potion):208    def apply(self, target, potion):
196        if potion.duration == 0:209        if potion.duration == 0:
197            return210            return
198        if potion.is_depleted():211        if potion.is_depleted():
199            raise TypeError("Potion is depleted.")212            raise TypeError("Potion is depleted.")
nn213        if potion.was_used:
214            raise TypeError("Potion is now part of something bigger than itself.")
200        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)215        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)
201        potion.effects = dict(sorted_potions)216        potion.effects = dict(sorted_potions)
n202        potion.was_used = Truen
203        if target not in self.targets_buffed_copies.values():217        if target not in self.targets_buffed_copies.values():
204            self.targets_copies[potion] = copy.copy(target)218            self.targets_copies[potion] = copy.copy(target)
205        else:219        else:
206            for potion_loop in self.used_potions:220            for potion_loop in self.used_potions:
nn221                potion_loop.was_used = False
207                if self.targets_buffed_copies[potion_loop] == target:222                if self.targets_buffed_copies[potion_loop] == target:
208                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])223                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])
nn224                potion_loop.was_used = True
209        self.used_potions.append(potion)225        self.used_potions.append(potion)
210        for effect_name in potion.effects:226        for effect_name in potion.effects:
211            function = getattr(potion, effect_name)227            function = getattr(potion, effect_name)
212            try:228            try:
213                function(target)229                function(target)
214            except TypeError:230            except TypeError:
215                continue231                continue
nn232        for potion_iter in self.used_potions:
233            potion_iter.was_used = False
216        self.targets_buffed_copies[potion] = target234        self.targets_buffed_copies[potion] = target
nn235        potion.was_used = True
236        for potion_iter in self.used_potions:
237            potion_iter.was_used = True
217    238    
218    def tick(self):239    def tick(self):
219        for potion in self.used_potions:240        for potion in self.used_potions:
220            potion.duration -= 1241            potion.duration -= 1
221            if potion.duration == 0:242            if potion.duration == 0:
222                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])243                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])
223                for potion_inner in self.used_potions:244                for potion_inner in self.used_potions:
nn245                    potion_inner.was_used = False
246                    potion.was_used = False
224                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:247                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:
nn248                        potion_inner.was_used = True
249                        potion.was_used = True
225                        continue250                        continue
tt251                    potion_inner.was_used = True
252                    potion.was_used = True
226                    copy = Potion(potion_inner.effects,potion_inner.duration)253                    copy = Potion(potion_inner.effects,potion_inner.duration)
227                    for effect_name,effect in  copy.effects.items():254                    for effect_name,effect in  copy.effects.items():
228                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]255                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]
229                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))256                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))
230                    for effect_name in  copy.effects:257                    for effect_name in  copy.effects:
231                        function = getattr(copy, effect_name)258                        function = getattr(copy, effect_name)
232                        function(self.targets_buffed_copies[potion])259                        function(self.targets_buffed_copies[potion])
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
2import copy2import copy
33
4def once(func):4def once(func):
5    def wrapper(target):5    def wrapper(target):
6        if wrapper.called:6        if wrapper.called:
7            raise TypeError("Effect is depleted.")7            raise TypeError("Effect is depleted.")
8        wrapper.called = True8        wrapper.called = True
9        func(target)9        func(target)
10    wrapper.called = False10    wrapper.called = False
11    return wrapper11    return wrapper
1212
13def calling_function_decorator(function, times):13def calling_function_decorator(function, times):
14    @once14    @once
15    def decorator(target):15    def decorator(target):
16        for _ in range(times):16        for _ in range(times):
17            function(target)17            function(target)
18    return decorator18    return decorator
1919
20class Potion:20class Potion:
2121
22    def round_intensity(self,to_return,effect_name):22    def round_intensity(self,to_return,effect_name):
n23         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])n23         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name])
2424
25    def is_depleted(self):25    def is_depleted(self):
26         is_depleted = True26         is_depleted = True
27         for effect_name,effect in self.effects.items():27         for effect_name,effect in self.effects.items():
28            function = getattr(self, effect_name)28            function = getattr(self, effect_name)
29            try:29            try:
30                function(None)               30                function(None)               
31            except TypeError:31            except TypeError:
32                is_depleted = True32                is_depleted = True
33            except AttributeError:33            except AttributeError:
34                is_depleted = False34                is_depleted = False
35                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))35                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
36         return is_depleted36         return is_depleted
37    37    
38    @staticmethod38    @staticmethod
39    def already_used(target):39    def already_used(target):
40        raise TypeError("Potion is now part of something bigger than itself.")40        raise TypeError("Potion is now part of something bigger than itself.")
41    41    
42    def __init__(self,effects, duration):42    def __init__(self,effects, duration):
43        self.effects = copy.copy(effects)43        self.effects = copy.copy(effects)
44        self.was_used = False44        self.was_used = False
45        self.intensity = {}45        self.intensity = {}
46        for effect_name in self.effects:46        for effect_name in self.effects:
47            self.intensity[effect_name] = 147            self.intensity[effect_name] = 1
48        for effect_name,effect in effects.items():48        for effect_name,effect in effects.items():
49             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))49             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
50             self.effects[effect_name] = effect50             self.effects[effect_name] = effect
51        self.duration = duration51        self.duration = duration
5252
53    def __add__(self, other):53    def __add__(self, other):
54        if self.is_depleted() or other.is_depleted():54        if self.is_depleted() or other.is_depleted():
55            raise TypeError("Potion is depleted.")55            raise TypeError("Potion is depleted.")
56        if self.was_used == True or other.was_used == True:56        if self.was_used == True or other.was_used == True:
57            raise TypeError("Potion is now part of something bigger than itself.")57            raise TypeError("Potion is now part of something bigger than itself.")
58        to_return = Potion(self.effects, max(self.duration, other.duration)) 58        to_return = Potion(self.effects, max(self.duration, other.duration)) 
59        for effect_name,effect in to_return.effects.items():59        for effect_name,effect in to_return.effects.items():
60            to_return.intensity[effect_name]=self.intensity[effect_name]60            to_return.intensity[effect_name]=self.intensity[effect_name]
61            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))61            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
62        for effect_name,effect in other.effects.items():62        for effect_name,effect in other.effects.items():
63            if effect_name in to_return.effects:63            if effect_name in to_return.effects:
64                to_return.intensity[effect_name] += 1       64                to_return.intensity[effect_name] += 1       
65                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))65                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
66            else:66            else:
n67                to_return.intensity[effect_name] = 1   n67                to_return.intensity[effect_name] = other.intensity[effect_name]   
68                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))68                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
69                to_return.effects[effect_name] = effect69                to_return.effects[effect_name] = effect
70        for effect_name in self.effects:70        for effect_name in self.effects:
71            setattr(self, effect_name, self.already_used)71            setattr(self, effect_name, self.already_used)
72        for effect_name in other.effects:72        for effect_name in other.effects:
73            setattr(other, effect_name, other.already_used)73            setattr(other, effect_name, other.already_used)
74        self.was_used = other.was_used = True74        self.was_used = other.was_used = True
75        return to_return75        return to_return
76    76    
77    def __mul__(self, value):77    def __mul__(self, value):
78        if self.is_depleted():78        if self.is_depleted():
79            raise TypeError("Potion is depleted.")79            raise TypeError("Potion is depleted.")
80        if self.was_used == True:80        if self.was_used == True:
81            raise TypeError("Potion is now part of something bigger than itself.")81            raise TypeError("Potion is now part of something bigger than itself.")
82        if value >= 0 and value <= 1:82        if value >= 0 and value <= 1:
83            to_return = Potion(self.effects, self.duration)83            to_return = Potion(self.effects, self.duration)
84            for effect_name in to_return.effects:84            for effect_name in to_return.effects:
85                to_return.intensity[effect_name] = self.intensity[effect_name]85                to_return.intensity[effect_name] = self.intensity[effect_name]
n86            for effect_name in to_return.effects:n86            for effect_name,effect in to_return.effects.items():
87                to_return.intensity[effect_name] *= value87                to_return.intensity[effect_name] *= value
88                self.round_intensity(to_return,effect_name)88                self.round_intensity(to_return,effect_name)
nn89                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
89               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])90               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])              
90            for effect_name,effect in to_return.effects.items():
91                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
92            for effect_name in self.effects:91            for effect_name in self.effects:
93                setattr(self, effect_name, self.already_used)92                setattr(self, effect_name, self.already_used)
94            self.was_used = True93            self.was_used = True
95            return to_return94            return to_return
96        to_return = Potion(self.effects, self.duration)95        to_return = Potion(self.effects, self.duration)
97        for effect_name in to_return.effects:96        for effect_name in to_return.effects:
98            to_return.intensity[effect_name] = self.intensity[effect_name]97            to_return.intensity[effect_name] = self.intensity[effect_name]
99        for effect_name in to_return.effects:98        for effect_name in to_return.effects:
100            to_return.intensity[effect_name] *= value99            to_return.intensity[effect_name] *= value
101        for effect_name,effect in to_return.effects.items():100        for effect_name,effect in to_return.effects.items():
102             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))101             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
103        for effect_name in self.effects:102        for effect_name in self.effects:
104            setattr(self, effect_name, self.already_used)103            setattr(self, effect_name, self.already_used)
105        self.was_used = True104        self.was_used = True
106        return to_return105        return to_return
107    106    
108    def __sub__(self, other):107    def __sub__(self, other):
109        if self.is_depleted() or other.is_depleted():108        if self.is_depleted() or other.is_depleted():
110            raise TypeError("Potion is depleted.")109            raise TypeError("Potion is depleted.")
111        if self.was_used == True or other.was_used == True:110        if self.was_used == True or other.was_used == True:
112            raise TypeError("Potion is now part of something bigger than itself.")111            raise TypeError("Potion is now part of something bigger than itself.")
113        to_return = Potion(self.effects, self.duration)112        to_return = Potion(self.effects, self.duration)
114        for effect_name,effect in to_return.effects.items():113        for effect_name,effect in to_return.effects.items():
115            to_return.intensity[effect_name] = self.intensity[effect_name]114            to_return.intensity[effect_name] = self.intensity[effect_name]
116            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))115            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))
117        for effect in other.effects.values():116        for effect in other.effects.values():
118            if effect not in to_return.effects.values():117            if effect not in to_return.effects.values():
119                raise TypeError("Error")118                raise TypeError("Error")
120        for effect_name, effect in other.effects.items():119        for effect_name, effect in other.effects.items():
121            if to_return.intensity[effect_name] > other.intensity[effect_name]:120            if to_return.intensity[effect_name] > other.intensity[effect_name]:
122                to_return.intensity[effect_name] -= other.intensity[effect_name]121                to_return.intensity[effect_name] -= other.intensity[effect_name]
123                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))122                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
124            else:123            else:
125                delattr(to_return, effect_name)124                delattr(to_return, effect_name)
126                del to_return.effects[effect_name]125                del to_return.effects[effect_name]
127                del to_return.intensity[effect_name]126                del to_return.intensity[effect_name]
128        for effect_name in self.effects:127        for effect_name in self.effects:
129            setattr(self, effect_name, self.already_used)128            setattr(self, effect_name, self.already_used)
130        for effect_name in other.effects:129        for effect_name in other.effects:
131            setattr(other, effect_name, other.already_used)130            setattr(other, effect_name, other.already_used)
132        self.was_used = other.was_used = True131        self.was_used = other.was_used = True
133        return to_return132        return to_return
134133
135    def __truediv__(self, value):134    def __truediv__(self, value):
136        if self.is_depleted():135        if self.is_depleted():
137            raise TypeError("Potion is depleted.")136            raise TypeError("Potion is depleted.")
138        if self.was_used == True:137        if self.was_used == True:
139            raise TypeError("Potion is now part of something bigger than itself.")138            raise TypeError("Potion is now part of something bigger than itself.")
140        copy=Potion(self.effects,self.duration)139        copy=Potion(self.effects,self.duration)
141        for effect_name in self.intensity:140        for effect_name in self.intensity:
142            copy.intensity[effect_name] = self.intensity[effect_name]141            copy.intensity[effect_name] = self.intensity[effect_name]
143        for effect_name,effect in copy.effects.items():142        for effect_name,effect in copy.effects.items():
144            copy.intensity[effect_name] /= value143            copy.intensity[effect_name] /= value
145            self.round_intensity(copy,effect_name)144            self.round_intensity(copy,effect_name)
146            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])145            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])
147            setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))        146            setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))        
148        potion_list=[]147        potion_list=[]
149        for _ in range(value):148        for _ in range(value):
150            potion_list.append(copy)149            potion_list.append(copy)
151        for effect_name in self.effects:150        for effect_name in self.effects:
152            setattr(self, effect_name, self.already_used)151            setattr(self, effect_name, self.already_used)
153        self.was_used = True152        self.was_used = True
154        return tuple(potion_list)153        return tuple(potion_list)
155 154 
156    def __bool__(self,other):155    def __bool__(self,other):
157        if self.is_depleted() or other.is_depleted():156        if self.is_depleted() or other.is_depleted():
158            raise TypeError("Potion is depleted.")157            raise TypeError("Potion is depleted.")
159        if self.was_used == True or other.was_used == True:158        if self.was_used == True or other.was_used == True:
160            raise TypeError("Potion is now part of something bigger than itself.")159            raise TypeError("Potion is now part of something bigger than itself.")
161        for effect_name in self.effects:160        for effect_name in self.effects:
162            if effect_name not in other.effects:161            if effect_name not in other.effects:
163                return False162                return False
164        for effect_name in self.effect:163        for effect_name in self.effect:
165            if self.intensity[effect_name] != other.intensity[effect_name]:164            if self.intensity[effect_name] != other.intensity[effect_name]:
166                return False165                return False
167        return True166        return True
168    167    
169    def __gt__(self,other):168    def __gt__(self,other):
170        if self.is_depleted() or other.is_depleted():169        if self.is_depleted() or other.is_depleted():
171            raise TypeError("Potion is depleted.")170            raise TypeError("Potion is depleted.")
172        if self.was_used == True or other.was_used == True:171        if self.was_used == True or other.was_used == True:
173            raise TypeError("Potion is now part of something bigger than itself.")172            raise TypeError("Potion is now part of something bigger than itself.")
174        sum_of_self = 0173        sum_of_self = 0
175        for effect_name in self.intensity:174        for effect_name in self.intensity:
176            sum_of_self+=self.intensity[effect_name]175            sum_of_self+=self.intensity[effect_name]
177        sum_of_other = 0176        sum_of_other = 0
178        for effect_name in other.intensity:177        for effect_name in other.intensity:
179            sum_of_other += other.intensity[effect_name]178            sum_of_other += other.intensity[effect_name]
180        return sum_of_self > sum_of_other179        return sum_of_self > sum_of_other
181180
182def sorting_potions(potion):181def sorting_potions(potion):
183        name = potion[0]182        name = potion[0]
184        sum_of_potion_name = 0183        sum_of_potion_name = 0
185        for letter in name:184        for letter in name:
186            sum_of_potion_name += ord(letter)185            sum_of_potion_name += ord(letter)
187        return sum_of_potion_name186        return sum_of_potion_name
188187
189188
190class ГоспожатаПоХимия:189class ГоспожатаПоХимия:
191    def __init__(self):190    def __init__(self):
192        self.used_potions = []191        self.used_potions = []
193        self.targets_copies = {}192        self.targets_copies = {}
194        self.targets_buffed_copies = {}193        self.targets_buffed_copies = {}
195194
196    def apply(self, target, potion):195    def apply(self, target, potion):
tt196        if potion.duration == 0:
197            return
197        if potion.is_depleted():198        if potion.is_depleted():
198            raise TypeError("Potion is depleted.")199            raise TypeError("Potion is depleted.")
199        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)200        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)
200        potion.effects = dict(sorted_potions)201        potion.effects = dict(sorted_potions)
201        potion.was_used = True202        potion.was_used = True
202        if target not in self.targets_buffed_copies.values():203        if target not in self.targets_buffed_copies.values():
203            self.targets_copies[potion] = copy.copy(target)204            self.targets_copies[potion] = copy.copy(target)
204        else:205        else:
205            for potion_loop in self.used_potions:206            for potion_loop in self.used_potions:
206                if self.targets_buffed_copies[potion_loop] == target:207                if self.targets_buffed_copies[potion_loop] == target:
207                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])208                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])
208        self.used_potions.append(potion)209        self.used_potions.append(potion)
209        for effect_name in potion.effects:210        for effect_name in potion.effects:
210            function = getattr(potion, effect_name)211            function = getattr(potion, effect_name)
211            try:212            try:
212                function(target)213                function(target)
213            except TypeError:214            except TypeError:
214                continue215                continue
215        self.targets_buffed_copies[potion] = target216        self.targets_buffed_copies[potion] = target
216    217    
217    def tick(self):218    def tick(self):
218        for potion in self.used_potions:219        for potion in self.used_potions:
219            potion.duration -= 1220            potion.duration -= 1
220            if potion.duration == 0:221            if potion.duration == 0:
221                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])222                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])
222                for potion_inner in self.used_potions:223                for potion_inner in self.used_potions:
223                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:224                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:
224                        continue225                        continue
225                    copy = Potion(potion_inner.effects,potion_inner.duration)226                    copy = Potion(potion_inner.effects,potion_inner.duration)
226                    for effect_name,effect in  copy.effects.items():227                    for effect_name,effect in  copy.effects.items():
227                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]228                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]
228                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))229                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))
229                    for effect_name in  copy.effects:230                    for effect_name in  copy.effects:
230                        function = getattr(copy, effect_name)231                        function = getattr(copy, effect_name)
231                        function(self.targets_buffed_copies[potion])232                        function(self.targets_buffed_copies[potion])
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
2import copy2import copy
33
4def once(func):4def once(func):
5    def wrapper(target):5    def wrapper(target):
6        if wrapper.called:6        if wrapper.called:
7            raise TypeError("Effect is depleted.")7            raise TypeError("Effect is depleted.")
8        wrapper.called = True8        wrapper.called = True
9        func(target)9        func(target)
10    wrapper.called = False10    wrapper.called = False
11    return wrapper11    return wrapper
1212
13def calling_function_decorator(function, times):13def calling_function_decorator(function, times):
14    @once14    @once
15    def decorator(target):15    def decorator(target):
16        for _ in range(times):16        for _ in range(times):
17            function(target)17            function(target)
18    return decorator18    return decorator
1919
20class Potion:20class Potion:
2121
22    def round_intensity(self,to_return,effect_name):22    def round_intensity(self,to_return,effect_name):
23         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])23         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])
2424
25    def is_depleted(self):25    def is_depleted(self):
26         is_depleted = True26         is_depleted = True
27         for effect_name,effect in self.effects.items():27         for effect_name,effect in self.effects.items():
28            function = getattr(self, effect_name)28            function = getattr(self, effect_name)
29            try:29            try:
30                function(None)               30                function(None)               
31            except TypeError:31            except TypeError:
32                is_depleted = True32                is_depleted = True
33            except AttributeError:33            except AttributeError:
34                is_depleted = False34                is_depleted = False
35                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))35                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
36         return is_depleted36         return is_depleted
37    37    
38    @staticmethod38    @staticmethod
39    def already_used(target):39    def already_used(target):
40        raise TypeError("Potion is now part of something bigger than itself.")40        raise TypeError("Potion is now part of something bigger than itself.")
41    41    
42    def __init__(self,effects, duration):42    def __init__(self,effects, duration):
43        self.effects = copy.copy(effects)43        self.effects = copy.copy(effects)
44        self.was_used = False44        self.was_used = False
45        self.intensity = {}45        self.intensity = {}
46        for effect_name in self.effects:46        for effect_name in self.effects:
47            self.intensity[effect_name] = 147            self.intensity[effect_name] = 1
48        for effect_name,effect in effects.items():48        for effect_name,effect in effects.items():
49             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))49             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
50             self.effects[effect_name] = effect50             self.effects[effect_name] = effect
51        self.duration = duration51        self.duration = duration
5252
53    def __add__(self, other):53    def __add__(self, other):
n54        if self.is_depleted():n54        if self.is_depleted() or other.is_depleted():
55            raise TypeError("Potion is depleted.")55            raise TypeError("Potion is depleted.")
56        if self.was_used == True or other.was_used == True:56        if self.was_used == True or other.was_used == True:
57            raise TypeError("Potion is now part of something bigger than itself.")57            raise TypeError("Potion is now part of something bigger than itself.")
58        to_return = Potion(self.effects, max(self.duration, other.duration)) 58        to_return = Potion(self.effects, max(self.duration, other.duration)) 
59        for effect_name,effect in to_return.effects.items():59        for effect_name,effect in to_return.effects.items():
60            to_return.intensity[effect_name]=self.intensity[effect_name]60            to_return.intensity[effect_name]=self.intensity[effect_name]
61            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))61            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
62        for effect_name,effect in other.effects.items():62        for effect_name,effect in other.effects.items():
63            if effect_name in to_return.effects:63            if effect_name in to_return.effects:
64                to_return.intensity[effect_name] += 1       64                to_return.intensity[effect_name] += 1       
65                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))65                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
66            else:66            else:
67                to_return.intensity[effect_name] = 1   67                to_return.intensity[effect_name] = 1   
68                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))68                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
69                to_return.effects[effect_name] = effect69                to_return.effects[effect_name] = effect
70        for effect_name in self.effects:70        for effect_name in self.effects:
71            setattr(self, effect_name, self.already_used)71            setattr(self, effect_name, self.already_used)
72        for effect_name in other.effects:72        for effect_name in other.effects:
73            setattr(other, effect_name, other.already_used)73            setattr(other, effect_name, other.already_used)
74        self.was_used = other.was_used = True74        self.was_used = other.was_used = True
75        return to_return75        return to_return
76    76    
77    def __mul__(self, value):77    def __mul__(self, value):
78        if self.is_depleted():78        if self.is_depleted():
79            raise TypeError("Potion is depleted.")79            raise TypeError("Potion is depleted.")
80        if self.was_used == True:80        if self.was_used == True:
81            raise TypeError("Potion is now part of something bigger than itself.")81            raise TypeError("Potion is now part of something bigger than itself.")
82        if value >= 0 and value <= 1:82        if value >= 0 and value <= 1:
83            to_return = Potion(self.effects, self.duration)83            to_return = Potion(self.effects, self.duration)
84            for effect_name in to_return.effects:84            for effect_name in to_return.effects:
85                to_return.intensity[effect_name] = self.intensity[effect_name]85                to_return.intensity[effect_name] = self.intensity[effect_name]
86            for effect_name in to_return.effects:86            for effect_name in to_return.effects:
87                to_return.intensity[effect_name] *= value87                to_return.intensity[effect_name] *= value
88                self.round_intensity(to_return,effect_name)88                self.round_intensity(to_return,effect_name)
89               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])89               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])
90            for effect_name,effect in to_return.effects.items():90            for effect_name,effect in to_return.effects.items():
91                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))91                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
92            for effect_name in self.effects:92            for effect_name in self.effects:
93                setattr(self, effect_name, self.already_used)93                setattr(self, effect_name, self.already_used)
94            self.was_used = True94            self.was_used = True
95            return to_return95            return to_return
96        to_return = Potion(self.effects, self.duration)96        to_return = Potion(self.effects, self.duration)
97        for effect_name in to_return.effects:97        for effect_name in to_return.effects:
98            to_return.intensity[effect_name] = self.intensity[effect_name]98            to_return.intensity[effect_name] = self.intensity[effect_name]
99        for effect_name in to_return.effects:99        for effect_name in to_return.effects:
100            to_return.intensity[effect_name] *= value100            to_return.intensity[effect_name] *= value
101        for effect_name,effect in to_return.effects.items():101        for effect_name,effect in to_return.effects.items():
102             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))102             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
103        for effect_name in self.effects:103        for effect_name in self.effects:
104            setattr(self, effect_name, self.already_used)104            setattr(self, effect_name, self.already_used)
105        self.was_used = True105        self.was_used = True
106        return to_return106        return to_return
107    107    
108    def __sub__(self, other):108    def __sub__(self, other):
n109        if self.is_depleted():n109        if self.is_depleted() or other.is_depleted():
110            raise TypeError("Potion is depleted.")110            raise TypeError("Potion is depleted.")
111        if self.was_used == True or other.was_used == True:111        if self.was_used == True or other.was_used == True:
112            raise TypeError("Potion is now part of something bigger than itself.")112            raise TypeError("Potion is now part of something bigger than itself.")
113        to_return = Potion(self.effects, self.duration)113        to_return = Potion(self.effects, self.duration)
114        for effect_name,effect in to_return.effects.items():114        for effect_name,effect in to_return.effects.items():
115            to_return.intensity[effect_name] = self.intensity[effect_name]115            to_return.intensity[effect_name] = self.intensity[effect_name]
116            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))116            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))
117        for effect in other.effects.values():117        for effect in other.effects.values():
118            if effect not in to_return.effects.values():118            if effect not in to_return.effects.values():
119                raise TypeError("Error")119                raise TypeError("Error")
120        for effect_name, effect in other.effects.items():120        for effect_name, effect in other.effects.items():
121            if to_return.intensity[effect_name] > other.intensity[effect_name]:121            if to_return.intensity[effect_name] > other.intensity[effect_name]:
122                to_return.intensity[effect_name] -= other.intensity[effect_name]122                to_return.intensity[effect_name] -= other.intensity[effect_name]
123                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))123                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
124            else:124            else:
125                delattr(to_return, effect_name)125                delattr(to_return, effect_name)
126                del to_return.effects[effect_name]126                del to_return.effects[effect_name]
127                del to_return.intensity[effect_name]127                del to_return.intensity[effect_name]
128        for effect_name in self.effects:128        for effect_name in self.effects:
129            setattr(self, effect_name, self.already_used)129            setattr(self, effect_name, self.already_used)
130        for effect_name in other.effects:130        for effect_name in other.effects:
131            setattr(other, effect_name, other.already_used)131            setattr(other, effect_name, other.already_used)
132        self.was_used = other.was_used = True132        self.was_used = other.was_used = True
133        return to_return133        return to_return
134134
135    def __truediv__(self, value):135    def __truediv__(self, value):
136        if self.is_depleted():136        if self.is_depleted():
137            raise TypeError("Potion is depleted.")137            raise TypeError("Potion is depleted.")
138        if self.was_used == True:138        if self.was_used == True:
139            raise TypeError("Potion is now part of something bigger than itself.")139            raise TypeError("Potion is now part of something bigger than itself.")
140        copy=Potion(self.effects,self.duration)140        copy=Potion(self.effects,self.duration)
141        for effect_name in self.intensity:141        for effect_name in self.intensity:
142            copy.intensity[effect_name] = self.intensity[effect_name]142            copy.intensity[effect_name] = self.intensity[effect_name]
143        for effect_name,effect in copy.effects.items():143        for effect_name,effect in copy.effects.items():
144            copy.intensity[effect_name] /= value144            copy.intensity[effect_name] /= value
145            self.round_intensity(copy,effect_name)145            self.round_intensity(copy,effect_name)
146            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])146            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])
147            setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))        147            setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))        
148        potion_list=[]148        potion_list=[]
149        for _ in range(value):149        for _ in range(value):
150            potion_list.append(copy)150            potion_list.append(copy)
151        for effect_name in self.effects:151        for effect_name in self.effects:
152            setattr(self, effect_name, self.already_used)152            setattr(self, effect_name, self.already_used)
153        self.was_used = True153        self.was_used = True
154        return tuple(potion_list)154        return tuple(potion_list)
155 155 
156    def __bool__(self,other):156    def __bool__(self,other):
n157 n157        if self.is_depleted() or other.is_depleted():
158            raise TypeError("Potion is depleted.")
159        if self.was_used == True or other.was_used == True:
160            raise TypeError("Potion is now part of something bigger than itself.")
158        for effect_name in self.effects:161        for effect_name in self.effects:
159            if effect_name not in other.effects:162            if effect_name not in other.effects:
160                return False163                return False
161        for effect_name in self.effect:164        for effect_name in self.effect:
162            if self.intensity[effect_name] != other.intensity[effect_name]:165            if self.intensity[effect_name] != other.intensity[effect_name]:
163                return False166                return False
164        return True167        return True
165    168    
166    def __gt__(self,other):169    def __gt__(self,other):
tt170        if self.is_depleted() or other.is_depleted():
171            raise TypeError("Potion is depleted.")
172        if self.was_used == True or other.was_used == True:
173            raise TypeError("Potion is now part of something bigger than itself.")
167        sum_of_self = 0174        sum_of_self = 0
168        for effect_name in self.intensity:175        for effect_name in self.intensity:
169            sum_of_self+=self.intensity[effect_name]176            sum_of_self+=self.intensity[effect_name]
170        sum_of_other = 0177        sum_of_other = 0
171        for effect_name in other.intensity:178        for effect_name in other.intensity:
172            sum_of_other += other.intensity[effect_name]179            sum_of_other += other.intensity[effect_name]
173        return sum_of_self > sum_of_other180        return sum_of_self > sum_of_other
174181
175def sorting_potions(potion):182def sorting_potions(potion):
176        name = potion[0]183        name = potion[0]
177        sum_of_potion_name = 0184        sum_of_potion_name = 0
178        for letter in name:185        for letter in name:
179            sum_of_potion_name += ord(letter)186            sum_of_potion_name += ord(letter)
180        return sum_of_potion_name187        return sum_of_potion_name
181188
182189
183class ГоспожатаПоХимия:190class ГоспожатаПоХимия:
184    def __init__(self):191    def __init__(self):
185        self.used_potions = []192        self.used_potions = []
186        self.targets_copies = {}193        self.targets_copies = {}
187        self.targets_buffed_copies = {}194        self.targets_buffed_copies = {}
188195
189    def apply(self, target, potion):196    def apply(self, target, potion):
190        if potion.is_depleted():197        if potion.is_depleted():
191            raise TypeError("Potion is depleted.")198            raise TypeError("Potion is depleted.")
192        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)199        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)
193        potion.effects = dict(sorted_potions)200        potion.effects = dict(sorted_potions)
194        potion.was_used = True201        potion.was_used = True
195        if target not in self.targets_buffed_copies.values():202        if target not in self.targets_buffed_copies.values():
196            self.targets_copies[potion] = copy.copy(target)203            self.targets_copies[potion] = copy.copy(target)
197        else:204        else:
198            for potion_loop in self.used_potions:205            for potion_loop in self.used_potions:
199                if self.targets_buffed_copies[potion_loop] == target:206                if self.targets_buffed_copies[potion_loop] == target:
200                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])207                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])
201        self.used_potions.append(potion)208        self.used_potions.append(potion)
202        for effect_name in potion.effects:209        for effect_name in potion.effects:
203            function = getattr(potion, effect_name)210            function = getattr(potion, effect_name)
204            try:211            try:
205                function(target)212                function(target)
206            except TypeError:213            except TypeError:
207                continue214                continue
208        self.targets_buffed_copies[potion] = target215        self.targets_buffed_copies[potion] = target
209    216    
210    def tick(self):217    def tick(self):
211        for potion in self.used_potions:218        for potion in self.used_potions:
212            potion.duration -= 1219            potion.duration -= 1
213            if potion.duration == 0:220            if potion.duration == 0:
214                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])221                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])
215                for potion_inner in self.used_potions:222                for potion_inner in self.used_potions:
216                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:223                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:
217                        continue224                        continue
218                    copy = Potion(potion_inner.effects,potion_inner.duration)225                    copy = Potion(potion_inner.effects,potion_inner.duration)
219                    for effect_name,effect in  copy.effects.items():226                    for effect_name,effect in  copy.effects.items():
220                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]227                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]
221                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))228                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))
222                    for effect_name in  copy.effects:229                    for effect_name in  copy.effects:
223                        function = getattr(copy, effect_name)230                        function = getattr(copy, effect_name)
224                        function(self.targets_buffed_copies[potion])231                        function(self.targets_buffed_copies[potion])
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
2import copy2import copy
33
4def once(func):4def once(func):
5    def wrapper(target):5    def wrapper(target):
6        if wrapper.called:6        if wrapper.called:
7            raise TypeError("Effect is depleted.")7            raise TypeError("Effect is depleted.")
8        wrapper.called = True8        wrapper.called = True
9        func(target)9        func(target)
10    wrapper.called = False10    wrapper.called = False
11    return wrapper11    return wrapper
1212
n13 n
14def calling_function_decorator(function,times):13def calling_function_decorator(function, times):
15    @once14    @once
16    def decorator(target):15    def decorator(target):
17        for _ in range(times):16        for _ in range(times):
18            function(target)17            function(target)
19    return decorator18    return decorator
2019
21class Potion:20class Potion:
2221
nn22    def round_intensity(self,to_return,effect_name):
23         to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])
24 
23    def is_depleted(self):25    def is_depleted(self):
n24         is_depleted=Truen26         is_depleted = True
25         for effect_name,effect in self.effects.items():27         for effect_name,effect in self.effects.items():
n26            function=getattr(self,effect_name)n28            function = getattr(self, effect_name)
27            try:29            try:
28                function(None)               30                function(None)               
29            except TypeError:31            except TypeError:
n30                is_depleted=Truen32                is_depleted = True
31            except AttributeError:33            except AttributeError:
n32                is_depleted=Falsen34                is_depleted = False
33                setattr(self,effect_name,calling_function_decorator(effect,self.intensity[effect_name]))35                setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
34         return is_depleted36         return is_depleted
n35                n37    
36    @staticmethod38    @staticmethod
37    def already_used(target):39    def already_used(target):
38        raise TypeError("Potion is now part of something bigger than itself.")40        raise TypeError("Potion is now part of something bigger than itself.")
39    41    
n40    def __init__(self,effects,duration):n42    def __init__(self,effects, duration):
41        self.effects=effects43        self.effects = copy.copy(effects)
42        self.was_used=False44        self.was_used = False
43        self.intensity={}45        self.intensity = {}
44        for effect_name in self.effects:46        for effect_name in self.effects:
n45            self.intensity[effect_name]=1n47            self.intensity[effect_name] = 1
46        for effect_name,effect in effects.items():48        for effect_name,effect in effects.items():
n47             setattr(self,effect_name,calling_function_decorator(effect,self.intensity[effect_name]))n49             setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
48             self.effects[effect_name]=effect50             self.effects[effect_name] = effect
49        self.duration=duration51        self.duration = duration
50 
51 
5252
53    def __add__(self, other):53    def __add__(self, other):
54        if self.is_depleted():54        if self.is_depleted():
55            raise TypeError("Potion is depleted.")55            raise TypeError("Potion is depleted.")
56        if self.was_used == True or other.was_used == True:56        if self.was_used == True or other.was_used == True:
57            raise TypeError("Potion is now part of something bigger than itself.")57            raise TypeError("Potion is now part of something bigger than itself.")
n58        to_return = Potion(self.effects,max(self.duration,other.duration)) n58        to_return = Potion(self.effects, max(self.duration, other.duration)) 
59        for effect_name,effect in to_return.effects.items():59        for effect_name,effect in to_return.effects.items():
60            to_return.intensity[effect_name]=self.intensity[effect_name]60            to_return.intensity[effect_name]=self.intensity[effect_name]
n61            setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))n61            setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
62        for effect_name,effect in other.effects.items():62        for effect_name,effect in other.effects.items():
63            if effect_name in to_return.effects:63            if effect_name in to_return.effects:
n64                to_return.intensity[effect_name]+=1       n64                to_return.intensity[effect_name] += 1       
65                setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))65                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
66            else:66            else:
n67                to_return.intensity[effect_name]=1   n67                to_return.intensity[effect_name] = 1   
68                setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))68                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
69                to_return.effects[effect_name]=effect69                to_return.effects[effect_name] = effect
70        for effect_name in self.effects:70        for effect_name in self.effects:
n71            setattr(self,effect_name,self.already_used)n71            setattr(self, effect_name, self.already_used)
72        for effect_name in other.effects:72        for effect_name in other.effects:
n73            setattr(other,effect_name,other.already_used)n73            setattr(other, effect_name, other.already_used)
74        self.was_used=other.was_used=True74        self.was_used = other.was_used = True
75        return to_return75        return to_return
76    76    
77    def __mul__(self, value):77    def __mul__(self, value):
78        if self.is_depleted():78        if self.is_depleted():
79            raise TypeError("Potion is depleted.")79            raise TypeError("Potion is depleted.")
80        if self.was_used == True:80        if self.was_used == True:
81            raise TypeError("Potion is now part of something bigger than itself.")81            raise TypeError("Potion is now part of something bigger than itself.")
n82        if value>= 0 and value <= 1:n82        if value >= 0 and value <= 1:
83            to_return = Potion(self.effects,self.duration)83            to_return = Potion(self.effects, self.duration)
84            for effect_name in to_return.effects:84            for effect_name in to_return.effects:
n85                to_return.intensity[effect_name]=self.intensity[effect_name]n85                to_return.intensity[effect_name] = self.intensity[effect_name]
86            for effect_name in to_return.effects:86            for effect_name in to_return.effects:
87                to_return.intensity[effect_name] *= value87                to_return.intensity[effect_name] *= value
nn88                self.round_intensity(to_return,effect_name)
88                to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name]<=0.5 else math.ceil(to_return.intensity[effect_name])89               #  to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if  to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])
89            for effect_name,effect in to_return.effects.items():90            for effect_name,effect in to_return.effects.items():
n90                setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))n91                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
91            for effect_name in self.effects:92            for effect_name in self.effects:
n92                setattr(self,effect_name,self.already_used)n93                setattr(self, effect_name, self.already_used)
93            self.was_used=True94            self.was_used = True
94            return to_return95            return to_return
n95 n
96        to_return = Potion(self.effects,self.duration)96        to_return = Potion(self.effects, self.duration)
97        for effect_name in to_return.effects:97        for effect_name in to_return.effects:
n98            to_return.intensity[effect_name]=self.intensity[effect_name]n98            to_return.intensity[effect_name] = self.intensity[effect_name]
99        for effect_name in to_return.effects:99        for effect_name in to_return.effects:
100            to_return.intensity[effect_name] *= value100            to_return.intensity[effect_name] *= value
101        for effect_name,effect in to_return.effects.items():101        for effect_name,effect in to_return.effects.items():
n102             setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))n102             setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
103        for effect_name in self.effects:103        for effect_name in self.effects:
n104            setattr(self,effect_name,self.already_used)n104            setattr(self, effect_name, self.already_used)
105        self.was_used=True105        self.was_used = True
106        return to_return106        return to_return
107    107    
108    def __sub__(self, other):108    def __sub__(self, other):
109        if self.is_depleted():109        if self.is_depleted():
110            raise TypeError("Potion is depleted.")110            raise TypeError("Potion is depleted.")
111        if self.was_used == True or other.was_used == True:111        if self.was_used == True or other.was_used == True:
112            raise TypeError("Potion is now part of something bigger than itself.")112            raise TypeError("Potion is now part of something bigger than itself.")
n113        to_return = Potion(self.effects,self.duration)n113        to_return = Potion(self.effects, self.duration)
114        for effect_name,effect in to_return.effects.items():114        for effect_name,effect in to_return.effects.items():
n115            to_return.intensity[effect_name]=self.intensity[effect_name]n115            to_return.intensity[effect_name] = self.intensity[effect_name]
116            setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))116            setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))
117        for effect in other.effects.values():117        for effect in other.effects.values():
118            if effect not in to_return.effects.values():118            if effect not in to_return.effects.values():
119                raise TypeError("Error")119                raise TypeError("Error")
120        for effect_name, effect in other.effects.items():120        for effect_name, effect in other.effects.items():
121            if to_return.intensity[effect_name] > other.intensity[effect_name]:121            if to_return.intensity[effect_name] > other.intensity[effect_name]:
122                to_return.intensity[effect_name] -= other.intensity[effect_name]122                to_return.intensity[effect_name] -= other.intensity[effect_name]
n123                setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name]))n123                setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
124            else:124            else:
125                delattr(to_return, effect_name)125                delattr(to_return, effect_name)
126                del to_return.effects[effect_name]126                del to_return.effects[effect_name]
127                del to_return.intensity[effect_name]127                del to_return.intensity[effect_name]
128        for effect_name in self.effects:128        for effect_name in self.effects:
n129            setattr(self,effect_name,self.already_used)n129            setattr(self, effect_name, self.already_used)
130        for effect_name in other.effects:130        for effect_name in other.effects:
n131            setattr(other,effect_name,other.already_used)n131            setattr(other, effect_name, other.already_used)
132        self.was_used=other.was_used=True132        self.was_used = other.was_used = True
133        return to_return133        return to_return
134134
135    def __truediv__(self, value):135    def __truediv__(self, value):
136        if self.is_depleted():136        if self.is_depleted():
137            raise TypeError("Potion is depleted.")137            raise TypeError("Potion is depleted.")
138        if self.was_used == True:138        if self.was_used == True:
139            raise TypeError("Potion is now part of something bigger than itself.")139            raise TypeError("Potion is now part of something bigger than itself.")
140        copy=Potion(self.effects,self.duration)140        copy=Potion(self.effects,self.duration)
141        for effect_name in self.intensity:141        for effect_name in self.intensity:
n142            copy.intensity[effect_name]=self.intensity[effect_name]n142            copy.intensity[effect_name] = self.intensity[effect_name]
143        for effect_name,effect in copy.effects.items():143        for effect_name,effect in copy.effects.items():
n144            copy.intensity[effect_name] //= valuen144            copy.intensity[effect_name] /= value
145            self.round_intensity(copy,effect_name)
146            #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if  copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])
145            setattr(copy,effect_name,calling_function_decorator(effect,copy.intensity[effect_name]))        147            setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))        
146        potion_list=[]148        potion_list=[]
147        for _ in range(value):149        for _ in range(value):
148            potion_list.append(copy)150            potion_list.append(copy)
149        for effect_name in self.effects:151        for effect_name in self.effects:
n150            setattr(self,effect_name,self.already_used)n152            setattr(self, effect_name, self.already_used)
151        self.was_used=True153        self.was_used = True
152        return tuple(potion_list)154        return tuple(potion_list)
n153 n155 
154        
155    def __bool__(self,other):156    def __bool__(self,other):
156157
157        for effect_name in self.effects:158        for effect_name in self.effects:
158            if effect_name not in other.effects:159            if effect_name not in other.effects:
159                return False160                return False
160        for effect_name in self.effect:161        for effect_name in self.effect:
161            if self.intensity[effect_name] != other.intensity[effect_name]:162            if self.intensity[effect_name] != other.intensity[effect_name]:
162                return False163                return False
163        return True164        return True
164    165    
165    def __gt__(self,other):166    def __gt__(self,other):
n166        sum_of_self=0n167        sum_of_self = 0
167        for effect_name in self.intensity:168        for effect_name in self.intensity:
168            sum_of_self+=self.intensity[effect_name]169            sum_of_self+=self.intensity[effect_name]
n169        sum_of_other=0n170        sum_of_other = 0
170        for effect_name in other.intensity:171        for effect_name in other.intensity:
n171            sum_of_other+=other.intensity[effect_name]n172            sum_of_other += other.intensity[effect_name]
172        return sum_of_self > sum_of_other173        return sum_of_self > sum_of_other
173174
174def sorting_potions(potion):175def sorting_potions(potion):
n175        name= potion[0]n176        name = potion[0]
176        sum_of_potion_name=0177        sum_of_potion_name = 0
177        for letter in name:178        for letter in name:
n178            sum_of_potion_name+=ord(letter)n179            sum_of_potion_name += ord(letter)
179        return sum_of_potion_name180        return sum_of_potion_name
nn181 
180182
181class ГоспожатаПоХимия:183class ГоспожатаПоХимия:
182    def __init__(self):184    def __init__(self):
n183        self.used_potions=[]n185        self.used_potions = []
184        self.targets_copies={}186        self.targets_copies = {}
185        self.targets_buffed_copies={}187        self.targets_buffed_copies = {}
186188
n187    def apply(self,target, potion):n189    def apply(self, target, potion):
188        if potion.is_depleted():190        if potion.is_depleted():
189            raise TypeError("Potion is depleted.")191            raise TypeError("Potion is depleted.")
n190        sorted_potions = sorted(potion.effects.items(),key=sorting_potions,reverse=True)n192        sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)
191        potion.effects=dict(sorted_potions)193        potion.effects = dict(sorted_potions)
192        if potion in self.used_potions:
193            raise TypeError("Potion is depleted.")
194        potion.was_used= True194        potion.was_used = True
195        if target not in self.targets_buffed_copies.values():
195        self.targets_copies[potion]=copy.copy(target)196            self.targets_copies[potion] = copy.copy(target)
197        else:
198            for potion_loop in self.used_potions:
199                if self.targets_buffed_copies[potion_loop] == target:
200                    self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])
201        self.used_potions.append(potion)
196        for effect_name in potion.effects:202        for effect_name in potion.effects:
n197            function=getattr(potion,effect_name)n203            function = getattr(potion, effect_name)
198            try:204            try:
199                function(target)205                function(target)
200            except TypeError:206            except TypeError:
201                continue207                continue
n202        self.targets_buffed_copies[potion]=targetn208        self.targets_buffed_copies[potion] = target
203        self.used_potions.append(potion)
204    209    
205    def tick(self):210    def tick(self):
206        for potion in self.used_potions:211        for potion in self.used_potions:
t207            potion.duration-=1t212            potion.duration -= 1
208            if potion.duration<=0:213            if potion.duration =0:
209                self.targets_buffed_copies[potion].__dict__=vars(self.targets_copies[potion])214                self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])
215                for potion_inner in self.used_potions:
216                    if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:
217                        continue
218                    copy = Potion(potion_inner.effects,potion_inner.duration)
219                    for effect_name,effect in  copy.effects.items():
220                         copy.intensity[effect_name] = potion_inner.intensity[effect_name]
221                         setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))
222                    for effect_name in  copy.effects:
223                        function = getattr(copy, effect_name)
224                        function(self.targets_buffed_copies[potion])
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op