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

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

4 точки общо

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

  1import copy
  2
  3MIN_UNSIGNED_INT = 0
  4
  5class Potion:
  6    def __init__(self, effects, duration):
  7        self.effects = effects
  8        self.duration = duration
  9
 10        self.effects_intensity = {}
 11        self.create_intensity()
 12
 13        self.set_effects_as_methods()
 14
 15        self.is_unusable = False
 16        self.usable_effects = set(self.effects.keys())
 17
 18    @staticmethod
 19    def rounded(number):
 20        rounded_num = round(number)
 21        return rounded_num + 1 if number - rounded_num > 0.5 else rounded_num
 22
 23    def set_effects_as_methods(self):
 24        for effect in self.effects:
 25            setattr(self, effect, self.log_method_callings(effect, self.effects[effect]))
 26    def check_potion_obsolete(self):
 27        if self.is_unusable:
 28            raise TypeError("Potion is now part of something bigger than itself.")
 29
 30    def log_method_callings(self, effect, method):
 31        def wrapper(*args, **kwargs):
 32            self.check_potion_obsolete()
 33            if effect not in self.usable_effects:
 34                raise TypeError(f"Effect is depleted.")
 35
 36            self.usable_effects.remove(effect)
 37
 38            for times in range(0, self.effects_intensity[effect]):
 39                if self.effects_intensity[effect] == 1:
 40                    self.check_potion_obsolete()
 41                    return method(*args, **kwargs)
 42                else:
 43                    self.check_potion_obsolete()
 44                    method(*args, **kwargs)
 45
 46            return method
 47        return wrapper
 48
 49    def create_intensity(self):
 50        self.effects_intensity = {effect:1 for effect in self.effects}
 51
 52    def __add__(self, other):
 53        self.check_potion_obsolete()
 54        new_effects = self.effects.copy()
 55        new_intensity = self.effects_intensity.copy()
 56        new_duration = self.duration
 57        #effects
 58        for effect in other.effects:
 59            #if the same
 60            if effect in self.effects:
 61                new_intensity[effect] += 1
 62                #if not the same
 63            else:
 64                new_effects[effect] = other.effects[effect]
 65                new_intensity[effect] = 1
 66        #duration
 67        if self.duration < other.duration:
 68            new_duration = other.duration
 69
 70        new_potion = Potion(new_effects, new_duration)
 71        new_potion.effects_intensity = new_intensity
 72        self.usable_effects.update(other.usable_effects)
 73        new_potion.usable_effects = self.usable_effects
 74
 75        self.is_unusable = True
 76
 77        return new_potion
 78
 79    def __mul__(self, number):
 80        self.check_potion_obsolete()
 81        if number>0 and isinstance(number, int):
 82            new_intensity = {intensity_effect: self.effects_intensity[intensity_effect] * number
 83                                 for intensity_effect in self.effects_intensity}
 84
 85            new_potion = Potion(self.effects, self.duration)
 86            new_potion.effects_intensity = new_intensity
 87
 88            self.is_unusable = True
 89
 90            return new_potion
 91
 92        elif 0 <= number <= 1 and isinstance(number, float):
 93            new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] * number)
 94                                 for intensity_effect in self.effects_intensity}
 95
 96            new_potion = Potion(self.effects, self.duration)
 97            new_potion.effects_intensity = new_intensity
 98
 99            self.is_unusable = True
