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

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

9 точки общо

18 успешни теста
2 неуспешни теста
Код

  1import math
  2import copy
  3import re
  4
  5class Potion:
  6    @staticmethod
  7    def round_down(n):
  8        temp = math.floor(n)
  9        if n - temp <= 0.5:
 10            return math.floor(n)
 11        return math.ceil(n)
 12
 13    def _wholeness_check(self, func):
 14        def check(args):
 15            self._validate_not_depleted()
 16            self._validate_not_used()
 17            return func(args)
 18        return check
 19
 20    def _depleted_check(self, effect, func):
 21        def check(args):
 22            if effect in self.depleted_effects:
 23                if self.depleted_effects[effect]:
 24                    raise TypeError("Effect is depleted.")
 25                self.depleted_effects[effect] = True
 26            return func(args)
 27        return check
 28    
 29    def _apply_intensity(self, effect, func):
 30        def apply(args):
 31            if effect in self.intensity:
 32                for _ in range(self.intensity[effect]):
 33                    func(args)
 34        return apply
 35    
 36    def _copy(self):
 37        copy_potion = Potion({}, self.duration)
 38        for effect in self.effects:
 39            copy_potion.effects[effect] = self.effects[effect]
 40            copy_potion.depleted_effects[effect] = self.depleted_effects[effect]
 41            copy_potion.intensity[effect] = self.intensity[effect]
 42            setattr(copy_potion, effect, copy_potion._wholeness_check(
 43                copy_potion._depleted_check(
 44                    effect, copy_potion._apply_intensity(
 45                        effect, copy_potion.effects.get(effect)))))
 46        return copy_potion
 47
 48    def _validate_not_used(self):
 49        if self.used:
 50            raise TypeError("Potion is now part of something bigger than itself.")
 51
 52    def _validate_not_depleted(self):
 53        if self.depleted:
 54            raise TypeError("Potion is depleted.")
 55
 56    def _increase_potential(self, scale):
 57        multiplied_potion = self._copy()
 58        for effect in multiplied_potion.intensity:
 59            multiplied_potion.intensity[effect] *= scale
 60        self.used = True
 61        return multiplied_potion
 62    
 63    def _decrease_potential(self, scale):
 64        divided_potion = self._copy()
 65        for effect in divided_potion.intensity:
 66            divided_potion.intensity[effect] = Potion.round_down(
 67                divided_potion.intensity[effect] * scale)
 68        self.used = True
 69        return divided_potion
 70
 71    def __init__(self, effects, duration):
 72        self.used = False
 73        self.depleted = False
 74        self.effects = effects
 75        self.depleted_effects = {}
 76        self.intensity = {}
 77        for effect in effects:
 78            self.depleted_effects[effect] = False
 79            self.intensity[effect] = 1
 80            setattr(self, effect, self._wholeness_check(
 81                self._depleted_check(
 82                    effect, self._apply_intensity(
 83                        effect, effects.get(effect)))))
 84        self.duration = duration
 85    
 86    def apply(self, target):
 87        self._validate_not_depleted()
 88        self._validate_not_used()
 89        for effect in sorted(self.effects.keys(), 
 90                             key=lambda name: sum(ord(c) for c in name),
 91                             reverse=True):
 92            if not self.depleted_effects[effect]:
 93                getattr(self, effect)(target)
 94        self.depleted = True
 95
 96    def __add__(self, other):
 97        self._validate_not_depleted()
 98        self._validate_not_used()
 99        other._validate_not_depleted()
