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

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

4 точки общо

8 успешни теста
12 неуспешни теста
Код

  1import math
  2
  3
  4class Potion:
  5    def __init__(self, effects, duration):
  6        '''Тук effects_used съдържа имената на методите и интензитета на
  7        всеки метод. effects_applicable съдържа boolean стойности за всеки метод
  8        дали съответният метод е използваем. Накрая, used_in_reaction се използва,
  9        за да се следи дали поушънката е използвана в реакция(в това влиза да е 
 10        apply-вана) или не.'''
 11
 12        self.effects = dict(effects)
 13        self.duration = duration
 14        self._create_effect_methods()
 15        self.effects_used = {k: 1 for k in self.effects}
 16        self.effects_applicable = {k: True for k in self.effects}
 17        self.used_in_reaction = False
 18    
 19    def _create_effect_methods(self):
 20        for effect_name, effect_function in self.effects.items():
 21            setattr(self, effect_name, 
 22                    self._create_effect_wrapper(effect_name, effect_function))
 23
 24    def _create_effect_wrapper(self, effect_name, effect_func):
 25        def wrapper(target):
 26            if (all(value == False for value in 
 27                    self.effects_applicable.values())):
 28                raise TypeError('Potion is depleted')
 29            elif not self.effects_applicable[effect_name]:
 30                raise TypeError('Effect is depleted.')
 31            else:
 32                for intensity in range(self.effects_used[effect_name]):
 33                    effect_func(target)
 34                    self.effects_used[effect_name] -= 1 
 35                self.effects_applicable[effect_name] = False
 36        return wrapper
 37
 38    def __add__(self, other):
 39        if not ((all(value == False for value in self.effects_applicable.values()))
 40            or 
 41            (all(value == False for value in other.effects_applicable.values()))):
 42
 43            new_pot_effects = self.effects.copy()
 44            new_pot_effects_used = self.effects_used.copy()
 45            
 46            for effect_name, effect_function in other.effects.items():
 47                try:
 48                    new_pot_effects_used[effect_name] += other.effects_used[effect_name]
 49                except KeyError:
 50                    new_pot_effects[effect_name] = effect_function
 51                    new_pot_effects_used[effect_name] = other.effects_used[effect_name]
 52
 53            new_pot_durat = 0
 54            if self.duration >= other.duration:
 55                new_pot_durat = self.duration
 56            else:
 57                new_pot_durat = other.duration
 58            new_potion = Potion(new_pot_effects, new_pot_durat) 
 59            new_potion.effects_used = new_pot_effects_used
 60
 61            for k, v in self.effects.items():
 62                delattr(self, k)
 63            self.effects.clear()
 64            for k, v in other.effects.items():
 65                delattr(other, k)
 66            for k, v in self.effects_used.items():
 67                self.effects_used[k] = 0
 68            self.used_in_reaction = True
 69            other.used_in_reaction = True
 70
 71        else:
 72            raise TypeError('Potion is depleted.')
 73        return new_potion
 74
 75    def __mul__(self, num):
 76        if not all(value == False for value in self.effects_applicable.values()):
 77            new_potion = Potion(self.effects.copy(), self.duration)
 78            new_potion.effects_used = self.effects_used.copy()
 79            new_potion.effects_applicable = self.effects_applicable.copy()
 80            
 81            for k, v in new_potion.effects_used.items():
 82
 83                new_potion.effects_used[k] *= num
 84                shorter_length = new_potion.effects_used[k]
 85                if shorter_length <= math.floor(shorter_length) + 1.5:
 86                    new_potion.effects_used[k] = math.floor(shorter_length)
 87                else:
 88                    new_potion.effects_used[k] = math.ceil(shorter_length)
 89                
 90            for k, v in self.effects.items():
 91                delattr(self, k)
 92            for k, v in self.effects_used.items():
 93                self.effects_used[k] = 0
 94            self.used_in_reaction = True
 95            for k, v in self.effects_applicable.items():
 96                self.effects_applicable[k] = False
 97        else:
 98            raise TypeError('Potion is depleted.')
 99        
100
101        return new_potion
102    
103    def __sub__(self, other):
104        if not ((all(value == False for value in self.effects_applicable.values())) 
105            or 
106            (all(value == False for value in other.effects_applicable.values()))):
107
108            new_potion = Potion(self.effects.copy(), self.duration)
109            new_potion.effects_used = self.effects_used.copy()
110            
111            self.used_in_reaction = True
112            other.used_in_reaction = True
113
114            for k, v in other.effects.items():
115                if k not in self.effects:
116                    raise TypeError('ne izdyrjam poveche na tozi jivot')
117                else:
118                    intens = new_potion.effects_used[k] - other.effects_used[k]
119                    if intens <= 0:
120                        new_potion.effects.pop(k)
121                        delattr(new_potion, k)
122                        new_potion.effects_used.pop(k)
123                    else:
124                        new_potion.effects_used[k] -= intens
125
126            for k, v in self.effects.items():
127                delattr(self, k)
128            self.effects.clear()
129            for k, v in self.effects_used.items():
130                self.effects_used[k] = 0
131            
132            for k, v in other.effects.items():
133                delattr(other, k)
134            other.effects.clear()
135            other.effects_used.clear()
136        else:
137            raise TypeError('Potion is depleted.')
138
139        return new_potion
140    
141    def __truediv__(self, number):
142        if not all(value == False for value in self.effects_applicable.values()):
143            divided_potions = []
144
145            new_pot = Potion(self.effects.copy(), self.duration)
146            new_pot.effects_used = self.effects_used.copy()
147            self.used_in_reaction = True
148
149            for k, v in new_pot.effects_used.items():
150                new_pot.effects_used[k] /= number
151                shorter_length = new_pot.effects_used[k]
152                if shorter_length <= math.floor(shorter_length) + 0.5:
153                    new_pot.effects_used[k] = math.floor(shorter_length)
154                else:
155                    new_pot.effects_used[k] = math.ceil(shorter_length)
156            
157            for _ in range(number):
158                divided_potions.append(new_pot)
159            
160            for k, v in self.effects.items():
161                delattr(self, k)
162            self.effects.clear()
163            self.effects_used.clear()
164            for k, v in self.effects_applicable.items():
165                self.effects_applicable[k] = False
166        else:
167            raise TypeError('Potion is depleted.')
168        
169        return tuple(divided_potions)
170    
171    def __getattr__(self, attr):
172        if self.used_in_reaction:
173            raise TypeError('Potion is now part of something bigger than itself.')
174    
175    def __eq__(self, other):
176        sum_self_intens = 0
177        sum_other_intens = 0
178
179        for k, v in self.effects_used.items():
180            if k not in other.effects_used:
181                return False
182            sum_self_intens += self.effects_used[k]
183            sum_other_intens += other.effects_used[k]
184            if sum_self_intens != sum_other_intens:
185                return False
186        return True
187
188    def __lt__(self, other):
189        sum_self_intens = 0
190        sum_other_intens = 0
191        for k, v in self.effects_used.items():
192            sum_self_intens += self.effects_used[k]
193            sum_other_intens += other.effects_used[k]
194        return sum_self_intens < sum_other_intens    
195
196    def __gt__(self, other):
197        sum_self_intens = 0
198        sum_other_intens = 0
199        for k, v in self.effects_used.items():
200            sum_self_intens += self.effects_used[k]
201            sum_other_intens += other.effects_used[k]
202        return sum_self_intens > sum_other_intens
203
204
205class ГоспожатаПоХимия:
206
207    def __init__(self):
208        self.is_pot_depleted = False
209        self.pot_duration = 0
210        self.target_dic = {}
211        self.object = None
212        self.objects = []
213
214    def apply(self, target, potion):
215        if potion not in self.objects:
216            self.target_dic = target.__dict__.copy()
217            new_dict = {}
218            for k, v in potion.effects.items():
219                ascii_sum = sum(ord(char) for char in k)
220                new_dict[ascii_sum] = v
221            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))
222            for k, v in sorted_effects.items():
223                v(target)
224                
225            for k, v in potion.effects_applicable.items():
226                potion.effects_applicable[k] = False
227
228            self.is_pot_depleted = True
229            self.pot_duration = potion.duration
230            self.object = target
231            self.objects.append(potion)
232            potion.used_in_reaction = True
233
234        else:
235            raise TypeError('Potion is depleted.')
236
237    def tick(self):
238        if self.is_pot_depleted:
239            self.pot_duration -= 1
240            if self.pot_duration == 0:
241                self.object.__dict__ = self.target_dic