100
101            return new_potion
102
103    def __sub__(self, other):
104        self.check_potion_obsolete()
105        new_effects = self.effects.copy()
106        new_intensity = self.effects_intensity.copy()
107        for key in self.effects.keys():
108            print(key)
109            if key in other.effects.keys():
110                if self.effects_intensity[key] == 1:
111                    del new_effects[key]
112                    del new_intensity[key]
113                else:
114                    new_intensity[key] -= other.effects_intensity[key]
115                    if new_intensity[key] <= 0:
116                        del new_effects[key]
117                        del new_intensity[key]
118
119
120        new_potion = Potion(new_effects, self.duration)
121        new_potion.effects_intensity = new_intensity
122
123        self.is_unusable = True
124
125        return new_potion
126
127    def __truediv__(self, number):
128        self.check_potion_obsolete()
129        new_effects = self.effects.copy()
130
131        new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] / number)
132                         for intensity_effect in self.effects_intensity}
133
134        new_potion = Potion(new_effects, self.duration)
135        new_potion.effects_intensity = new_intensity
136        new_potion.usable_effects = set(new_effects.keys())
137
138        new_potions = (new_potion, ) * number
139
140        self.is_unusable = True
141
142        return new_potions
143
144    def __eq__(self, other):
145        return self.effects == other.effects and self.effects_intensity == other.effects_intensity
146
147    def __gt__(self, other):
148        return sum(self.effects_intensity.values()) > sum(other.effects_intensity.values())
149
150    def __lt__(self, other):
151        return sum(self.effects_intensity.values()) < sum(other.effects_intensity.values())
152
153    def __getattr__(self, method_name):
154        return getattr(self, method_name)()
155class ГоспожатаПоХимия:
156    def __init__(self):
157        self.applied_potions = {}
158        self.given_target_copy = None
159        self.current_target_object = None
160
161    @staticmethod
162    def sum_of_unicode_chars(string):
163        return sum(map(ord, string))
164
165    def find_current_max_sum(self, names_of_effects):
166        max_sum = MIN_UNSIGNED_INT
167        max_sum_name = ""
168        for name in names_of_effects:
169            if self.sum_of_unicode_chars(name) > max_sum:
170                max_sum = self.sum_of_unicode_chars(name)
171                max_sum_name = name
172
173        return max_sum_name
174
175    def apply(self, target, potion):
176        names_of_effects = potion.usable_effects
177        self.applied_potions[tuple(names_of_effects)] = potion.duration
178        self.given_target_copy = copy.deepcopy(target)
179        self.current_target_object = target
180
181        if potion.is_unusable or len(potion.usable_effects) == 0:
182            raise TypeError("Potion is depleted.")
183        else:
184            potion.is_unusable = True
185
186        while len(potion.usable_effects) != 0:
187            current_max_sum_name_effect = self.find_current_max_sum(names_of_effects)
188            if current_max_sum_name_effect in potion.usable_effects:
189                potion.current_max_sum_name_effect(target)
190            else:
191                raise TypeError("Effect is depleted.")
192
193
194    def tick(self):
195        for potion in self.applied_potions:
196            self.applied_potions[potion] -= 1
197            if self.applied_potions[potion] == 0:
198                del self.applied_potions[potion]
199                self.current_target_object = self.given_target_copy

.......FF.E
Stdout:
int_attr_fun
float_attr_fun
EEEEEEEEE
======================================================================
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)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded

Stdout:
int_attr_fun
float_attr_fun