100        other._validate_not_used()
101        compound = self._copy()
102        for effect in other.effects:
103            if effect in compound.effects:
104                compound.intensity[effect] += other.intensity[effect]
105            else:
106                compound.effects[effect] = other.effects[effect]
107                compound.depleted_effects[effect] = other.depleted_effects[effect]
108                compound.intensity[effect] = other.intensity[effect]
109                setattr(compound, effect, compound._wholeness_check(
110                    compound._depleted_check(
111                        effect, compound._apply_intensity(
112                            effect, compound.effects.get(effect)))))
113        self.used = True
114        other.used = True
115        return compound
116
117    def __mul__(self, scale):
118        self._validate_not_depleted()
119        self._validate_not_used()
120        if scale > 1:
121            return self._increase_potential(scale)
122        return self._decrease_potential(scale)
123    
124    def __sub__(self, other):
125        self._validate_not_depleted()
126        self._validate_not_used()
127        other._validate_not_depleted()
128        other._validate_not_used()
129        purified_potion = self._copy()
130        for effect in other.effects:
131            if effect in purified_potion.effects:
132                if purified_potion.intensity[effect] > other.intensity[effect]:
133                    purified_potion.intensity[effect] -= other.intensity[effect]
134                else:
135                    purified_potion.depleted_effects.pop(effect)
136                    purified_potion.intensity.pop(effect)
137                    purified_potion.effects.pop(effect)
138                    delattr(purified_potion, effect)
139            else:
140                raise TypeError("Cannot remove non-existent effect.")
141        self.used = True
142        other.used = True
143        return purified_potion
144    
145    def __truediv__(self, scale):
146        self._validate_not_depleted()
147        self._validate_not_used()
148        potions = []
149        for _ in range(scale):
150            potion = self._copy()
151            for effect in potion.intensity:
152                potion.intensity[effect] //= scale
153            potions.append(potion)
154        self.used = True
155        return tuple(potions)
156    
157    def __eq__(self, other):
158        return (self.effects == other.effects and self.intensity == other.intensity)
159
160    def __lt__(self, other):
161        return sum(self.intensity.values()) < sum(other.intensity.values())
162    
163    def __gt__(self, other):
164        return sum(self.intensity.values()) > sum(other.intensity.values())
165
166
167class ГоспожатаПоХимия:
168    def __init__(self):
169        self.durations = {}
170        self.targets = {}
171        self.effects = {}
172
173    def apply(self, target, potion):
174        old_target = copy.deepcopy(target)
175        potion.apply(target)
176        self.durations[id(potion)] = potion.duration
177        if id(target) not in self.targets:
178            self.targets[id(target)] = old_target
179        self.effects[id(potion)] = [target, self.targets[id(target)]]
180
181    def tick(self):
182        for effect in self.durations:
183            self.durations[effect] -= 1
184            if  self.durations[effect] == 0:
185                target, old_target = self.effects[effect]
186                for attrib in target.__dir__():
187                    if re.search("^__[A-Za-z_0-9]+__$", attrib):
188                        continue
189                    setattr(target, attrib, getattr(old_target, attrib))

................FF..
======================================================================
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 427, in test_ticking_immutable
self.assertEqual(self._target.int_attr, 500)
AssertionError: 5 != 500

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

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

FAILED (failures=2)

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