.F.FE...F.EEF..FFEFF
======================================================================
ERROR: test_superbness (test.TestPotionComparison)
Test superbness of potions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 323, in test_superbness
self.assertLess(potion1, potion2)
File "/usr/lib/python3.10/unittest/case.py", line 1230, in assertLess
if not a < b:
File "/tmp/solution.py", line 193, in __lt__
sum_other_intens += other.effects_used[k]
KeyError: 'int_attr_fun'

======================================================================
ERROR: test_purification (test.TestPotionOperations)
Test purification of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 169, in test_purification
potion.int_attr_fun(self._target)
TypeError: 'NoneType' object is not callable

======================================================================
ERROR: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 218, in test_separation
potion2.int_attr_fun(self._target)
File "/tmp/solution.py", line 28, in wrapper
raise TypeError('Potion is depleted')
TypeError: Potion is depleted

======================================================================
ERROR: 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 455, in test_ticking_multiple_potions
self._dimitrichka.apply(self._target, potion2)
File "/tmp/solution.py", line 235, in apply
raise TypeError('Potion is depleted.')
TypeError: Potion is depleted.

======================================================================
FAIL: test_depletion (test.TestBasicPotion)
Test depletion of a potion effect.
----------------------------------------------------------------------
TypeError: Potion is depleted

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/tmp/test.py", line 78, in test_depletion
with self.assertRaisesRegex(TypeError, 'Effect is depleted\.'):
AssertionError: "Effect is depleted\." does not match "Potion is depleted"

======================================================================
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 0x7fd30c1ee260> == <solution.Potion object at 0x7fd30c1ecaf0>

======================================================================
FAIL: test_dilution (test.TestPotionOperations)
Test dilution of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 127, in test_dilution
self.assertEqual(self._target.int_attr, 50)
AssertionError: 5 != 50

======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 391, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
AssertionError: TypeError not raised

======================================================================
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_immutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with immutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 425, in test_ticking_immutable
self.assertEqual(self._target.int_attr, 500)
AssertionError: 50 != 500

======================================================================
FAIL: test_ticking_multiple_targets (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 487, in test_ticking_multiple_targets
self.assertEqual(target1.int_attr, 500)
AssertionError: 50 != 500

======================================================================
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=8, errors=4)

Дискусия
Георги Кунчев
05.12.2023 16:50

1 - не е нужно, но го следвай за следващ код; 2 - трябва двяка двойка ефекти да е с равен интензитет. Ако сумата от интензитетите е равна, но разпределена различно, трябва да връщащ `False`
Стелиан Витанов
05.12.2023 16:15

Имам два въпроса: 1) Имам няколко реда, които надвишават допустимия лимит. Трябва ли да ги оправя? 2) Когато сравняваме две отвари дали са '==', пише, че са такива, ако съдържат едни и същи ефекти с един и същ интензитет. Това значи ли, че ще е True, ако в две отвари сборът на всички интензитети е равен, както и самите ефекти са еднакви, но интензитетите са разпределени по различен начин между ефектите?
История