======================================================================
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 34, in wrapper
raise TypeError(f"Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
ERROR: 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 379, in test_applying_depleted_potion
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
ERROR: test_applying_normal_case (test.TestГоспожатаПоХимия)
Test applying a normal potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 350, in test_applying_normal_case
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
ERROR: test_applying_order (test.TestГоспожатаПоХимия)
Test applying order of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 404, in test_applying_order
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
ERROR: 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 365, in test_applying_part_of_potion
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
ERROR: test_ticking_immutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with immutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 424, in test_ticking_immutable
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
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 454, in test_ticking_multiple_potions
self._dimitrichka.apply(self._target, potion1)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
ERROR: 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 485, in test_ticking_multiple_targets
self._dimitrichka.apply(target1, potion1)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
ERROR: test_ticking_mutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 438, in test_ticking_mutable
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 189, in apply
potion.current_max_sum_name_effect(target)
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
File "/tmp/solution.py", line 154, in __getattr__
return getattr(self, method_name)()
[Previous line repeated 488 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

======================================================================
FAIL: test_deprecation (test.TestPotionOperations)
Test deprecation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 259, in test_deprecation
with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
AssertionError: TypeError not raised

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

----------------------------------------------------------------------
Ran 20 tests in 0.012s

FAILED (failures=2, errors=10)

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

f1import copyf1import copy
22
3MIN_UNSIGNED_INT = 03MIN_UNSIGNED_INT = 0
44
5class Potion:5class Potion:
6    def __init__(self, effects, duration):6    def __init__(self, effects, duration):
7        self.effects = effects7        self.effects = effects
8        self.duration = duration8        self.duration = duration
99
10        self.effects_intensity = {}10        self.effects_intensity = {}
11        self.create_intensity()11        self.create_intensity()
1212
13        self.set_effects_as_methods()13        self.set_effects_as_methods()
1414
15        self.is_unusable = False15        self.is_unusable = False
16        self.usable_effects = set(self.effects.keys())16        self.usable_effects = set(self.effects.keys())
1717
18    @staticmethod18    @staticmethod
19    def rounded(number):19    def rounded(number):
20        rounded_num = round(number)20        rounded_num = round(number)
21        return rounded_num + 1 if number - rounded_num > 0.5 else rounded_num21        return rounded_num + 1 if number - rounded_num > 0.5 else rounded_num
2222
23    def set_effects_as_methods(self):23    def set_effects_as_methods(self):
24        for effect in self.effects:24        for effect in self.effects:
25            setattr(self, effect, self.log_method_callings(effect, self.effects[effect]))25            setattr(self, effect, self.log_method_callings(effect, self.effects[effect]))
26    def check_potion_obsolete(self):26    def check_potion_obsolete(self):
27        if self.is_unusable:27        if self.is_unusable:
28            raise TypeError("Potion is now part of something bigger than itself.")28            raise TypeError("Potion is now part of something bigger than itself.")
2929
30    def log_method_callings(self, effect, method):30    def log_method_callings(self, effect, method):
31        def wrapper(*args, **kwargs):31        def wrapper(*args, **kwargs):
nn32            self.check_potion_obsolete()
32            if effect not in self.usable_effects:33            if effect not in self.usable_effects:
n33                raise TypeError("Effect is depleted.")n34                raise TypeError(f"Effect is depleted.")
3435
35            self.usable_effects.remove(effect)36            self.usable_effects.remove(effect)
3637
37            for times in range(0, self.effects_intensity[effect]):38            for times in range(0, self.effects_intensity[effect]):
38                if self.effects_intensity[effect] == 1:39                if self.effects_intensity[effect] == 1:
nn40                    self.check_potion_obsolete()
39                    return method41                    return method(*args, **kwargs)
40                else:42                else:
nn43                    self.check_potion_obsolete()
41                    method()44                    method(*args, **kwargs)
4245
43            return method46            return method
44        return wrapper47        return wrapper
4548
46    def create_intensity(self):49    def create_intensity(self):
47        self.effects_intensity = {effect:1 for effect in self.effects}50        self.effects_intensity = {effect:1 for effect in self.effects}
4851
49    def __add__(self, other):52    def __add__(self, other):
50        self.check_potion_obsolete()53        self.check_potion_obsolete()
51        new_effects = self.effects.copy()54        new_effects = self.effects.copy()
52        new_intensity = self.effects_intensity.copy()55        new_intensity = self.effects_intensity.copy()
53        new_duration = self.duration56        new_duration = self.duration
54        #effects57        #effects
n55        for effect in self.effects:n58        for effect in other.effects:
56            #if the same59            #if the same
n57            if effect in other.effects:n60            if effect in self.effects:
58                new_intensity[effect] += 161                new_intensity[effect] += 1
59                #if not the same62                #if not the same
60            else:63            else:
61                new_effects[effect] = other.effects[effect]64                new_effects[effect] = other.effects[effect]
62                new_intensity[effect] = 165                new_intensity[effect] = 1
63        #duration66        #duration
64        if self.duration < other.duration:67        if self.duration < other.duration:
65            new_duration = other.duration68            new_duration = other.duration
6669
67        new_potion = Potion(new_effects, new_duration)70        new_potion = Potion(new_effects, new_duration)
68        new_potion.effects_intensity = new_intensity71        new_potion.effects_intensity = new_intensity
nn72        self.usable_effects.update(other.usable_effects)
69        new_potion.usable_effects = self.usable_effects73        new_potion.usable_effects = self.usable_effects
7074
71        self.is_unusable = True75        self.is_unusable = True
7276
73        return new_potion77        return new_potion
7478
75    def __mul__(self, number):79    def __mul__(self, number):
76        self.check_potion_obsolete()80        self.check_potion_obsolete()
77        if number>0 and isinstance(number, int):81        if number>0 and isinstance(number, int):
78            new_intensity = {intensity_effect: self.effects_intensity[intensity_effect] * number82            new_intensity = {intensity_effect: self.effects_intensity[intensity_effect] * number
79                                 for intensity_effect in self.effects_intensity}83                                 for intensity_effect in self.effects_intensity}
8084
81            new_potion = Potion(self.effects, self.duration)85            new_potion = Potion(self.effects, self.duration)
82            new_potion.effects_intensity = new_intensity86            new_potion.effects_intensity = new_intensity
8387
nn88            self.is_unusable = True
89 
84            return new_potion90            return new_potion
8591
86        elif 0 <= number <= 1 and isinstance(number, float):92        elif 0 <= number <= 1 and isinstance(number, float):
87            new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] * number)93            new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] * number)
88                                 for intensity_effect in self.effects_intensity}94                                 for intensity_effect in self.effects_intensity}
8995
90            new_potion = Potion(self.effects, self.duration)96            new_potion = Potion(self.effects, self.duration)
91            new_potion.effects_intensity = new_intensity97            new_potion.effects_intensity = new_intensity
9298
93            self.is_unusable = True99            self.is_unusable = True
94100
95            return new_potion101            return new_potion
96102
97    def __sub__(self, other):103    def __sub__(self, other):
98        self.check_potion_obsolete()104        self.check_potion_obsolete()
99        new_effects = self.effects.copy()105        new_effects = self.effects.copy()
100        new_intensity = self.effects_intensity.copy()106        new_intensity = self.effects_intensity.copy()
101        for key in self.effects.keys():107        for key in self.effects.keys():
nn108            print(key)
102            if key in other.effects.keys():109            if key in other.effects.keys():
nn110                if self.effects_intensity[key] == 1:
103                del new_effects[key]111                    del new_effects[key]
104                del new_intensity[key]112                    del new_intensity[key]
105            else:113                else:
106                raise TypeError("Subtraction not possible due to missing effect/s...")114                    new_intensity[key] -= other.effects_intensity[key]
115                    if new_intensity[key] <= 0:
116                        del new_effects[key]
117                        del new_intensity[key]
118 
107119
108        new_potion = Potion(new_effects, self.duration)120        new_potion = Potion(new_effects, self.duration)
109        new_potion.effects_intensity = new_intensity121        new_potion.effects_intensity = new_intensity
110122
111        self.is_unusable = True123        self.is_unusable = True
112124
113        return new_potion125        return new_potion
114126
115    def __truediv__(self, number):127    def __truediv__(self, number):
116        self.check_potion_obsolete()128        self.check_potion_obsolete()
117        new_effects = self.effects.copy()129        new_effects = self.effects.copy()
118130
n119        new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] / new_effects)n131        new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] / number)
120                         for intensity_effect in self.effects_intensity}132                         for intensity_effect in self.effects_intensity}
121133
122        new_potion = Potion(new_effects, self.duration)134        new_potion = Potion(new_effects, self.duration)
123        new_potion.effects_intensity = new_intensity135        new_potion.effects_intensity = new_intensity
nn136        new_potion.usable_effects = set(new_effects.keys())
124137
125        new_potions = (new_potion, ) * number138        new_potions = (new_potion, ) * number
126139
127        self.is_unusable = True140        self.is_unusable = True
128141
129        return new_potions142        return new_potions
130143
131    def __eq__(self, other):144    def __eq__(self, other):
132        return self.effects == other.effects and self.effects_intensity == other.effects_intensity145        return self.effects == other.effects and self.effects_intensity == other.effects_intensity
133146
134    def __gt__(self, other):147    def __gt__(self, other):
135        return sum(self.effects_intensity.values()) > sum(other.effects_intensity.values())148        return sum(self.effects_intensity.values()) > sum(other.effects_intensity.values())
136149
137    def __lt__(self, other):150    def __lt__(self, other):
138        return sum(self.effects_intensity.values()) < sum(other.effects_intensity.values())151        return sum(self.effects_intensity.values()) < sum(other.effects_intensity.values())
139152
nn153    def __getattr__(self, method_name):
154        return getattr(self, method_name)()
140class ГоспожатаПоХимия:155class ГоспожатаПоХимия:
141    def __init__(self):156    def __init__(self):
142        self.applied_potions = {}157        self.applied_potions = {}
143        self.given_target_copy = None158        self.given_target_copy = None
144        self.current_target_object = None159        self.current_target_object = None
145160
146    @staticmethod161    @staticmethod
147    def sum_of_unicode_chars(string):162    def sum_of_unicode_chars(string):
148        return sum(map(ord, string))163        return sum(map(ord, string))
149164
150    def find_current_max_sum(self, names_of_effects):165    def find_current_max_sum(self, names_of_effects):
151        max_sum = MIN_UNSIGNED_INT166        max_sum = MIN_UNSIGNED_INT
152        max_sum_name = ""167        max_sum_name = ""
153        for name in names_of_effects:168        for name in names_of_effects:
154            if self.sum_of_unicode_chars(name) > max_sum:169            if self.sum_of_unicode_chars(name) > max_sum:
155                max_sum = self.sum_of_unicode_chars(name)170                max_sum = self.sum_of_unicode_chars(name)
156                max_sum_name = name171                max_sum_name = name
157172
158        return max_sum_name173        return max_sum_name
159174
160    def apply(self, target, potion):175    def apply(self, target, potion):
161        names_of_effects = potion.usable_effects176        names_of_effects = potion.usable_effects
n162        self.applied_potions[potion] = potion.durationn177        self.applied_potions[tuple(names_of_effects)] = potion.duration
163        self.given_target_copy = copy.deepcopy(target)178        self.given_target_copy = copy.deepcopy(target)
164        self.current_target_object = target179        self.current_target_object = target
165180
166        if potion.is_unusable or len(potion.usable_effects) == 0:181        if potion.is_unusable or len(potion.usable_effects) == 0:
167            raise TypeError("Potion is depleted.")182            raise TypeError("Potion is depleted.")
168        else:183        else:
169            potion.is_unusable = True184            potion.is_unusable = True
170185
171        while len(potion.usable_effects) != 0:186        while len(potion.usable_effects) != 0:
172            current_max_sum_name_effect = self.find_current_max_sum(names_of_effects)187            current_max_sum_name_effect = self.find_current_max_sum(names_of_effects)
173            if current_max_sum_name_effect in potion.usable_effects:188            if current_max_sum_name_effect in potion.usable_effects:
174                potion.current_max_sum_name_effect(target)189                potion.current_max_sum_name_effect(target)
175            else:190            else:
176                raise TypeError("Effect is depleted.")191                raise TypeError("Effect is depleted.")
177192
178193
179    def tick(self):194    def tick(self):
180        for potion in self.applied_potions:195        for potion in self.applied_potions:
181            self.applied_potions[potion] -= 1196            self.applied_potions[potion] -= 1
182            if self.applied_potions[potion] == 0:197            if self.applied_potions[potion] == 0:
183                del self.applied_potions[potion]198                del self.applied_potions[potion]
184                self.current_target_object = self.given_target_copy199                self.current_target_object = self.given_target_copy
185200
186201
187202
188203
t189 t
190 
191 
192 
193 
194 
195 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import copyf1import copy
22
3MIN_UNSIGNED_INT = 03MIN_UNSIGNED_INT = 0
44
5class Potion:5class Potion:
6    def __init__(self, effects, duration):6    def __init__(self, effects, duration):
7        self.effects = effects7        self.effects = effects
8        self.duration = duration8        self.duration = duration
99
10        self.effects_intensity = {}10        self.effects_intensity = {}
11        self.create_intensity()11        self.create_intensity()
1212
13        self.set_effects_as_methods()13        self.set_effects_as_methods()
1414
15        self.is_unusable = False15        self.is_unusable = False
16        self.usable_effects = set(self.effects.keys())16        self.usable_effects = set(self.effects.keys())
1717
18    @staticmethod18    @staticmethod
19    def rounded(number):19    def rounded(number):
20        rounded_num = round(number)20        rounded_num = round(number)
21        return rounded_num + 1 if number - rounded_num > 0.5 else rounded_num21        return rounded_num + 1 if number - rounded_num > 0.5 else rounded_num
2222
23    def set_effects_as_methods(self):23    def set_effects_as_methods(self):
24        for effect in self.effects:24        for effect in self.effects:
25            setattr(self, effect, self.log_method_callings(effect, self.effects[effect]))25            setattr(self, effect, self.log_method_callings(effect, self.effects[effect]))
26    def check_potion_obsolete(self):26    def check_potion_obsolete(self):
27        if self.is_unusable:27        if self.is_unusable:
28            raise TypeError("Potion is now part of something bigger than itself.")28            raise TypeError("Potion is now part of something bigger than itself.")
2929
30    def log_method_callings(self, effect, method):30    def log_method_callings(self, effect, method):
31        def wrapper(*args, **kwargs):31        def wrapper(*args, **kwargs):
32            if effect not in self.usable_effects:32            if effect not in self.usable_effects:
33                raise TypeError("Effect is depleted.")33                raise TypeError("Effect is depleted.")
3434
35            self.usable_effects.remove(effect)35            self.usable_effects.remove(effect)
3636
37            for times in range(0, self.effects_intensity[effect]):37            for times in range(0, self.effects_intensity[effect]):
38                if self.effects_intensity[effect] == 1:38                if self.effects_intensity[effect] == 1:
39                    return method39                    return method
40                else:40                else:
41                    method()41                    method()
4242
43            return method43            return method
44        return wrapper44        return wrapper
4545
46    def create_intensity(self):46    def create_intensity(self):
47        self.effects_intensity = {effect:1 for effect in self.effects}47        self.effects_intensity = {effect:1 for effect in self.effects}
4848
49    def __add__(self, other):49    def __add__(self, other):
50        self.check_potion_obsolete()50        self.check_potion_obsolete()
51        new_effects = self.effects.copy()51        new_effects = self.effects.copy()
52        new_intensity = self.effects_intensity.copy()52        new_intensity = self.effects_intensity.copy()
53        new_duration = self.duration53        new_duration = self.duration
54        #effects54        #effects
55        for effect in self.effects:55        for effect in self.effects:
56            #if the same56            #if the same
57            if effect in other.effects:57            if effect in other.effects:
58                new_intensity[effect] += 158                new_intensity[effect] += 1
59                #if not the same59                #if not the same
60            else:60            else:
61                new_effects[effect] = other.effects[effect]61                new_effects[effect] = other.effects[effect]
62                new_intensity[effect] = 162                new_intensity[effect] = 1
63        #duration63        #duration
64        if self.duration < other.duration:64        if self.duration < other.duration:
65            new_duration = other.duration65            new_duration = other.duration
6666
67        new_potion = Potion(new_effects, new_duration)67        new_potion = Potion(new_effects, new_duration)
68        new_potion.effects_intensity = new_intensity68        new_potion.effects_intensity = new_intensity
69        new_potion.usable_effects = self.usable_effects69        new_potion.usable_effects = self.usable_effects
7070
71        self.is_unusable = True71        self.is_unusable = True
7272
73        return new_potion73        return new_potion
7474
75    def __mul__(self, number):75    def __mul__(self, number):
76        self.check_potion_obsolete()76        self.check_potion_obsolete()
77        if number>0 and isinstance(number, int):77        if number>0 and isinstance(number, int):
78            new_intensity = {intensity_effect: self.effects_intensity[intensity_effect] * number78            new_intensity = {intensity_effect: self.effects_intensity[intensity_effect] * number
79                                 for intensity_effect in self.effects_intensity}79                                 for intensity_effect in self.effects_intensity}
8080
81            new_potion = Potion(self.effects, self.duration)81            new_potion = Potion(self.effects, self.duration)
82            new_potion.effects_intensity = new_intensity82            new_potion.effects_intensity = new_intensity
8383
84            return new_potion84            return new_potion
8585
86        elif 0 <= number <= 1 and isinstance(number, float):86        elif 0 <= number <= 1 and isinstance(number, float):
87            new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] * number)87            new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] * number)
88                                 for intensity_effect in self.effects_intensity}88                                 for intensity_effect in self.effects_intensity}
8989
90            new_potion = Potion(self.effects, self.duration)90            new_potion = Potion(self.effects, self.duration)
91            new_potion.effects_intensity = new_intensity91            new_potion.effects_intensity = new_intensity
9292
93            self.is_unusable = True93            self.is_unusable = True
9494
95            return new_potion95            return new_potion
9696
97    def __sub__(self, other):97    def __sub__(self, other):
98        self.check_potion_obsolete()98        self.check_potion_obsolete()
99        new_effects = self.effects.copy()99        new_effects = self.effects.copy()
100        new_intensity = self.effects_intensity.copy()100        new_intensity = self.effects_intensity.copy()
101        for key in self.effects.keys():101        for key in self.effects.keys():
102            if key in other.effects.keys():102            if key in other.effects.keys():
103                del new_effects[key]103                del new_effects[key]
104                del new_intensity[key]104                del new_intensity[key]
105            else:105            else:
106                raise TypeError("Subtraction not possible due to missing effect/s...")106                raise TypeError("Subtraction not possible due to missing effect/s...")
107107
108        new_potion = Potion(new_effects, self.duration)108        new_potion = Potion(new_effects, self.duration)
109        new_potion.effects_intensity = new_intensity109        new_potion.effects_intensity = new_intensity
110110
111        self.is_unusable = True111        self.is_unusable = True
112112
113        return new_potion113        return new_potion
114114
115    def __truediv__(self, number):115    def __truediv__(self, number):
116        self.check_potion_obsolete()116        self.check_potion_obsolete()
117        new_effects = self.effects.copy()117        new_effects = self.effects.copy()
118118
119        new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] / new_effects)119        new_intensity = {intensity_effect: self.rounded(self.effects_intensity[intensity_effect] / new_effects)
120                         for intensity_effect in self.effects_intensity}120                         for intensity_effect in self.effects_intensity}
121121
122        new_potion = Potion(new_effects, self.duration)122        new_potion = Potion(new_effects, self.duration)
123        new_potion.effects_intensity = new_intensity123        new_potion.effects_intensity = new_intensity
124124
125        new_potions = (new_potion, ) * number125        new_potions = (new_potion, ) * number
126126
127        self.is_unusable = True127        self.is_unusable = True
128128
129        return new_potions129        return new_potions
130130
131    def __eq__(self, other):131    def __eq__(self, other):
132        return self.effects == other.effects and self.effects_intensity == other.effects_intensity132        return self.effects == other.effects and self.effects_intensity == other.effects_intensity
133133
134    def __gt__(self, other):134    def __gt__(self, other):
135        return sum(self.effects_intensity.values()) > sum(other.effects_intensity.values())135        return sum(self.effects_intensity.values()) > sum(other.effects_intensity.values())
136136
137    def __lt__(self, other):137    def __lt__(self, other):
138        return sum(self.effects_intensity.values()) < sum(other.effects_intensity.values())138        return sum(self.effects_intensity.values()) < sum(other.effects_intensity.values())
139139
t140    def __call__(self, *args, **kwargs):t
141        #for calling effects and using intensity logic
142        pass
143 
144 
145class ГоспожатаПоХимия:140class ГоспожатаПоХимия:
146    def __init__(self):141    def __init__(self):
147        self.applied_potions = {}142        self.applied_potions = {}
148        self.given_target_copy = None143        self.given_target_copy = None
149        self.current_target_object = None144        self.current_target_object = None
150145
151    @staticmethod146    @staticmethod
152    def sum_of_unicode_chars(string):147    def sum_of_unicode_chars(string):
153        return sum(map(ord, string))148        return sum(map(ord, string))
154149
155    def find_current_max_sum(self, names_of_effects):150    def find_current_max_sum(self, names_of_effects):
156        max_sum = MIN_UNSIGNED_INT151        max_sum = MIN_UNSIGNED_INT
157        max_sum_name = ""152        max_sum_name = ""
158        for name in names_of_effects:153        for name in names_of_effects:
159            if self.sum_of_unicode_chars(name) > max_sum:154            if self.sum_of_unicode_chars(name) > max_sum:
160                max_sum = self.sum_of_unicode_chars(name)155                max_sum = self.sum_of_unicode_chars(name)
161                max_sum_name = name156                max_sum_name = name
162157
163        return max_sum_name158        return max_sum_name
164159
165    def apply(self, target, potion):160    def apply(self, target, potion):
166        names_of_effects = potion.usable_effects161        names_of_effects = potion.usable_effects
167        self.applied_potions[potion] = potion.duration162        self.applied_potions[potion] = potion.duration
168        self.given_target_copy = copy.deepcopy(target)163        self.given_target_copy = copy.deepcopy(target)
169        self.current_target_object = target164        self.current_target_object = target
170165
171        if potion.is_unusable or len(potion.usable_effects) == 0:166        if potion.is_unusable or len(potion.usable_effects) == 0:
172            raise TypeError("Potion is depleted.")167            raise TypeError("Potion is depleted.")
173        else:168        else:
174            potion.is_unusable = True169            potion.is_unusable = True
175170
176        while len(potion.usable_effects) != 0:171        while len(potion.usable_effects) != 0:
177            current_max_sum_name_effect = self.find_current_max_sum(names_of_effects)172            current_max_sum_name_effect = self.find_current_max_sum(names_of_effects)
178            if current_max_sum_name_effect in potion.usable_effects:173            if current_max_sum_name_effect in potion.usable_effects:
179                potion.current_max_sum_name_effect(target)174                potion.current_max_sum_name_effect(target)
180            else:175            else:
181                raise TypeError("Effect is depleted.")176                raise TypeError("Effect is depleted.")
182177
183178
184    def tick(self):179    def tick(self):
185        for potion in self.applied_potions:180        for potion in self.applied_potions:
186            self.applied_potions[potion] -= 1181            self.applied_potions[potion] -= 1
187            if self.applied_potions[potion] == 0:182            if self.applied_potions[potion] == 0:
188                del self.applied_potions[potion]183                del self.applied_potions[potion]
189                self.current_target_object = self.given_target_copy184                self.current_target_object = self.given_target_copy
190185
191186
192187
193188
194189
195190
196191
197192
198193
199194
200195
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op