f1import mathf1import math
2import copy2import copy
3import re3import re
44
5class Potion:5class Potion:
6    @staticmethod6    @staticmethod
7    def round_down(n):7    def round_down(n):
8        temp = math.floor(n)8        temp = math.floor(n)
9        if n - temp <= 0.5:9        if n - temp <= 0.5:
10            return math.floor(n)10            return math.floor(n)
11        return math.ceil(n)11        return math.ceil(n)
1212
13    def _wholeness_check(self, func):13    def _wholeness_check(self, func):
14        def check(args):14        def check(args):
15            self._validate_not_depleted()15            self._validate_not_depleted()
16            self._validate_not_used()16            self._validate_not_used()
17            return func(args)17            return func(args)
18        return check18        return check
1919
20    def _depleted_check(self, effect, func):20    def _depleted_check(self, effect, func):
21        def check(args):21        def check(args):
22            if effect in self.depleted_effects:22            if effect in self.depleted_effects:
23                if self.depleted_effects[effect]:23                if self.depleted_effects[effect]:
24                    raise TypeError("Effect is depleted.")24                    raise TypeError("Effect is depleted.")
25                self.depleted_effects[effect] = True25                self.depleted_effects[effect] = True
26            return func(args)26            return func(args)
27        return check27        return check
28    28    
29    def _apply_intensity(self, effect, func):29    def _apply_intensity(self, effect, func):
30        def apply(args):30        def apply(args):
31            if effect in self.intensity:31            if effect in self.intensity:
32                for _ in range(self.intensity[effect]):32                for _ in range(self.intensity[effect]):
33                    func(args)33                    func(args)
34        return apply34        return apply
35    35    
36    def _copy(self):36    def _copy(self):
37        copy_potion = Potion({}, self.duration)37        copy_potion = Potion({}, self.duration)
38        for effect in self.effects:38        for effect in self.effects:
39            copy_potion.effects[effect] = self.effects[effect]39            copy_potion.effects[effect] = self.effects[effect]
40            copy_potion.depleted_effects[effect] = self.depleted_effects[effect]40            copy_potion.depleted_effects[effect] = self.depleted_effects[effect]
41            copy_potion.intensity[effect] = self.intensity[effect]41            copy_potion.intensity[effect] = self.intensity[effect]
42            setattr(copy_potion, effect, copy_potion._wholeness_check(42            setattr(copy_potion, effect, copy_potion._wholeness_check(
43                copy_potion._depleted_check(43                copy_potion._depleted_check(
44                    effect, copy_potion._apply_intensity(44                    effect, copy_potion._apply_intensity(
45                        effect, copy_potion.effects.get(effect)))))45                        effect, copy_potion.effects.get(effect)))))
46        return copy_potion46        return copy_potion
4747
48    def _validate_not_used(self):48    def _validate_not_used(self):
49        if self.used:49        if self.used:
50            raise TypeError("Potion is now part of something bigger than itself.")50            raise TypeError("Potion is now part of something bigger than itself.")
5151
52    def _validate_not_depleted(self):52    def _validate_not_depleted(self):
53        if self.depleted:53        if self.depleted:
54            raise TypeError("Potion is depleted.")54            raise TypeError("Potion is depleted.")
5555
56    def _increase_potential(self, scale):56    def _increase_potential(self, scale):
57        multiplied_potion = self._copy()57        multiplied_potion = self._copy()
58        for effect in multiplied_potion.intensity:58        for effect in multiplied_potion.intensity:
59            multiplied_potion.intensity[effect] *= scale59            multiplied_potion.intensity[effect] *= scale
60        self.used = True60        self.used = True
61        return multiplied_potion61        return multiplied_potion
62    62    
63    def _decrease_potential(self, scale):63    def _decrease_potential(self, scale):
64        divided_potion = self._copy()64        divided_potion = self._copy()
65        for effect in divided_potion.intensity:65        for effect in divided_potion.intensity:
66            divided_potion.intensity[effect] = Potion.round_down(66            divided_potion.intensity[effect] = Potion.round_down(
67                divided_potion.intensity[effect] * scale)67                divided_potion.intensity[effect] * scale)
68        self.used = True68        self.used = True
69        return divided_potion69        return divided_potion
7070
71    def __init__(self, effects, duration):71    def __init__(self, effects, duration):
72        self.used = False72        self.used = False
73        self.depleted = False73        self.depleted = False
74        self.effects = effects74        self.effects = effects
75        self.depleted_effects = {}75        self.depleted_effects = {}
76        self.intensity = {}76        self.intensity = {}
77        for effect in effects:77        for effect in effects:
78            self.depleted_effects[effect] = False78            self.depleted_effects[effect] = False
79            self.intensity[effect] = 179            self.intensity[effect] = 1
80            setattr(self, effect, self._wholeness_check(80            setattr(self, effect, self._wholeness_check(
81                self._depleted_check(81                self._depleted_check(
82                    effect, self._apply_intensity(82                    effect, self._apply_intensity(
83                        effect, effects.get(effect)))))83                        effect, effects.get(effect)))))
84        self.duration = duration84        self.duration = duration
85    85    
86    def apply(self, target):86    def apply(self, target):
87        self._validate_not_depleted()87        self._validate_not_depleted()
88        self._validate_not_used()88        self._validate_not_used()
89        for effect in sorted(self.effects.keys(), 89        for effect in sorted(self.effects.keys(), 
90                             key=lambda name: sum(ord(c) for c in name),90                             key=lambda name: sum(ord(c) for c in name),
91                             reverse=True):91                             reverse=True):
92            if not self.depleted_effects[effect]:92            if not self.depleted_effects[effect]:
93                getattr(self, effect)(target)93                getattr(self, effect)(target)
94        self.depleted = True94        self.depleted = True
9595
96    def __add__(self, other):96    def __add__(self, other):
97        self._validate_not_depleted()97        self._validate_not_depleted()
98        self._validate_not_used()98        self._validate_not_used()
99        other._validate_not_depleted()99        other._validate_not_depleted()
100        other._validate_not_used()100        other._validate_not_used()
101        compound = self._copy()101        compound = self._copy()
102        for effect in other.effects:102        for effect in other.effects:
103            if effect in compound.effects:103            if effect in compound.effects:
104                compound.intensity[effect] += other.intensity[effect]104                compound.intensity[effect] += other.intensity[effect]
105            else:105            else:
106                compound.effects[effect] = other.effects[effect]106                compound.effects[effect] = other.effects[effect]
107                compound.depleted_effects[effect] = other.depleted_effects[effect]107                compound.depleted_effects[effect] = other.depleted_effects[effect]
108                compound.intensity[effect] = other.intensity[effect]108                compound.intensity[effect] = other.intensity[effect]
109                setattr(compound, effect, compound._wholeness_check(109                setattr(compound, effect, compound._wholeness_check(
110                    compound._depleted_check(110                    compound._depleted_check(
111                        effect, compound._apply_intensity(111                        effect, compound._apply_intensity(
112                            effect, compound.effects.get(effect)))))112                            effect, compound.effects.get(effect)))))
113        self.used = True113        self.used = True
114        other.used = True114        other.used = True
115        return compound115        return compound
116116
117    def __mul__(self, scale):117    def __mul__(self, scale):
118        self._validate_not_depleted()118        self._validate_not_depleted()
119        self._validate_not_used()119        self._validate_not_used()
120        if scale > 1:120        if scale > 1:
121            return self._increase_potential(scale)121            return self._increase_potential(scale)
122        return self._decrease_potential(scale)122        return self._decrease_potential(scale)
123    123    
124    def __sub__(self, other):124    def __sub__(self, other):
125        self._validate_not_depleted()125        self._validate_not_depleted()
126        self._validate_not_used()126        self._validate_not_used()
127        other._validate_not_depleted()127        other._validate_not_depleted()
128        other._validate_not_used()128        other._validate_not_used()
129        purified_potion = self._copy()129        purified_potion = self._copy()
130        for effect in other.effects:130        for effect in other.effects:
131            if effect in purified_potion.effects:131            if effect in purified_potion.effects:
132                if purified_potion.intensity[effect] > other.intensity[effect]:132                if purified_potion.intensity[effect] > other.intensity[effect]:
133                    purified_potion.intensity[effect] -= other.intensity[effect]133                    purified_potion.intensity[effect] -= other.intensity[effect]
134                else:134                else:
135                    purified_potion.depleted_effects.pop(effect)135                    purified_potion.depleted_effects.pop(effect)
136                    purified_potion.intensity.pop(effect)136                    purified_potion.intensity.pop(effect)
137                    purified_potion.effects.pop(effect)137                    purified_potion.effects.pop(effect)
138                    delattr(purified_potion, effect)138                    delattr(purified_potion, effect)
139            else:139            else:
140                raise TypeError("Cannot remove non-existent effect.")140                raise TypeError("Cannot remove non-existent effect.")
141        self.used = True141        self.used = True
142        other.used = True142        other.used = True
143        return purified_potion143        return purified_potion
144    144    
145    def __truediv__(self, scale):145    def __truediv__(self, scale):
146        self._validate_not_depleted()146        self._validate_not_depleted()
147        self._validate_not_used()147        self._validate_not_used()
148        potions = []148        potions = []
149        for _ in range(scale):149        for _ in range(scale):
150            potion = self._copy()150            potion = self._copy()
151            for effect in potion.intensity:151            for effect in potion.intensity:
152                potion.intensity[effect] //= scale152                potion.intensity[effect] //= scale
153            potions.append(potion)153            potions.append(potion)
154        self.used = True154        self.used = True
155        return tuple(potions)155        return tuple(potions)
156    156    
157    def __eq__(self, other):157    def __eq__(self, other):
158        return (self.effects == other.effects and self.intensity == other.intensity)158        return (self.effects == other.effects and self.intensity == other.intensity)
159159
160    def __lt__(self, other):160    def __lt__(self, other):
161        return sum(self.intensity.values()) < sum(other.intensity.values())161        return sum(self.intensity.values()) < sum(other.intensity.values())
162    162    
163    def __gt__(self, other):163    def __gt__(self, other):
164        return sum(self.intensity.values()) > sum(other.intensity.values())164        return sum(self.intensity.values()) > sum(other.intensity.values())
165165
166166
167class ГоспожатаПоХимия:167class ГоспожатаПоХимия:
168    def __init__(self):168    def __init__(self):
n169        self.durations = []n169        self.durations = {}
170        self.targets = {}
171        self.effects = {}
170172
171    def apply(self, target, potion):173    def apply(self, target, potion):
172        old_target = copy.deepcopy(target)174        old_target = copy.deepcopy(target)
173        potion.apply(target)175        potion.apply(target)
n174        self.durations.append([potion.duration, target, old_target])n176        self.durations[id(potion)] = potion.duration
177        if id(target) not in self.targets:
178            self.targets[id(target)] = old_target
179        self.effects[id(potion)] = [target, self.targets[id(target)]]
175180
176    def tick(self):181    def tick(self):
n177        for triplet in self.durations:n182        for effect in self.durations:
178            target, old_target = triplet[1], triplet[2]183            self.durations[effect] -= 1
179            triplet[0] -= 1184            if  self.durations[effect] == 0:
180            if triplet[0] == 0:185                target, old_target = self.effects[effect]
181                for attrib in old_target.__dir__():186                for attrib in target.__dir__():
182                    if re.search("^__[A-Za-z_0-9]+__$", attrib):187                    if re.search("^__[A-Za-z_0-9]+__$", attrib):
183                        continue188                        continue
184                    setattr(target, attrib, getattr(old_target, attrib))189                    setattr(target, attrib, getattr(old_target, attrib))
t185                self.durations.remove(triplet)t
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
2import copy2import copy
3import re3import re
44
5class Potion:5class Potion:
6    @staticmethod6    @staticmethod
7    def round_down(n):7    def round_down(n):
8        temp = math.floor(n)8        temp = math.floor(n)
9        if n - temp <= 0.5:9        if n - temp <= 0.5:
10            return math.floor(n)10            return math.floor(n)
11        return math.ceil(n)11        return math.ceil(n)
1212
13    def _wholeness_check(self, func):13    def _wholeness_check(self, func):
14        def check(args):14        def check(args):
15            self._validate_not_depleted()15            self._validate_not_depleted()
16            self._validate_not_used()16            self._validate_not_used()
17            return func(args)17            return func(args)
18        return check18        return check
1919
20    def _depleted_check(self, effect, func):20    def _depleted_check(self, effect, func):
21        def check(args):21        def check(args):
22            if effect in self.depleted_effects:22            if effect in self.depleted_effects:
23                if self.depleted_effects[effect]:23                if self.depleted_effects[effect]:
24                    raise TypeError("Effect is depleted.")24                    raise TypeError("Effect is depleted.")
25                self.depleted_effects[effect] = True25                self.depleted_effects[effect] = True
26            return func(args)26            return func(args)
27        return check27        return check
28    28    
29    def _apply_intensity(self, effect, func):29    def _apply_intensity(self, effect, func):
30        def apply(args):30        def apply(args):
31            if effect in self.intensity:31            if effect in self.intensity:
32                for _ in range(self.intensity[effect]):32                for _ in range(self.intensity[effect]):
33                    func(args)33                    func(args)
34        return apply34        return apply
35    35    
36    def _copy(self):36    def _copy(self):
37        copy_potion = Potion({}, self.duration)37        copy_potion = Potion({}, self.duration)
38        for effect in self.effects:38        for effect in self.effects:
39            copy_potion.effects[effect] = self.effects[effect]39            copy_potion.effects[effect] = self.effects[effect]
40            copy_potion.depleted_effects[effect] = self.depleted_effects[effect]40            copy_potion.depleted_effects[effect] = self.depleted_effects[effect]
41            copy_potion.intensity[effect] = self.intensity[effect]41            copy_potion.intensity[effect] = self.intensity[effect]
42            setattr(copy_potion, effect, copy_potion._wholeness_check(42            setattr(copy_potion, effect, copy_potion._wholeness_check(
43                copy_potion._depleted_check(43                copy_potion._depleted_check(
44                    effect, copy_potion._apply_intensity(44                    effect, copy_potion._apply_intensity(
45                        effect, copy_potion.effects.get(effect)))))45                        effect, copy_potion.effects.get(effect)))))
46        return copy_potion46        return copy_potion
4747
48    def _validate_not_used(self):48    def _validate_not_used(self):
49        if self.used:49        if self.used:
50            raise TypeError("Potion is now part of something bigger than itself.")50            raise TypeError("Potion is now part of something bigger than itself.")
5151
52    def _validate_not_depleted(self):52    def _validate_not_depleted(self):
53        if self.depleted:53        if self.depleted:
54            raise TypeError("Potion is depleted.")54            raise TypeError("Potion is depleted.")
5555
56    def _increase_potential(self, scale):56    def _increase_potential(self, scale):
57        multiplied_potion = self._copy()57        multiplied_potion = self._copy()
58        for effect in multiplied_potion.intensity:58        for effect in multiplied_potion.intensity:
59            multiplied_potion.intensity[effect] *= scale59            multiplied_potion.intensity[effect] *= scale
60        self.used = True60        self.used = True
61        return multiplied_potion61        return multiplied_potion
62    62    
63    def _decrease_potential(self, scale):63    def _decrease_potential(self, scale):
64        divided_potion = self._copy()64        divided_potion = self._copy()
65        for effect in divided_potion.intensity:65        for effect in divided_potion.intensity:
66            divided_potion.intensity[effect] = Potion.round_down(66            divided_potion.intensity[effect] = Potion.round_down(
67                divided_potion.intensity[effect] * scale)67                divided_potion.intensity[effect] * scale)
68        self.used = True68        self.used = True
69        return divided_potion69        return divided_potion
7070
71    def __init__(self, effects, duration):71    def __init__(self, effects, duration):
72        self.used = False72        self.used = False
73        self.depleted = False73        self.depleted = False
74        self.effects = effects74        self.effects = effects
75        self.depleted_effects = {}75        self.depleted_effects = {}
76        self.intensity = {}76        self.intensity = {}
77        for effect in effects:77        for effect in effects:
78            self.depleted_effects[effect] = False78            self.depleted_effects[effect] = False
79            self.intensity[effect] = 179            self.intensity[effect] = 1
80            setattr(self, effect, self._wholeness_check(80            setattr(self, effect, self._wholeness_check(
81                self._depleted_check(81                self._depleted_check(
82                    effect, self._apply_intensity(82                    effect, self._apply_intensity(
83                        effect, effects.get(effect)))))83                        effect, effects.get(effect)))))
84        self.duration = duration84        self.duration = duration
85    85    
86    def apply(self, target):86    def apply(self, target):
87        self._validate_not_depleted()87        self._validate_not_depleted()
88        self._validate_not_used()88        self._validate_not_used()
89        for effect in sorted(self.effects.keys(), 89        for effect in sorted(self.effects.keys(), 
90                             key=lambda name: sum(ord(c) for c in name),90                             key=lambda name: sum(ord(c) for c in name),
91                             reverse=True):91                             reverse=True):
92            if not self.depleted_effects[effect]:92            if not self.depleted_effects[effect]:
93                getattr(self, effect)(target)93                getattr(self, effect)(target)
94        self.depleted = True94        self.depleted = True
9595
n96    def __add__(self, o_potion):n96    def __add__(self, other):
97        self._validate_not_depleted()97        self._validate_not_depleted()
98        self._validate_not_used()98        self._validate_not_used()
n99        o_potion._validate_not_depleted()n99        other._validate_not_depleted()
100        o_potion._validate_not_used()100        other._validate_not_used()
101        compound = self._copy()101        compound = self._copy()
n102        for effect in o_potion.effects:n102        for effect in other.effects:
103            if effect in compound.effects:103            if effect in compound.effects:
n104                compound.intensity[effect] += o_potion.intensity[effect]n104                compound.intensity[effect] += other.intensity[effect]
105            else:105            else:
n106                compound.effects[effect] = o_potion.effects[effect]n106                compound.effects[effect] = other.effects[effect]
107                compound.depleted_effects[effect] = o_potion.depleted_effects[effect]107                compound.depleted_effects[effect] = other.depleted_effects[effect]
108                compound.intensity[effect] = o_potion.intensity[effect]108                compound.intensity[effect] = other.intensity[effect]
109                setattr(compound, effect, compound._wholeness_check(109                setattr(compound, effect, compound._wholeness_check(
110                    compound._depleted_check(110                    compound._depleted_check(
111                        effect, compound._apply_intensity(111                        effect, compound._apply_intensity(
112                            effect, compound.effects.get(effect)))))112                            effect, compound.effects.get(effect)))))
113        self.used = True113        self.used = True
n114        o_potion.used = Truen114        other.used = True
115        return compound115        return compound
116116
117    def __mul__(self, scale):117    def __mul__(self, scale):
118        self._validate_not_depleted()118        self._validate_not_depleted()
119        self._validate_not_used()119        self._validate_not_used()
120        if scale > 1:120        if scale > 1:
121            return self._increase_potential(scale)121            return self._increase_potential(scale)
122        return self._decrease_potential(scale)122        return self._decrease_potential(scale)
123    123    
n124    def __sub__(self, o_potion):n124    def __sub__(self, other):
125        self._validate_not_depleted()125        self._validate_not_depleted()
126        self._validate_not_used()126        self._validate_not_used()
n127        o_potion._validate_not_depleted()n127        other._validate_not_depleted()
128        o_potion._validate_not_used()128        other._validate_not_used()
129        purified_potion = self._copy()129        purified_potion = self._copy()
n130        for effect in o_potion.effects:n130        for effect in other.effects:
131            if effect in purified_potion.effects:131            if effect in purified_potion.effects:
n132                if purified_potion.intensity[effect] > o_potion.intensity[effect]:n132                if purified_potion.intensity[effect] > other.intensity[effect]:
133                    purified_potion.intensity[effect] -= o_potion.intensity[effect]133                    purified_potion.intensity[effect] -= other.intensity[effect]
134                else:134                else:
135                    purified_potion.depleted_effects.pop(effect)135                    purified_potion.depleted_effects.pop(effect)
136                    purified_potion.intensity.pop(effect)136                    purified_potion.intensity.pop(effect)
137                    purified_potion.effects.pop(effect)137                    purified_potion.effects.pop(effect)
138                    delattr(purified_potion, effect)138                    delattr(purified_potion, effect)
139            else:139            else:
140                raise TypeError("Cannot remove non-existent effect.")140                raise TypeError("Cannot remove non-existent effect.")
141        self.used = True141        self.used = True
n142        o_potion.used = Truen142        other.used = True
143        return purified_potion143        return purified_potion
144    144    
145    def __truediv__(self, scale):145    def __truediv__(self, scale):
146        self._validate_not_depleted()146        self._validate_not_depleted()
147        self._validate_not_used()147        self._validate_not_used()
148        potions = []148        potions = []
149        for _ in range(scale):149        for _ in range(scale):
150            potion = self._copy()150            potion = self._copy()
151            for effect in potion.intensity:151            for effect in potion.intensity:
152                potion.intensity[effect] //= scale152                potion.intensity[effect] //= scale
153            potions.append(potion)153            potions.append(potion)
154        self.used = True154        self.used = True
155        return tuple(potions)155        return tuple(potions)
156    156    
n157    def __eq__(self, o_potion):n157    def __eq__(self, other):
158        return (self.effects == o_potion.effects 158        return (self.effects == other.effects and self.intensity == other.intensity)
159    and self.intensity == o_potion.intensity)
160159
n161    def __lt__(self, o_potion):n160    def __lt__(self, other):
162        i1 = 0161        return sum(self.intensity.values()) < sum(other.intensity.values())
163        for intensity in self.intensity.values():
164            i1 += intensity
165        i2 = 0
166        for intensity in o_potion.intensity.values():
167            i2 += intensity
168        return i1 < i2
169    162    
n170    def __gt__(self, o_potion):n163    def __gt__(self, other):
171        i1 = 0164        return sum(self.intensity.values()) > sum(other.intensity.values())
172        for intensity in self.intensity.values():
173            i1 += intensity
174        i2 = 0
175        for intensity in o_potion.intensity.values():
176            i2 += intensity
177        return i1 > i2
178165
179166
180class ГоспожатаПоХимия:167class ГоспожатаПоХимия:
181    def __init__(self):168    def __init__(self):
182        self.durations = []169        self.durations = []
183170
184    def apply(self, target, potion):171    def apply(self, target, potion):
185        old_target = copy.deepcopy(target)172        old_target = copy.deepcopy(target)
186        potion.apply(target)173        potion.apply(target)
187        self.durations.append([potion.duration, target, old_target])174        self.durations.append([potion.duration, target, old_target])
188175
189    def tick(self):176    def tick(self):
190        for triplet in self.durations:177        for triplet in self.durations:
nn178            target, old_target = triplet[1], triplet[2]
191            triplet[0] -= 1179            triplet[0] -= 1
192            if triplet[0] == 0:180            if triplet[0] == 0:
n193                for attrib in triplet[2].__dir__():n181                for attrib in old_target.__dir__():
194                    if re.search("^__[A-Za-z_0-9]+__$", attrib):182                    if re.search("^__[A-Za-z_0-9]+__$", attrib):
195                        continue183                        continue
t196                    triplet[1].__setattr__(attrib, triplet[2].__getattribute__(attrib))t184                    setattr(target, attrib, getattr(old_target, attrib))
197                self.durations.remove(triplet)185                self.durations.remove(triplet)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op