f1import mathf1import math
22
33
4class Potion:4class Potion:
5    def __init__(self, effects, duration):5    def __init__(self, effects, duration):
6        '''Тук effects_used съдържа имената на методите и интензитета на6        '''Тук effects_used съдържа имената на методите и интензитета на
7        всеки метод. effects_applicable съдържа boolean стойности за всеки метод7        всеки метод. effects_applicable съдържа boolean стойности за всеки метод
8        дали съответният метод е използваем. Накрая, used_in_reaction се използва,8        дали съответният метод е използваем. Накрая, used_in_reaction се използва,
9        за да се следи дали поушънката е използвана в реакция(в това влиза да е 9        за да се следи дали поушънката е използвана в реакция(в това влиза да е 
10        apply-вана) или не.'''10        apply-вана) или не.'''
1111
12        self.effects = dict(effects)12        self.effects = dict(effects)
13        self.duration = duration13        self.duration = duration
14        self._create_effect_methods()14        self._create_effect_methods()
15        self.effects_used = {k: 1 for k in self.effects}15        self.effects_used = {k: 1 for k in self.effects}
16        self.effects_applicable = {k: True for k in self.effects}16        self.effects_applicable = {k: True for k in self.effects}
17        self.used_in_reaction = False17        self.used_in_reaction = False
18    18    
19    def _create_effect_methods(self):19    def _create_effect_methods(self):
20        for effect_name, effect_function in self.effects.items():20        for effect_name, effect_function in self.effects.items():
21            setattr(self, effect_name, 21            setattr(self, effect_name, 
22                    self._create_effect_wrapper(effect_name, effect_function))22                    self._create_effect_wrapper(effect_name, effect_function))
2323
24    def _create_effect_wrapper(self, effect_name, effect_func):24    def _create_effect_wrapper(self, effect_name, effect_func):
25        def wrapper(target):25        def wrapper(target):
26            if (all(value == False for value in 26            if (all(value == False for value in 
27                    self.effects_applicable.values())):27                    self.effects_applicable.values())):
28                raise TypeError('Potion is depleted')28                raise TypeError('Potion is depleted')
29            elif not self.effects_applicable[effect_name]:29            elif not self.effects_applicable[effect_name]:
30                raise TypeError('Effect is depleted.')30                raise TypeError('Effect is depleted.')
31            else:31            else:
32                for intensity in range(self.effects_used[effect_name]):32                for intensity in range(self.effects_used[effect_name]):
33                    effect_func(target)33                    effect_func(target)
n34                    self.effects_used[effect_name] -= 1n34                    self.effects_used[effect_name] -= 1 
35                self.effects_applicable[effect_name] = False35                self.effects_applicable[effect_name] = False
36        return wrapper36        return wrapper
3737
38    def __add__(self, other):38    def __add__(self, other):
39        if not ((all(value == False for value in self.effects_applicable.values()))39        if not ((all(value == False for value in self.effects_applicable.values()))
40            or 40            or 
41            (all(value == False for value in other.effects_applicable.values()))):41            (all(value == False for value in other.effects_applicable.values()))):
4242
43            new_pot_effects = self.effects.copy()43            new_pot_effects = self.effects.copy()
44            new_pot_effects_used = self.effects_used.copy()44            new_pot_effects_used = self.effects_used.copy()
45            45            
46            for effect_name, effect_function in other.effects.items():46            for effect_name, effect_function in other.effects.items():
47                try:47                try:
48                    new_pot_effects_used[effect_name] += other.effects_used[effect_name]48                    new_pot_effects_used[effect_name] += other.effects_used[effect_name]
49                except KeyError:49                except KeyError:
50                    new_pot_effects[effect_name] = effect_function50                    new_pot_effects[effect_name] = effect_function
51                    new_pot_effects_used[effect_name] = other.effects_used[effect_name]51                    new_pot_effects_used[effect_name] = other.effects_used[effect_name]
5252
53            new_pot_durat = 053            new_pot_durat = 0
54            if self.duration >= other.duration:54            if self.duration >= other.duration:
55                new_pot_durat = self.duration55                new_pot_durat = self.duration
56            else:56            else:
57                new_pot_durat = other.duration57                new_pot_durat = other.duration
58            new_potion = Potion(new_pot_effects, new_pot_durat) 58            new_potion = Potion(new_pot_effects, new_pot_durat) 
59            new_potion.effects_used = new_pot_effects_used59            new_potion.effects_used = new_pot_effects_used
6060
61            for k, v in self.effects.items():61            for k, v in self.effects.items():
62                delattr(self, k)62                delattr(self, k)
63            self.effects.clear()63            self.effects.clear()
64            for k, v in other.effects.items():64            for k, v in other.effects.items():
65                delattr(other, k)65                delattr(other, k)
66            for k, v in self.effects_used.items():66            for k, v in self.effects_used.items():
67                self.effects_used[k] = 067                self.effects_used[k] = 0
68            self.used_in_reaction = True68            self.used_in_reaction = True
69            other.used_in_reaction = True69            other.used_in_reaction = True
7070
71        else:71        else:
72            raise TypeError('Potion is depleted.')72            raise TypeError('Potion is depleted.')
73        return new_potion73        return new_potion
7474
75    def __mul__(self, num):75    def __mul__(self, num):
76        if not all(value == False for value in self.effects_applicable.values()):76        if not all(value == False for value in self.effects_applicable.values()):
77            new_potion = Potion(self.effects.copy(), self.duration)77            new_potion = Potion(self.effects.copy(), self.duration)
78            new_potion.effects_used = self.effects_used.copy()78            new_potion.effects_used = self.effects_used.copy()
79            new_potion.effects_applicable = self.effects_applicable.copy()79            new_potion.effects_applicable = self.effects_applicable.copy()
80            80            
81            for k, v in new_potion.effects_used.items():81            for k, v in new_potion.effects_used.items():
8282
83                new_potion.effects_used[k] *= num83                new_potion.effects_used[k] *= num
84                shorter_length = new_potion.effects_used[k]84                shorter_length = new_potion.effects_used[k]
85                if shorter_length <= math.floor(shorter_length) + 1.5:85                if shorter_length <= math.floor(shorter_length) + 1.5:
86                    new_potion.effects_used[k] = math.floor(shorter_length)86                    new_potion.effects_used[k] = math.floor(shorter_length)
87                else:87                else:
88                    new_potion.effects_used[k] = math.ceil(shorter_length)88                    new_potion.effects_used[k] = math.ceil(shorter_length)
89                89                
90            for k, v in self.effects.items():90            for k, v in self.effects.items():
91                delattr(self, k)91                delattr(self, k)
92            for k, v in self.effects_used.items():92            for k, v in self.effects_used.items():
93                self.effects_used[k] = 093                self.effects_used[k] = 0
94            self.used_in_reaction = True94            self.used_in_reaction = True
95            for k, v in self.effects_applicable.items():95            for k, v in self.effects_applicable.items():
96                self.effects_applicable[k] = False96                self.effects_applicable[k] = False
97        else:97        else:
98            raise TypeError('Potion is depleted.')98            raise TypeError('Potion is depleted.')
99        99        
100100
101        return new_potion101        return new_potion
102    102    
103    def __sub__(self, other):103    def __sub__(self, other):
104        if not ((all(value == False for value in self.effects_applicable.values())) 104        if not ((all(value == False for value in self.effects_applicable.values())) 
105            or 105            or 
106            (all(value == False for value in other.effects_applicable.values()))):106            (all(value == False for value in other.effects_applicable.values()))):
107107
108            new_potion = Potion(self.effects.copy(), self.duration)108            new_potion = Potion(self.effects.copy(), self.duration)
109            new_potion.effects_used = self.effects_used.copy()109            new_potion.effects_used = self.effects_used.copy()
110            110            
111            self.used_in_reaction = True111            self.used_in_reaction = True
112            other.used_in_reaction = True112            other.used_in_reaction = True
113113
114            for k, v in other.effects.items():114            for k, v in other.effects.items():
115                if k not in self.effects:115                if k not in self.effects:
116                    raise TypeError('ne izdyrjam poveche na tozi jivot')116                    raise TypeError('ne izdyrjam poveche na tozi jivot')
117                else:117                else:
118                    intens = new_potion.effects_used[k] - other.effects_used[k]118                    intens = new_potion.effects_used[k] - other.effects_used[k]
119                    if intens <= 0:119                    if intens <= 0:
120                        new_potion.effects.pop(k)120                        new_potion.effects.pop(k)
121                        delattr(new_potion, k)121                        delattr(new_potion, k)
122                        new_potion.effects_used.pop(k)122                        new_potion.effects_used.pop(k)
123                    else:123                    else:
124                        new_potion.effects_used[k] -= intens124                        new_potion.effects_used[k] -= intens
125125
126            for k, v in self.effects.items():126            for k, v in self.effects.items():
127                delattr(self, k)127                delattr(self, k)
128            self.effects.clear()128            self.effects.clear()
129            for k, v in self.effects_used.items():129            for k, v in self.effects_used.items():
130                self.effects_used[k] = 0130                self.effects_used[k] = 0
131            131            
132            for k, v in other.effects.items():132            for k, v in other.effects.items():
133                delattr(other, k)133                delattr(other, k)
134            other.effects.clear()134            other.effects.clear()
135            other.effects_used.clear()135            other.effects_used.clear()
136        else:136        else:
137            raise TypeError('Potion is depleted.')137            raise TypeError('Potion is depleted.')
138138
139        return new_potion139        return new_potion
140    140    
141    def __truediv__(self, number):141    def __truediv__(self, number):
142        if not all(value == False for value in self.effects_applicable.values()):142        if not all(value == False for value in self.effects_applicable.values()):
143            divided_potions = []143            divided_potions = []
144144
145            new_pot = Potion(self.effects.copy(), self.duration)145            new_pot = Potion(self.effects.copy(), self.duration)
146            new_pot.effects_used = self.effects_used.copy()146            new_pot.effects_used = self.effects_used.copy()
147            self.used_in_reaction = True147            self.used_in_reaction = True
148148
149            for k, v in new_pot.effects_used.items():149            for k, v in new_pot.effects_used.items():
150                new_pot.effects_used[k] /= number150                new_pot.effects_used[k] /= number
151                shorter_length = new_pot.effects_used[k]151                shorter_length = new_pot.effects_used[k]
152                if shorter_length <= math.floor(shorter_length) + 0.5:152                if shorter_length <= math.floor(shorter_length) + 0.5:
153                    new_pot.effects_used[k] = math.floor(shorter_length)153                    new_pot.effects_used[k] = math.floor(shorter_length)
154                else:154                else:
155                    new_pot.effects_used[k] = math.ceil(shorter_length)155                    new_pot.effects_used[k] = math.ceil(shorter_length)
156            156            
157            for _ in range(number):157            for _ in range(number):
158                divided_potions.append(new_pot)158                divided_potions.append(new_pot)
159            159            
160            for k, v in self.effects.items():160            for k, v in self.effects.items():
161                delattr(self, k)161                delattr(self, k)
162            self.effects.clear()162            self.effects.clear()
163            self.effects_used.clear()163            self.effects_used.clear()
164            for k, v in self.effects_applicable.items():164            for k, v in self.effects_applicable.items():
165                self.effects_applicable[k] = False165                self.effects_applicable[k] = False
166        else:166        else:
167            raise TypeError('Potion is depleted.')167            raise TypeError('Potion is depleted.')
168        168        
169        return tuple(divided_potions)169        return tuple(divided_potions)
170    170    
171    def __getattr__(self, attr):171    def __getattr__(self, attr):
172        if self.used_in_reaction:172        if self.used_in_reaction:
173            raise TypeError('Potion is now part of something bigger than itself.')173            raise TypeError('Potion is now part of something bigger than itself.')
174    174    
175    def __eq__(self, other):175    def __eq__(self, other):
176        sum_self_intens = 0176        sum_self_intens = 0
177        sum_other_intens = 0177        sum_other_intens = 0
178178
179        for k, v in self.effects_used.items():179        for k, v in self.effects_used.items():
180            if k not in other.effects_used:180            if k not in other.effects_used:
181                return False181                return False
182            sum_self_intens += self.effects_used[k]182            sum_self_intens += self.effects_used[k]
183            sum_other_intens += other.effects_used[k]183            sum_other_intens += other.effects_used[k]
t184        t
185        return sum_self_intens == sum_other_intens184            if sum_self_intens != sum_other_intens:
185                return False
186        return True
186187
187    def __lt__(self, other):188    def __lt__(self, other):
188        sum_self_intens = 0189        sum_self_intens = 0
189        sum_other_intens = 0190        sum_other_intens = 0
190        for k, v in self.effects_used.items():191        for k, v in self.effects_used.items():
191            sum_self_intens += self.effects_used[k]192            sum_self_intens += self.effects_used[k]
192            sum_other_intens += other.effects_used[k]193            sum_other_intens += other.effects_used[k]
193        return sum_self_intens < sum_other_intens    194        return sum_self_intens < sum_other_intens    
194195
195    def __gt__(self, other):196    def __gt__(self, other):
196        sum_self_intens = 0197        sum_self_intens = 0
197        sum_other_intens = 0198        sum_other_intens = 0
198        for k, v in self.effects_used.items():199        for k, v in self.effects_used.items():
199            sum_self_intens += self.effects_used[k]200            sum_self_intens += self.effects_used[k]
200            sum_other_intens += other.effects_used[k]201            sum_other_intens += other.effects_used[k]
201        return sum_self_intens > sum_other_intens202        return sum_self_intens > sum_other_intens
202203
203204
204class ГоспожатаПоХимия:205class ГоспожатаПоХимия:
205206
206    def __init__(self):207    def __init__(self):
207        self.is_pot_depleted = False208        self.is_pot_depleted = False
208        self.pot_duration = 0209        self.pot_duration = 0
209        self.target_dic = {}210        self.target_dic = {}
210        self.object = None211        self.object = None
211        self.objects = []212        self.objects = []
212213
213    def apply(self, target, potion):214    def apply(self, target, potion):
214        if potion not in self.objects:215        if potion not in self.objects:
215            self.target_dic = target.__dict__.copy()216            self.target_dic = target.__dict__.copy()
216            new_dict = {}217            new_dict = {}
217            for k, v in potion.effects.items():218            for k, v in potion.effects.items():
218                ascii_sum = sum(ord(char) for char in k)219                ascii_sum = sum(ord(char) for char in k)
219                new_dict[ascii_sum] = v220                new_dict[ascii_sum] = v
220            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))221            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))
221            for k, v in sorted_effects.items():222            for k, v in sorted_effects.items():
222                v(target)223                v(target)
223                224                
224            for k, v in potion.effects_applicable.items():225            for k, v in potion.effects_applicable.items():
225                potion.effects_applicable[k] = False226                potion.effects_applicable[k] = False
226227
227            self.is_pot_depleted = True228            self.is_pot_depleted = True
228            self.pot_duration = potion.duration229            self.pot_duration = potion.duration
229            self.object = target230            self.object = target
230            self.objects.append(potion)231            self.objects.append(potion)
231            potion.used_in_reaction = True232            potion.used_in_reaction = True
232233
233        else:234        else:
234            raise TypeError('Potion is depleted.')235            raise TypeError('Potion is depleted.')
235236
236    def tick(self):237    def tick(self):
237        if self.is_pot_depleted:238        if self.is_pot_depleted:
238            self.pot_duration -= 1239            self.pot_duration -= 1
239            if self.pot_duration == 0:240            if self.pot_duration == 0:
240                self.object.__dict__ = self.target_dic241                self.object.__dict__ = self.target_dic
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
22
33
4class Potion:4class Potion:
5    def __init__(self, effects, duration):5    def __init__(self, effects, duration):
nn6        '''Тук effects_used съдържа имената на методите и интензитета на
7        всеки метод. effects_applicable съдържа boolean стойности за всеки метод
8        дали съответният метод е използваем. Накрая, used_in_reaction се използва,
9        за да се следи дали поушънката е използвана в реакция(в това влиза да е 
10        apply-вана) или не.'''
11 
6        self.effects = dict(effects)12        self.effects = dict(effects)
7        self.duration = duration13        self.duration = duration
8        self._create_effect_methods()14        self._create_effect_methods()
n9        self.effects_used = {k:2 for k in self.effects}n15        self.effects_used = {k: 1 for k in self.effects}
10        self.effects_applicable = {k:True for k in self.effects}16        self.effects_applicable = {k: True for k in self.effects}
11        self.used_in_reaction = False17        self.used_in_reaction = False
12    18    
13    def _create_effect_methods(self):19    def _create_effect_methods(self):
14        for effect_name, effect_function in self.effects.items():20        for effect_name, effect_function in self.effects.items():
15            setattr(self, effect_name, 21            setattr(self, effect_name, 
16                    self._create_effect_wrapper(effect_name, effect_function))22                    self._create_effect_wrapper(effect_name, effect_function))
1723
18    def _create_effect_wrapper(self, effect_name, effect_func):24    def _create_effect_wrapper(self, effect_name, effect_func):
19        def wrapper(target):25        def wrapper(target):
20            if (all(value == False for value in 26            if (all(value == False for value in 
21                    self.effects_applicable.values())):27                    self.effects_applicable.values())):
22                raise TypeError('Potion is depleted')28                raise TypeError('Potion is depleted')
23            elif not self.effects_applicable[effect_name]:29            elif not self.effects_applicable[effect_name]:
24                raise TypeError('Effect is depleted.')30                raise TypeError('Effect is depleted.')
25            else:31            else:
26                for intensity in range(self.effects_used[effect_name]):32                for intensity in range(self.effects_used[effect_name]):
27                    effect_func(target)33                    effect_func(target)
n28                    self.effects_used[effect_name] -= 2n34                    self.effects_used[effect_name] -= 1
29                self.effects_applicable[effect_name] = False35                self.effects_applicable[effect_name] = False
30        return wrapper36        return wrapper
3137
32    def __add__(self, other):38    def __add__(self, other):
n33        if not self.used_in_reaction and not other.used_in_reaction:n39        if not ((all(value == False for value in self.effects_applicable.values()))
40            or 
41            (all(value == False for value in other.effects_applicable.values()))):
42 
34            new_pot_effects = self.effects.copy()43            new_pot_effects = self.effects.copy()
35            new_pot_effects_used = self.effects_used.copy()44            new_pot_effects_used = self.effects_used.copy()
n36            self.used_in_reaction = Truen45            
37            other.used_in_reaction = True
38            for effect_name, effect_function in other.effects.items():46            for effect_name, effect_function in other.effects.items():
39                try:47                try:
n40                    new_pot_effects_used[effect_name] += 2n48                    new_pot_effects_used[effect_name] += other.effects_used[effect_name]
41                except KeyError:49                except KeyError:
42                    new_pot_effects[effect_name] = effect_function50                    new_pot_effects[effect_name] = effect_function
nn51                    new_pot_effects_used[effect_name] = other.effects_used[effect_name]
52 
43            new_pot_durat = 153            new_pot_durat = 0
44            if self.duration >= other.duration:54            if self.duration >= other.duration:
45                new_pot_durat = self.duration55                new_pot_durat = self.duration
46            else:56            else:
47                new_pot_durat = other.duration57                new_pot_durat = other.duration
48            new_potion = Potion(new_pot_effects, new_pot_durat) 58            new_potion = Potion(new_pot_effects, new_pot_durat) 
49            new_potion.effects_used = new_pot_effects_used59            new_potion.effects_used = new_pot_effects_used
5060
51            for k, v in self.effects.items():61            for k, v in self.effects.items():
52                delattr(self, k)62                delattr(self, k)
53            self.effects.clear()63            self.effects.clear()
nn64            for k, v in other.effects.items():
65                delattr(other, k)
54            for k, v in self.effects_used.items():66            for k, v in self.effects_used.items():
n55                self.effects_used[k] = 1n67                self.effects_used[k] = 0
68            self.used_in_reaction = True
69            other.used_in_reaction = True
70 
56        else:71        else:
57            raise TypeError('Potion is depleted.')72            raise TypeError('Potion is depleted.')
58        return new_potion73        return new_potion
5974
60    def __mul__(self, num):75    def __mul__(self, num):
n61        if not self.used_in_reaction:n76        if not all(value == False for value in self.effects_applicable.values()):
62            new_potion = Potion(self.effects.copy(), self.duration)77            new_potion = Potion(self.effects.copy(), self.duration)
63            new_potion.effects_used = self.effects_used.copy()78            new_potion.effects_used = self.effects_used.copy()
64            new_potion.effects_applicable = self.effects_applicable.copy()79            new_potion.effects_applicable = self.effects_applicable.copy()
n65            self.used_in_reaction = Truen80            
66            for k, v in self.effects_applicable.items():
67                self.effects_applicable[k] = False
68 
69            for k, v in new_potion.effects_used.items():81            for k, v in new_potion.effects_used.items():
7082
71                new_potion.effects_used[k] *= num83                new_potion.effects_used[k] *= num
72                shorter_length = new_potion.effects_used[k]84                shorter_length = new_potion.effects_used[k]
73                if shorter_length <= math.floor(shorter_length) + 1.5:85                if shorter_length <= math.floor(shorter_length) + 1.5:
74                    new_potion.effects_used[k] = math.floor(shorter_length)86                    new_potion.effects_used[k] = math.floor(shorter_length)
75                else:87                else:
76                    new_potion.effects_used[k] = math.ceil(shorter_length)88                    new_potion.effects_used[k] = math.ceil(shorter_length)
77                89                
n78    n
79            # for k, v in self.effects.items():90            for k, v in self.effects.items():
80            #     delattr(self, k)91                delattr(self, k)
81 
82            for k, v in self.effects_used.items():92            for k, v in self.effects_used.items():
n83                self.effects_used[k] = 1n93                self.effects_used[k] = 0
94            self.used_in_reaction = True
95            for k, v in self.effects_applicable.items():
96                self.effects_applicable[k] = False
84        else:97        else:
n85            raise TypeError('Potion is now part of something bigger.')n98            raise TypeError('Potion is depleted.')
86        99        
87100
88        return new_potion101        return new_potion
89    102    
90    def __sub__(self, other):103    def __sub__(self, other):
nn104        if not ((all(value == False for value in self.effects_applicable.values())) 
105            or 
106            (all(value == False for value in other.effects_applicable.values()))):
107 
91        new_potion = Potion(self.effects.copy(), self.duration)108            new_potion = Potion(self.effects.copy(), self.duration)
92        new_potion.effects_used = self.effects_used.copy()109            new_potion.effects_used = self.effects_used.copy()
110            
111            self.used_in_reaction = True
112            other.used_in_reaction = True
113 
114            for k, v in other.effects.items():
115                if k not in self.effects:
116                    raise TypeError('ne izdyrjam poveche na tozi jivot')
117                else:
118                    intens = new_potion.effects_used[k] - other.effects_used[k]
119                    if intens <= 0:
120                        new_potion.effects.pop(k)
121                        delattr(new_potion, k)
122                        new_potion.effects_used.pop(k)
123                    else:
124                        new_potion.effects_used[k] -= intens
125 
126            for k, v in self.effects.items():
127                delattr(self, k)
128            self.effects.clear()
129            for k, v in self.effects_used.items():
130                self.effects_used[k] = 0
131            
132            for k, v in other.effects.items():
133                delattr(other, k)
134            other.effects.clear()
135            other.effects_used.clear()
136        else:
137            raise TypeError('Potion is depleted.')
138 
139        return new_potion
140    
141    def __truediv__(self, number):
142        if not all(value == False for value in self.effects_applicable.values()):
143            divided_potions = []
144 
145            new_pot = Potion(self.effects.copy(), self.duration)
146            new_pot.effects_used = self.effects_used.copy()
147            self.used_in_reaction = True
148 
149            for k, v in new_pot.effects_used.items():
150                new_pot.effects_used[k] /= number
151                shorter_length = new_pot.effects_used[k]
152                if shorter_length <= math.floor(shorter_length) + 0.5:
153                    new_pot.effects_used[k] = math.floor(shorter_length)
154                else:
155                    new_pot.effects_used[k] = math.ceil(shorter_length)
156            
157            for _ in range(number):
158                divided_potions.append(new_pot)
159            
160            for k, v in self.effects.items():
161                delattr(self, k)
162            self.effects.clear()
163            self.effects_used.clear()
164            for k, v in self.effects_applicable.items():
165                self.effects_applicable[k] = False
166        else:
167            raise TypeError('Potion is depleted.')
93        168        
n94        self.used_in_reaction = Truen
95        other.used_in_reaction = True
96 
97        for k, v in other.effects.items():
98            if k not in self.effects:
99                raise TypeError('ne izdyrjam poveche na tozi jivot')
100            else:
101                intens = new_potion.effects_used[k] - other.effects_used[k]
102                if intens < 1:
103                    new_potion.effects.pop(k)
104                    delattr(new_potion, new_potion.k)
105                    new_potion.effects_used.pop(k)
106                else:
107                    new_potion.effects_used[k] -= intens
108 
109        for k, v in self.effects.items():
110            delattr(self, k)
111        self.effects.clear()
112        for k, v in self.effects_used.items():
113            self.effects_used[k] = 1
114        
115        for k, v in other.effects.items():
116            delattr(other, k)
117        other.effects.clear()
118        other.effects_used.clear()
119 
120        return new_potion
121    
122    def __truediv__(self, number):
123        divided_potions = []
124 
125        new_pot = Potion(self.effects.copy(), self.duration)
126        new_pot.effects_used = self.effects_used.copy()
127        self.used_in_reaction = True
128 
129        for k, v in new_pot.effects_used.items():
130            new_pot.effects_used[k] /= number
131            shorter_length = new_pot.effects_used[k]
132            if shorter_length <= math.floor(shorter_length) + 0.5:
133                new_pot.effects_used[k] = math.floor(shorter_length)
134            else:
135                new_pot.effects_used[k] = math.ceil(shorter_length)
136        
137        for _ in range(number):
138            divided_potions.append(new_pot)
139        
140        for k, v in self.effects.items():
141            delattr(self, k)
142        self.effects.clear()
143        self.effects_used.clear()
144        
145        return divided_potions169        return tuple(divided_potions)
146    170    
147    def __getattr__(self, attr):171    def __getattr__(self, attr):
148        if self.used_in_reaction:172        if self.used_in_reaction:
n149            raise TypeError(n
150                'Potion is now part of something bigger than itself.'173            raise TypeError('Potion is now part of something bigger than itself.')
151                )
152    174    
153    def __eq__(self, other):175    def __eq__(self, other):
154        sum_self_intens = 0176        sum_self_intens = 0
155        sum_other_intens = 0177        sum_other_intens = 0
156178
157        for k, v in self.effects_used.items():179        for k, v in self.effects_used.items():
158            if k not in other.effects_used:180            if k not in other.effects_used:
159                return False181                return False
160            sum_self_intens += self.effects_used[k]182            sum_self_intens += self.effects_used[k]
161            sum_other_intens += other.effects_used[k]183            sum_other_intens += other.effects_used[k]
162        184        
n163        if sum_self_intens == sum_other_intens:n185        return sum_self_intens == sum_other_intens
164            return True
165        return False
166186
167    def __lt__(self, other):187    def __lt__(self, other):
168        sum_self_intens = 0188        sum_self_intens = 0
169        sum_other_intens = 0189        sum_other_intens = 0
170        for k, v in self.effects_used.items():190        for k, v in self.effects_used.items():
171            sum_self_intens += self.effects_used[k]191            sum_self_intens += self.effects_used[k]
172            sum_other_intens += other.effects_used[k]192            sum_other_intens += other.effects_used[k]
n173        if sum_self_intens < sum_other_intens:n193        return sum_self_intens < sum_other_intens    
174            return True194 
175        else:
176            return False
177    
178    def __gt__(self, other):195    def __gt__(self, other):
179        sum_self_intens = 0196        sum_self_intens = 0
180        sum_other_intens = 0197        sum_other_intens = 0
181        for k, v in self.effects_used.items():198        for k, v in self.effects_used.items():
182            sum_self_intens += self.effects_used[k]199            sum_self_intens += self.effects_used[k]
183            sum_other_intens += other.effects_used[k]200            sum_other_intens += other.effects_used[k]
n184        if sum_self_intens > sum_other_intens:n201        return sum_self_intens > sum_other_intens
185            return True
186        else:
187            return False
188202
189203
190class ГоспожатаПоХимия:204class ГоспожатаПоХимия:
191205
nn206    def __init__(self):
192    is_pot_depleted = False207        self.is_pot_depleted = False
193    pot_duration = 0208        self.pot_duration = 0
194    target_dic = {}209        self.target_dic = {}
195    object = None210        self.object = None
196    objects = []211        self.objects = []
197212
198    def apply(self, target, potion):213    def apply(self, target, potion):
n199        if potion not in ГоспожатаПоХимия.objects:n214        if potion not in self.objects:
200            ГоспожатаПоХимия.target_dic = target.__dict__.copy()215            self.target_dic = target.__dict__.copy()
201            new_dict = {}216            new_dict = {}
202            for k, v in potion.effects.items():217            for k, v in potion.effects.items():
203                ascii_sum = sum(ord(char) for char in k)218                ascii_sum = sum(ord(char) for char in k)
204                new_dict[ascii_sum] = v219                new_dict[ascii_sum] = v
205            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))220            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))
206            for k, v in sorted_effects.items():221            for k, v in sorted_effects.items():
207                v(target)222                v(target)
nn223                
224            for k, v in potion.effects_applicable.items():
208                potion.effects_applicable[k] = False225                potion.effects_applicable[k] = False
nn226 
209            ГоспожатаПоХимия.is_pot_depleted = True227            self.is_pot_depleted = True
210            ГоспожатаПоХимия.pot_duration = potion.duration228            self.pot_duration = potion.duration
211            ГоспожатаПоХимия.object = target229            self.object = target
212            ГоспожатаПоХимия.objects.append(potion)230            self.objects.append(potion)
213            potion.used_in_reaction = True231            potion.used_in_reaction = True
214232
215        else:233        else:
216            raise TypeError('Potion is depleted.')234            raise TypeError('Potion is depleted.')
217235
218    def tick(self):236    def tick(self):
t219        if ГоспожатаПоХимия.is_pot_depleted:t237        if self.is_pot_depleted:
220            ГоспожатаПоХимия.pot_duration -= 1238            self.pot_duration -= 1
221            if ГоспожатаПоХимия.pot_duration == 0:239            if self.pot_duration == 0:
222                ГоспожатаПоХимия.object.__dict__ = ГоспожатаПоХимия.target_dic240                self.object.__dict__ = self.target_dic
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

t1from entities import Entityt
2import math1import math
32
43
5class Potion:4class Potion:
6    def __init__(self, effects, duration):5    def __init__(self, effects, duration):
7        self.effects = dict(effects)6        self.effects = dict(effects)
8        self.duration = duration7        self.duration = duration
9        self._create_effect_methods()8        self._create_effect_methods()
10        self.effects_used = {k:2 for k in self.effects}9        self.effects_used = {k:2 for k in self.effects}
11        self.effects_applicable = {k:True for k in self.effects}10        self.effects_applicable = {k:True for k in self.effects}
12        self.used_in_reaction = False11        self.used_in_reaction = False
13    12    
14    def _create_effect_methods(self):13    def _create_effect_methods(self):
15        for effect_name, effect_function in self.effects.items():14        for effect_name, effect_function in self.effects.items():
16            setattr(self, effect_name, 15            setattr(self, effect_name, 
17                    self._create_effect_wrapper(effect_name, effect_function))16                    self._create_effect_wrapper(effect_name, effect_function))
1817
19    def _create_effect_wrapper(self, effect_name, effect_func):18    def _create_effect_wrapper(self, effect_name, effect_func):
20        def wrapper(target):19        def wrapper(target):
21            if (all(value == False for value in 20            if (all(value == False for value in 
22                    self.effects_applicable.values())):21                    self.effects_applicable.values())):
23                raise TypeError('Potion is depleted')22                raise TypeError('Potion is depleted')
24            elif not self.effects_applicable[effect_name]:23            elif not self.effects_applicable[effect_name]:
25                raise TypeError('Effect is depleted.')24                raise TypeError('Effect is depleted.')
26            else:25            else:
27                for intensity in range(self.effects_used[effect_name]):26                for intensity in range(self.effects_used[effect_name]):
28                    effect_func(target)27                    effect_func(target)
29                    self.effects_used[effect_name] -= 228                    self.effects_used[effect_name] -= 2
30                self.effects_applicable[effect_name] = False29                self.effects_applicable[effect_name] = False
31        return wrapper30        return wrapper
3231
33    def __add__(self, other):32    def __add__(self, other):
34        if not self.used_in_reaction and not other.used_in_reaction:33        if not self.used_in_reaction and not other.used_in_reaction:
35            new_pot_effects = self.effects.copy()34            new_pot_effects = self.effects.copy()
36            new_pot_effects_used = self.effects_used.copy()35            new_pot_effects_used = self.effects_used.copy()
37            self.used_in_reaction = True36            self.used_in_reaction = True
38            other.used_in_reaction = True37            other.used_in_reaction = True
39            for effect_name, effect_function in other.effects.items():38            for effect_name, effect_function in other.effects.items():
40                try:39                try:
41                    new_pot_effects_used[effect_name] += 240                    new_pot_effects_used[effect_name] += 2
42                except KeyError:41                except KeyError:
43                    new_pot_effects[effect_name] = effect_function42                    new_pot_effects[effect_name] = effect_function
44            new_pot_durat = 143            new_pot_durat = 1
45            if self.duration >= other.duration:44            if self.duration >= other.duration:
46                new_pot_durat = self.duration45                new_pot_durat = self.duration
47            else:46            else:
48                new_pot_durat = other.duration47                new_pot_durat = other.duration
49            new_potion = Potion(new_pot_effects, new_pot_durat) 48            new_potion = Potion(new_pot_effects, new_pot_durat) 
50            new_potion.effects_used = new_pot_effects_used49            new_potion.effects_used = new_pot_effects_used
5150
52            for k, v in self.effects.items():51            for k, v in self.effects.items():
53                delattr(self, k)52                delattr(self, k)
54            self.effects.clear()53            self.effects.clear()
55            for k, v in self.effects_used.items():54            for k, v in self.effects_used.items():
56                self.effects_used[k] = 155                self.effects_used[k] = 1
57        else:56        else:
58            raise TypeError('Potion is depleted.')57            raise TypeError('Potion is depleted.')
59        return new_potion58        return new_potion
6059
61    def __mul__(self, num):60    def __mul__(self, num):
62        if not self.used_in_reaction:61        if not self.used_in_reaction:
63            new_potion = Potion(self.effects.copy(), self.duration)62            new_potion = Potion(self.effects.copy(), self.duration)
64            new_potion.effects_used = self.effects_used.copy()63            new_potion.effects_used = self.effects_used.copy()
65            new_potion.effects_applicable = self.effects_applicable.copy()64            new_potion.effects_applicable = self.effects_applicable.copy()
66            self.used_in_reaction = True65            self.used_in_reaction = True
67            for k, v in self.effects_applicable.items():66            for k, v in self.effects_applicable.items():
68                self.effects_applicable[k] = False67                self.effects_applicable[k] = False
6968
70            for k, v in new_potion.effects_used.items():69            for k, v in new_potion.effects_used.items():
7170
72                new_potion.effects_used[k] *= num71                new_potion.effects_used[k] *= num
73                shorter_length = new_potion.effects_used[k]72                shorter_length = new_potion.effects_used[k]
74                if shorter_length <= math.floor(shorter_length) + 1.5:73                if shorter_length <= math.floor(shorter_length) + 1.5:
75                    new_potion.effects_used[k] = math.floor(shorter_length)74                    new_potion.effects_used[k] = math.floor(shorter_length)
76                else:75                else:
77                    new_potion.effects_used[k] = math.ceil(shorter_length)76                    new_potion.effects_used[k] = math.ceil(shorter_length)
78                77                
79    78    
80            # for k, v in self.effects.items():79            # for k, v in self.effects.items():
81            #     delattr(self, k)80            #     delattr(self, k)
8281
83            for k, v in self.effects_used.items():82            for k, v in self.effects_used.items():
84                self.effects_used[k] = 183                self.effects_used[k] = 1
85        else:84        else:
86            raise TypeError('Potion is now part of something bigger.')85            raise TypeError('Potion is now part of something bigger.')
87        86        
8887
89        return new_potion88        return new_potion
90    89    
91    def __sub__(self, other):90    def __sub__(self, other):
92        new_potion = Potion(self.effects.copy(), self.duration)91        new_potion = Potion(self.effects.copy(), self.duration)
93        new_potion.effects_used = self.effects_used.copy()92        new_potion.effects_used = self.effects_used.copy()
94        93        
95        self.used_in_reaction = True94        self.used_in_reaction = True
96        other.used_in_reaction = True95        other.used_in_reaction = True
9796
98        for k, v in other.effects.items():97        for k, v in other.effects.items():
99            if k not in self.effects:98            if k not in self.effects:
100                raise TypeError('ne izdyrjam poveche na tozi jivot')99                raise TypeError('ne izdyrjam poveche na tozi jivot')
101            else:100            else:
102                intens = new_potion.effects_used[k] - other.effects_used[k]101                intens = new_potion.effects_used[k] - other.effects_used[k]
103                if intens < 1:102                if intens < 1:
104                    new_potion.effects.pop(k)103                    new_potion.effects.pop(k)
105                    delattr(new_potion, new_potion.k)104                    delattr(new_potion, new_potion.k)
106                    new_potion.effects_used.pop(k)105                    new_potion.effects_used.pop(k)
107                else:106                else:
108                    new_potion.effects_used[k] -= intens107                    new_potion.effects_used[k] -= intens
109108
110        for k, v in self.effects.items():109        for k, v in self.effects.items():
111            delattr(self, k)110            delattr(self, k)
112        self.effects.clear()111        self.effects.clear()
113        for k, v in self.effects_used.items():112        for k, v in self.effects_used.items():
114            self.effects_used[k] = 1113            self.effects_used[k] = 1
115        114        
116        for k, v in other.effects.items():115        for k, v in other.effects.items():
117            delattr(other, k)116            delattr(other, k)
118        other.effects.clear()117        other.effects.clear()
119        other.effects_used.clear()118        other.effects_used.clear()
120119
121        return new_potion120        return new_potion
122    121    
123    def __truediv__(self, number):122    def __truediv__(self, number):
124        divided_potions = []123        divided_potions = []
125124
126        new_pot = Potion(self.effects.copy(), self.duration)125        new_pot = Potion(self.effects.copy(), self.duration)
127        new_pot.effects_used = self.effects_used.copy()126        new_pot.effects_used = self.effects_used.copy()
128        self.used_in_reaction = True127        self.used_in_reaction = True
129128
130        for k, v in new_pot.effects_used.items():129        for k, v in new_pot.effects_used.items():
131            new_pot.effects_used[k] /= number130            new_pot.effects_used[k] /= number
132            shorter_length = new_pot.effects_used[k]131            shorter_length = new_pot.effects_used[k]
133            if shorter_length <= math.floor(shorter_length) + 0.5:132            if shorter_length <= math.floor(shorter_length) + 0.5:
134                new_pot.effects_used[k] = math.floor(shorter_length)133                new_pot.effects_used[k] = math.floor(shorter_length)
135            else:134            else:
136                new_pot.effects_used[k] = math.ceil(shorter_length)135                new_pot.effects_used[k] = math.ceil(shorter_length)
137        136        
138        for _ in range(number):137        for _ in range(number):
139            divided_potions.append(new_pot)138            divided_potions.append(new_pot)
140        139        
141        for k, v in self.effects.items():140        for k, v in self.effects.items():
142            delattr(self, k)141            delattr(self, k)
143        self.effects.clear()142        self.effects.clear()
144        self.effects_used.clear()143        self.effects_used.clear()
145        144        
146        return divided_potions145        return divided_potions
147    146    
148    def __getattr__(self, attr):147    def __getattr__(self, attr):
149        if self.used_in_reaction:148        if self.used_in_reaction:
150            raise TypeError(149            raise TypeError(
151                'Potion is now part of something bigger than itself.'150                'Potion is now part of something bigger than itself.'
152                )151                )
153    152    
154    def __eq__(self, other):153    def __eq__(self, other):
155        sum_self_intens = 0154        sum_self_intens = 0
156        sum_other_intens = 0155        sum_other_intens = 0
157156
158        for k, v in self.effects_used.items():157        for k, v in self.effects_used.items():
159            if k not in other.effects_used:158            if k not in other.effects_used:
160                return False159                return False
161            sum_self_intens += self.effects_used[k]160            sum_self_intens += self.effects_used[k]
162            sum_other_intens += other.effects_used[k]161            sum_other_intens += other.effects_used[k]
163        162        
164        if sum_self_intens == sum_other_intens:163        if sum_self_intens == sum_other_intens:
165            return True164            return True
166        return False165        return False
167166
168    def __lt__(self, other):167    def __lt__(self, other):
169        sum_self_intens = 0168        sum_self_intens = 0
170        sum_other_intens = 0169        sum_other_intens = 0
171        for k, v in self.effects_used.items():170        for k, v in self.effects_used.items():
172            sum_self_intens += self.effects_used[k]171            sum_self_intens += self.effects_used[k]
173            sum_other_intens += other.effects_used[k]172            sum_other_intens += other.effects_used[k]
174        if sum_self_intens < sum_other_intens:173        if sum_self_intens < sum_other_intens:
175            return True174            return True
176        else:175        else:
177            return False176            return False
178    177    
179    def __gt__(self, other):178    def __gt__(self, other):
180        sum_self_intens = 0179        sum_self_intens = 0
181        sum_other_intens = 0180        sum_other_intens = 0
182        for k, v in self.effects_used.items():181        for k, v in self.effects_used.items():
183            sum_self_intens += self.effects_used[k]182            sum_self_intens += self.effects_used[k]
184            sum_other_intens += other.effects_used[k]183            sum_other_intens += other.effects_used[k]
185        if sum_self_intens > sum_other_intens:184        if sum_self_intens > sum_other_intens:
186            return True185            return True
187        else:186        else:
188            return False187            return False
189188
190189
191class ГоспожатаПоХимия:190class ГоспожатаПоХимия:
192191
193    is_pot_depleted = False192    is_pot_depleted = False
194    pot_duration = 0193    pot_duration = 0
195    target_dic = {}194    target_dic = {}
196    object = None195    object = None
197    objects = []196    objects = []
198197
199    def apply(self, target, potion):198    def apply(self, target, potion):
200        if potion not in ГоспожатаПоХимия.objects:199        if potion not in ГоспожатаПоХимия.objects:
201            ГоспожатаПоХимия.target_dic = target.__dict__.copy()200            ГоспожатаПоХимия.target_dic = target.__dict__.copy()
202            new_dict = {}201            new_dict = {}
203            for k, v in potion.effects.items():202            for k, v in potion.effects.items():
204                ascii_sum = sum(ord(char) for char in k)203                ascii_sum = sum(ord(char) for char in k)
205                new_dict[ascii_sum] = v204                new_dict[ascii_sum] = v
206            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))205            sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))
207            for k, v in sorted_effects.items():206            for k, v in sorted_effects.items():
208                v(target)207                v(target)
209                potion.effects_applicable[k] = False208                potion.effects_applicable[k] = False
210            ГоспожатаПоХимия.is_pot_depleted = True209            ГоспожатаПоХимия.is_pot_depleted = True
211            ГоспожатаПоХимия.pot_duration = potion.duration210            ГоспожатаПоХимия.pot_duration = potion.duration
212            ГоспожатаПоХимия.object = target211            ГоспожатаПоХимия.object = target
213            ГоспожатаПоХимия.objects.append(potion)212            ГоспожатаПоХимия.objects.append(potion)
214            potion.used_in_reaction = True213            potion.used_in_reaction = True
215214
216        else:215        else:
217            raise TypeError('Potion is depleted.')216            raise TypeError('Potion is depleted.')
218217
219    def tick(self):218    def tick(self):
220        if ГоспожатаПоХимия.is_pot_depleted:219        if ГоспожатаПоХимия.is_pot_depleted:
221            ГоспожатаПоХимия.pot_duration -= 1220            ГоспожатаПоХимия.pot_duration -= 1
222            if ГоспожатаПоХимия.pot_duration == 0:221            if ГоспожатаПоХимия.pot_duration == 0:
223                ГоспожатаПоХимия.object.__dict__ = ГоспожатаПоХимия.target_dic222                ГоспожатаПоХимия.object.__dict__ = ГоспожатаПоХимия.target_dic
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op