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

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

7 точки общо

14 успешни теста
6 неуспешни теста
Код

  1import math
  2import copy
  3
  4
  5class Potion:
  6
  7    def __init__(self, effects, duration):
  8        self.effects = effects
  9        self.duration = duration
 10        self.intensity = {key: 1.0 for key in effects.keys()}
 11        self.used = False
 12        self.used_effects = {key: False for key in effects.keys()}
 13        self.start_duration = -1
 14        self.end_duration = -1
 15        for effect in effects.keys():
 16            setattr(self, effect, lambda target, name=effect: self.apply_effect(target, name))
 17
 18    @staticmethod
 19    def is_potion_used(*potions):
 20        for potion in potions:
 21            if potion.used:
 22                raise TypeError("Potion is now part of something bigger than itself.")
 23
 24    def __add__(self, other):
 25        Potion.is_potion_used(self, other)
 26
 27        combined_effects = dict(self.effects)
 28        combined_intensity = dict(self.intensity)
 29
 30        for key, value in other.effects.items():
 31            if key in combined_effects:
 32                combined_intensity[key] += other.intensity.get(key,0)
 33            else:
 34                combined_effects[key] = value
 35                combined_intensity[key] = other.intensity.get(key,0)
 36
 37        duration = max(self.duration, other.duration)
 38        new_potion = Potion(combined_effects, duration)
 39        new_potion.intensity = dict(combined_intensity)
 40        self.used = True
 41        other.used = True
 42        return new_potion
 43
 44    def __mul__(self, coefficient):
 45        Potion.is_potion_used(self)
 46
 47        multiplied_intensity = dict(self.intensity)
 48
 49        for key in self.intensity.keys():
 50            result_intensity = multiplied_intensity[key]*coefficient
 51            fraction, integer = math.modf(result_intensity)
 52            if coefficient >= 1:
 53                multiplied_intensity[key] = result_intensity
 54            elif fraction <= 0.5:
 55                multiplied_intensity[key] = float(math.floor(result_intensity))
 56            else:
 57                multiplied_intensity[key] = float(math.ceil(result_intensity))
 58
 59        new_potion = Potion(self.effects, self.duration)
 60        new_potion.intensity = dict(multiplied_intensity)
 61        self.used = True
 62        return new_potion
 63
 64    def __sub__(self, other):
 65        Potion.is_potion_used(self, other)
 66
 67        if not all(effect in self.effects for effect in other.effects):
 68            raise TypeError("Cannot subtract potions with different effects")
 69
 70        subtracted_effects = dict(self.effects)
 71        subtracted_intensity = dict(self.intensity)
 72
 73        to_delete_keys = []
 74        for key in other.effects.keys():
 75            if key in subtracted_effects:
 76                subtracted_intensity[key] -= other.intensity.get(key,0)
 77            if subtracted_intensity[key] <= 0:
 78                to_delete_keys.append(key)
 79
 80        for key in to_delete_keys:
 81            del subtracted_effects[key]
 82            del subtracted_intensity[key]
 83
 84        new_potion = Potion(subtracted_effects, self.duration)
 85        new_potion.intensity = dict(subtracted_intensity)
 86        self.used = True
 87        other.used = True
 88        return new_potion
 89
 90    def __truediv__(self, divisor):
 91        Potion.is_potion_used(self)
 92
 93        new_intensity = dict(self.intensity)
 94        for key in self.intensity.keys():
 95            result_intensity = new_intensity[key] / divisor
 96            fraction, integer = math.modf(result_intensity)
 97            if fraction <= 0.5:
 98                new_intensity[key] = float(math.floor(result_intensity))
 99            else:
100                new_intensity[key] = float(math.ceil(result_intensity))
101
102        new_potions = []
103        for _ in range(divisor):
104            new_potion = Potion(self.effects, self.duration)
105            new_potion.intensity = dict(new_intensity)
106            new_potions.append(new_potion)
107
108        self.used = True
109        return new_potions
110
111    def __eq__(self, other):
112        Potion.is_potion_used(self, other)
113
114        equal_intensities = True
115        for intensity_self_key, intensity_self_value in self.intensity.items():
116            for intensity_other_key, intensity_other_value in other.intensity.items():
117                if intensity_self_key == intensity_other_key:
118                    if intensity_self_value != intensity_other_value:
119                        equal_intensities = False
120        return (all(effect in self.effects for effect in other.effects) and
121                all(effect in other.effects for effect in self.effects) and
122                equal_intensities)
123
124    def __gt__(self, other):
125        Potion.is_potion_used(self, other)
126
127        sum_self = sum(self.intensity.values())
128        sum_other = sum(other.intensity.values())
129        return sum_self > sum_other
130
131    def __lt__(self, other):
132        Potion.is_potion_used(self, other)
133
134        sum_self = sum(self.intensity.values())
135        sum_other = sum(other.intensity.values())
136        return sum_self < sum_other
137
138    def apply_effect(self, target, effect):
139        Potion.is_potion_used(self)
140        if self.used_effects[effect]:
141            raise TypeError("Effect is depleted.")
142        for _ in range(int(self.intensity[effect])):
143            self.effects[effect](target)
144        self.used_effects[effect] = True
145
146
147class ГоспожатаПоХимия:
148
149    def __init__(self):
150        self.tick_count = 0
151        self.active_potions = {}
152        self.initial_states = {}
153
154    def apply(self, target, potion):
155        if potion.used:
156            raise TypeError("Potion is depleted.")
157
158        initial_state = copy.deepcopy(target)
159
160        sorted_by_molecular_mass = sorted(potion.intensity.items(),
161                                          key=lambda x: sum(ord(c) for c in x[0]), reverse=True)
162        for effect in sorted_by_molecular_mass:
163            for _ in range(int(effect[1])):
164                potion.apply_effect(target, effect[0])
165                potion.start_duration = self.tick_count
166                potion.end_duration = self.tick_count + potion.duration
167
168        """
169        if self.active_potions[id(target)]:
170            self.active_potions[id(target)] = potion
171            self.initial_states[id(target)] = initial_state, target
172        """
173
174    def tick(self):
175        #collect all applied (potions : target) in a list and subtract
176        #their potion.active variables every tick
177        #if a potion expires return to initial state of target
178        self.tick_count += 1
179
180        expired_potions = {target_id:potion for target_id, potion in self.active_potions.items()
181                           if potion.end_duration <= self.tick_count}
182
183        sorted_by_start_time = sorted(expired_potions.items(), key=lambda x: x[1].start_duration)
184        """
185        for target_id, potion in sorted_by_start_time:
186            if potion.end_duration <= self.tick_count:
187
188            self.active_potions.pop()
189            initial_state, target = self.initial_states.pop(target_id)
190            self.reset_target_to_initial_state(target, initial_state)
191        """
192
193    def reset_target_to_initial_state(self, target, initial_state):
194        target.__dict__.update(initial_state.__dict__)

............F..EEFEF
======================================================================
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 164, in apply
potion.apply_effect(target, effect[0])
File "/tmp/solution.py", line 141, in apply_effect
raise TypeError("Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
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 164, in apply
potion.apply_effect(target, effect[0])
File "/tmp/solution.py", line 141, in apply_effect
raise TypeError("Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
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 164, in apply
potion.apply_effect(target, effect[0])
File "/tmp/solution.py", line 141, in apply_effect
raise TypeError("Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
TypeError: Effect is depleted.

During handling of the above exception, another exception occurred:

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

======================================================================
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: 500 != 50

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

----------------------------------------------------------------------
Ran 20 tests in 0.002s

FAILED (failures=3, errors=3)

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

n1import math, copyn1import math
2import copy
23
34
4class Potion:5class Potion:
n5    n6 
6    def __init__(self, effects, duration):7    def __init__(self, effects, duration):
7        self.effects = effects8        self.effects = effects
8        self.duration = duration9        self.duration = duration
n9        self.intensity = {key:1.0 for key in effects.keys()}n10        self.intensity = {key: 1.0 for key in effects.keys()}
10        self.used = False11        self.used = False
n11        self.used_effects = {key:False for key in effects.keys()}n12        self.used_effects = {key: False for key in effects.keys()}
12        self.start_duration = -113        self.start_duration = -1
13        self.end_duration = -114        self.end_duration = -1
14        for effect in effects.keys():15        for effect in effects.keys():
15            setattr(self, effect, lambda target, name=effect: self.apply_effect(target, name))16            setattr(self, effect, lambda target, name=effect: self.apply_effect(target, name))
1617
nn18    @staticmethod
19    def is_potion_used(*potions):
20        for potion in potions:
21            if potion.used:
22                raise TypeError("Potion is now part of something bigger than itself.")
23 
17    def __add__(self, other):24    def __add__(self, other):
n18        if self.used or other.used:n25        Potion.is_potion_used(self, other)
19            raise TypeError("Potion is now part of something bigger than itself.")
2026
21        combined_effects = dict(self.effects)27        combined_effects = dict(self.effects)
22        combined_intensity = dict(self.intensity)28        combined_intensity = dict(self.intensity)
2329
24        for key, value in other.effects.items():30        for key, value in other.effects.items():
25            if key in combined_effects:31            if key in combined_effects:
26                combined_intensity[key] += other.intensity.get(key,0)32                combined_intensity[key] += other.intensity.get(key,0)
27            else:33            else:
28                combined_effects[key] = value34                combined_effects[key] = value
29                combined_intensity[key] = other.intensity.get(key,0)35                combined_intensity[key] = other.intensity.get(key,0)
3036
31        duration = max(self.duration, other.duration)37        duration = max(self.duration, other.duration)
32        new_potion = Potion(combined_effects, duration)38        new_potion = Potion(combined_effects, duration)
33        new_potion.intensity = dict(combined_intensity)39        new_potion.intensity = dict(combined_intensity)
34        self.used = True40        self.used = True
35        other.used = True41        other.used = True
36        return new_potion42        return new_potion
3743
38    def __mul__(self, coefficient):44    def __mul__(self, coefficient):
n39        if self.used:n45        Potion.is_potion_used(self)
40            raise TypeError("Potion is now part of something bigger than itself.")
4146
42        multiplied_intensity = dict(self.intensity)47        multiplied_intensity = dict(self.intensity)
4348
44        for key in self.intensity.keys():49        for key in self.intensity.keys():
45            result_intensity = multiplied_intensity[key]*coefficient50            result_intensity = multiplied_intensity[key]*coefficient
46            fraction, integer = math.modf(result_intensity)51            fraction, integer = math.modf(result_intensity)
47            if coefficient >= 1:52            if coefficient >= 1:
48                multiplied_intensity[key] = result_intensity53                multiplied_intensity[key] = result_intensity
49            elif fraction <= 0.5:54            elif fraction <= 0.5:
50                multiplied_intensity[key] = float(math.floor(result_intensity))55                multiplied_intensity[key] = float(math.floor(result_intensity))
51            else:56            else:
52                multiplied_intensity[key] = float(math.ceil(result_intensity))57                multiplied_intensity[key] = float(math.ceil(result_intensity))
5358
54        new_potion = Potion(self.effects, self.duration)59        new_potion = Potion(self.effects, self.duration)
55        new_potion.intensity = dict(multiplied_intensity)60        new_potion.intensity = dict(multiplied_intensity)
56        self.used = True61        self.used = True
57        return new_potion62        return new_potion
5863
59    def __sub__(self, other):64    def __sub__(self, other):
n60        if self.used or other.used:n65        Potion.is_potion_used(self, other)
61            raise TypeError("Potion is now part of something bigger than itself.")
6266
63        if not all(effect in self.effects for effect in other.effects):67        if not all(effect in self.effects for effect in other.effects):
64            raise TypeError("Cannot subtract potions with different effects")68            raise TypeError("Cannot subtract potions with different effects")
6569
66        subtracted_effects = dict(self.effects)70        subtracted_effects = dict(self.effects)
67        subtracted_intensity = dict(self.intensity)71        subtracted_intensity = dict(self.intensity)
6872
69        to_delete_keys = []73        to_delete_keys = []
70        for key in other.effects.keys():74        for key in other.effects.keys():
71            if key in subtracted_effects:75            if key in subtracted_effects:
72                subtracted_intensity[key] -= other.intensity.get(key,0)76                subtracted_intensity[key] -= other.intensity.get(key,0)
73            if subtracted_intensity[key] <= 0:77            if subtracted_intensity[key] <= 0:
74                to_delete_keys.append(key)78                to_delete_keys.append(key)
7579
76        for key in to_delete_keys:80        for key in to_delete_keys:
77            del subtracted_effects[key]81            del subtracted_effects[key]
78            del subtracted_intensity[key]82            del subtracted_intensity[key]
7983
80        new_potion = Potion(subtracted_effects, self.duration)84        new_potion = Potion(subtracted_effects, self.duration)
81        new_potion.intensity = dict(subtracted_intensity)85        new_potion.intensity = dict(subtracted_intensity)
82        self.used = True86        self.used = True
83        other.used = True87        other.used = True
84        return new_potion88        return new_potion
8589
86    def __truediv__(self, divisor):90    def __truediv__(self, divisor):
n87        if self.used:n91        Potion.is_potion_used(self)
88            raise TypeError("Potion is now part of something bigger than itself.")
8992
90        new_intensity = dict(self.intensity)93        new_intensity = dict(self.intensity)
91        for key in self.intensity.keys():94        for key in self.intensity.keys():
n92            result_intensity = new_intensity[key]/divisorn95            result_intensity = new_intensity[key] / divisor
93            fraction, integer = math.modf(result_intensity)96            fraction, integer = math.modf(result_intensity)
94            if fraction <= 0.5:97            if fraction <= 0.5:
95                new_intensity[key] = float(math.floor(result_intensity))98                new_intensity[key] = float(math.floor(result_intensity))
96            else:99            else:
97                new_intensity[key] = float(math.ceil(result_intensity))100                new_intensity[key] = float(math.ceil(result_intensity))
98101
99        new_potions = []102        new_potions = []
100        for _ in range(divisor):103        for _ in range(divisor):
101            new_potion = Potion(self.effects, self.duration)104            new_potion = Potion(self.effects, self.duration)
102            new_potion.intensity = dict(new_intensity)105            new_potion.intensity = dict(new_intensity)
103            new_potions.append(new_potion)106            new_potions.append(new_potion)
104107
105        self.used = True108        self.used = True
106        return new_potions109        return new_potions
107110
108    def __eq__(self, other):111    def __eq__(self, other):
n109        if self.used or other.used:n112        Potion.is_potion_used(self, other)
110            raise TypeError("Potion is now part of something bigger than itself.")113 
111        equal_intensities = True114        equal_intensities = True
112        for intensity_self_key, intensity_self_value in self.intensity.items():115        for intensity_self_key, intensity_self_value in self.intensity.items():
113            for intensity_other_key, intensity_other_value in other.intensity.items():116            for intensity_other_key, intensity_other_value in other.intensity.items():
114                if intensity_self_key == intensity_other_key:117                if intensity_self_key == intensity_other_key:
115                    if intensity_self_value != intensity_other_value:118                    if intensity_self_value != intensity_other_value:
116                        equal_intensities = False119                        equal_intensities = False
117        return (all(effect in self.effects for effect in other.effects) and120        return (all(effect in self.effects for effect in other.effects) and
118                all(effect in other.effects for effect in self.effects) and121                all(effect in other.effects for effect in self.effects) and
119                equal_intensities)122                equal_intensities)
120123
121    def __gt__(self, other):124    def __gt__(self, other):
n122        if self.used or other.used:n125        Potion.is_potion_used(self, other)
123            raise TypeError("Potion is now part of something bigger than itself.")
124126
125        sum_self = sum(self.intensity.values())127        sum_self = sum(self.intensity.values())
126        sum_other = sum(other.intensity.values())128        sum_other = sum(other.intensity.values())
127        return sum_self > sum_other129        return sum_self > sum_other
128130
129    def __lt__(self, other):131    def __lt__(self, other):
n130        if self.used or other.used:n132        Potion.is_potion_used(self, other)
131            raise TypeError("Potion is now part of something bigger than itself.")
132133
133        sum_self = sum(self.intensity.values())134        sum_self = sum(self.intensity.values())
134        sum_other = sum(other.intensity.values())135        sum_other = sum(other.intensity.values())
135        return sum_self < sum_other136        return sum_self < sum_other
136137
137    def apply_effect(self, target, effect):138    def apply_effect(self, target, effect):
t138        if self.used:t139        Potion.is_potion_used(self)
139            raise TypeError("Potion is now part of something bigger than itself.")
140        if self.used_effects[effect]:140        if self.used_effects[effect]:
141            raise TypeError("Effect is depleted.")141            raise TypeError("Effect is depleted.")
142        for _ in range(int(self.intensity[effect])):142        for _ in range(int(self.intensity[effect])):
143            self.effects[effect](target)143            self.effects[effect](target)
144        self.used_effects[effect] = True144        self.used_effects[effect] = True
145145
146146
147class ГоспожатаПоХимия:147class ГоспожатаПоХимия:
148148
149    def __init__(self):149    def __init__(self):
150        self.tick_count = 0150        self.tick_count = 0
151        self.active_potions = {}151        self.active_potions = {}
152        self.initial_states = {}152        self.initial_states = {}
153153
154    def apply(self, target, potion):154    def apply(self, target, potion):
155        if potion.used:155        if potion.used:
156            raise TypeError("Potion is depleted.")156            raise TypeError("Potion is depleted.")
157157
158        initial_state = copy.deepcopy(target)158        initial_state = copy.deepcopy(target)
159159
160        sorted_by_molecular_mass = sorted(potion.intensity.items(),160        sorted_by_molecular_mass = sorted(potion.intensity.items(),
161                                          key=lambda x: sum(ord(c) for c in x[0]), reverse=True)161                                          key=lambda x: sum(ord(c) for c in x[0]), reverse=True)
162        for effect in sorted_by_molecular_mass:162        for effect in sorted_by_molecular_mass:
163            for _ in range(int(effect[1])):163            for _ in range(int(effect[1])):
164                potion.apply_effect(target, effect[0])164                potion.apply_effect(target, effect[0])
165                potion.start_duration = self.tick_count165                potion.start_duration = self.tick_count
166                potion.end_duration = self.tick_count + potion.duration166                potion.end_duration = self.tick_count + potion.duration
167167
168        """168        """
169        if self.active_potions[id(target)]:169        if self.active_potions[id(target)]:
170            self.active_potions[id(target)] = potion170            self.active_potions[id(target)] = potion
171            self.initial_states[id(target)] = initial_state, target171            self.initial_states[id(target)] = initial_state, target
172        """172        """
173173
174    def tick(self):174    def tick(self):
175        #collect all applied (potions : target) in a list and subtract175        #collect all applied (potions : target) in a list and subtract
176        #their potion.active variables every tick176        #their potion.active variables every tick
177        #if a potion expires return to initial state of target177        #if a potion expires return to initial state of target
178        self.tick_count += 1178        self.tick_count += 1
179179
180        expired_potions = {target_id:potion for target_id, potion in self.active_potions.items()180        expired_potions = {target_id:potion for target_id, potion in self.active_potions.items()
181                           if potion.end_duration <= self.tick_count}181                           if potion.end_duration <= self.tick_count}
182182
183        sorted_by_start_time = sorted(expired_potions.items(), key=lambda x: x[1].start_duration)183        sorted_by_start_time = sorted(expired_potions.items(), key=lambda x: x[1].start_duration)
184        """184        """
185        for target_id, potion in sorted_by_start_time:185        for target_id, potion in sorted_by_start_time:
186            if potion.end_duration <= self.tick_count:186            if potion.end_duration <= self.tick_count:
187187
188            self.active_potions.pop()188            self.active_potions.pop()
189            initial_state, target = self.initial_states.pop(target_id)189            initial_state, target = self.initial_states.pop(target_id)
190            self.reset_target_to_initial_state(target, initial_state)190            self.reset_target_to_initial_state(target, initial_state)
191        """191        """
192192
193    def reset_target_to_initial_state(self, target, initial_state):193    def reset_target_to_initial_state(self, target, initial_state):
194        target.__dict__.update(initial_state.__dict__)194        target.__dict__.update(initial_state.__dict__)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import math, copyf1import math, copy
22
nn3 
3class Potion:4class Potion:
nn5    
4    def __init__(self, effects, duration):6    def __init__(self, effects, duration):
5        self.effects = effects7        self.effects = effects
6        self.duration = duration8        self.duration = duration
7        self.intensity = {key:1.0 for key in effects.keys()}9        self.intensity = {key:1.0 for key in effects.keys()}
8        self.used = False10        self.used = False
9        self.used_effects = {key:False for key in effects.keys()}11        self.used_effects = {key:False for key in effects.keys()}
10        self.start_duration = -112        self.start_duration = -1
11        self.end_duration = -113        self.end_duration = -1
12        for effect in effects.keys():14        for effect in effects.keys():
13            setattr(self, effect, lambda target, name=effect: self.apply_effect(target, name))15            setattr(self, effect, lambda target, name=effect: self.apply_effect(target, name))
1416
15    def __add__(self, other):17    def __add__(self, other):
16        if self.used or other.used:18        if self.used or other.used:
17            raise TypeError("Potion is now part of something bigger than itself.")19            raise TypeError("Potion is now part of something bigger than itself.")
n18        n20 
19        combined_effects = dict(self.effects)21        combined_effects = dict(self.effects)
20        combined_intensity = dict(self.intensity)22        combined_intensity = dict(self.intensity)
2123
22        for key, value in other.effects.items():24        for key, value in other.effects.items():
23            if key in combined_effects:25            if key in combined_effects:
24                combined_intensity[key] += other.intensity.get(key,0)26                combined_intensity[key] += other.intensity.get(key,0)
25            else:27            else:
26                combined_effects[key] = value28                combined_effects[key] = value
27                combined_intensity[key] = other.intensity.get(key,0)29                combined_intensity[key] = other.intensity.get(key,0)
2830
29        duration = max(self.duration, other.duration)31        duration = max(self.duration, other.duration)
30        new_potion = Potion(combined_effects, duration)32        new_potion = Potion(combined_effects, duration)
31        new_potion.intensity = dict(combined_intensity)33        new_potion.intensity = dict(combined_intensity)
32        self.used = True34        self.used = True
33        other.used = True35        other.used = True
34        return new_potion36        return new_potion
n35    n37 
36    def __mul__(self, coefficient):38    def __mul__(self, coefficient):
37        if self.used:39        if self.used:
38            raise TypeError("Potion is now part of something bigger than itself.")40            raise TypeError("Potion is now part of something bigger than itself.")
n39        n41 
40        multiplied_intensity = dict(self.intensity)42        multiplied_intensity = dict(self.intensity)
4143
42        for key in self.intensity.keys():44        for key in self.intensity.keys():
43            result_intensity = multiplied_intensity[key]*coefficient45            result_intensity = multiplied_intensity[key]*coefficient
44            fraction, integer = math.modf(result_intensity)46            fraction, integer = math.modf(result_intensity)
45            if coefficient >= 1:47            if coefficient >= 1:
46                multiplied_intensity[key] = result_intensity48                multiplied_intensity[key] = result_intensity
47            elif fraction <= 0.5:49            elif fraction <= 0.5:
48                multiplied_intensity[key] = float(math.floor(result_intensity))50                multiplied_intensity[key] = float(math.floor(result_intensity))
49            else:51            else:
50                multiplied_intensity[key] = float(math.ceil(result_intensity))52                multiplied_intensity[key] = float(math.ceil(result_intensity))
n51        n53 
52        new_potion = Potion(self.effects, self.duration)54        new_potion = Potion(self.effects, self.duration)
53        new_potion.intensity = dict(multiplied_intensity)55        new_potion.intensity = dict(multiplied_intensity)
54        self.used = True56        self.used = True
55        return new_potion57        return new_potion
n56    n58 
57    def __sub__(self, other):59    def __sub__(self, other):
58        if self.used or other.used:60        if self.used or other.used:
59            raise TypeError("Potion is now part of something bigger than itself.")61            raise TypeError("Potion is now part of something bigger than itself.")
n60        n62 
61        if not all(effect in self.effects for effect in other.effects):63        if not all(effect in self.effects for effect in other.effects):
62            raise TypeError("Cannot subtract potions with different effects")64            raise TypeError("Cannot subtract potions with different effects")
n63        n65 
64        subtracted_effects = dict(self.effects)66        subtracted_effects = dict(self.effects)
65        subtracted_intensity = dict(self.intensity)67        subtracted_intensity = dict(self.intensity)
n66        n68 
67        to_delete_keys = []69        to_delete_keys = []
n68        for key, value in other.effects.items():n70        for key in other.effects.keys():
69            if key in subtracted_effects:71            if key in subtracted_effects:
70                subtracted_intensity[key] -= other.intensity.get(key,0)72                subtracted_intensity[key] -= other.intensity.get(key,0)
71            if subtracted_intensity[key] <= 0:73            if subtracted_intensity[key] <= 0:
72                to_delete_keys.append(key)74                to_delete_keys.append(key)
7375
74        for key in to_delete_keys:76        for key in to_delete_keys:
75            del subtracted_effects[key]77            del subtracted_effects[key]
76            del subtracted_intensity[key]78            del subtracted_intensity[key]
7779
78        new_potion = Potion(subtracted_effects, self.duration)80        new_potion = Potion(subtracted_effects, self.duration)
79        new_potion.intensity = dict(subtracted_intensity)81        new_potion.intensity = dict(subtracted_intensity)
80        self.used = True82        self.used = True
81        other.used = True83        other.used = True
82        return new_potion84        return new_potion
n83    n85 
84    def __truediv__(self, divisor):86    def __truediv__(self, divisor):
85        if self.used:87        if self.used:
86            raise TypeError("Potion is now part of something bigger than itself.")88            raise TypeError("Potion is now part of something bigger than itself.")
8789
88        new_intensity = dict(self.intensity)90        new_intensity = dict(self.intensity)
89        for key in self.intensity.keys():91        for key in self.intensity.keys():
90            result_intensity = new_intensity[key]/divisor92            result_intensity = new_intensity[key]/divisor
91            fraction, integer = math.modf(result_intensity)93            fraction, integer = math.modf(result_intensity)
92            if fraction <= 0.5:94            if fraction <= 0.5:
93                new_intensity[key] = float(math.floor(result_intensity))95                new_intensity[key] = float(math.floor(result_intensity))
94            else:96            else:
95                new_intensity[key] = float(math.ceil(result_intensity))97                new_intensity[key] = float(math.ceil(result_intensity))
9698
97        new_potions = []99        new_potions = []
98        for _ in range(divisor):100        for _ in range(divisor):
99            new_potion = Potion(self.effects, self.duration)101            new_potion = Potion(self.effects, self.duration)
100            new_potion.intensity = dict(new_intensity)102            new_potion.intensity = dict(new_intensity)
101            new_potions.append(new_potion)103            new_potions.append(new_potion)
n102        n104 
103        self.used = True105        self.used = True
104        return new_potions106        return new_potions
n105    n107 
106    def __eq__(self, other):108    def __eq__(self, other):
107        if self.used or other.used:109        if self.used or other.used:
108            raise TypeError("Potion is now part of something bigger than itself.")110            raise TypeError("Potion is now part of something bigger than itself.")
109        equal_intensities = True111        equal_intensities = True
110        for intensity_self_key, intensity_self_value in self.intensity.items():112        for intensity_self_key, intensity_self_value in self.intensity.items():
111            for intensity_other_key, intensity_other_value in other.intensity.items():113            for intensity_other_key, intensity_other_value in other.intensity.items():
112                if intensity_self_key == intensity_other_key:114                if intensity_self_key == intensity_other_key:
113                    if intensity_self_value != intensity_other_value:115                    if intensity_self_value != intensity_other_value:
114                        equal_intensities = False116                        equal_intensities = False
115        return (all(effect in self.effects for effect in other.effects) and117        return (all(effect in self.effects for effect in other.effects) and
116                all(effect in other.effects for effect in self.effects) and118                all(effect in other.effects for effect in self.effects) and
117                equal_intensities)119                equal_intensities)
n118    n120 
119    def __gt__(self, other):121    def __gt__(self, other):
120        if self.used or other.used:122        if self.used or other.used:
121            raise TypeError("Potion is now part of something bigger than itself.")123            raise TypeError("Potion is now part of something bigger than itself.")
n122        n124 
123        sum_self = sum(self.intensity.values())125        sum_self = sum(self.intensity.values())
124        sum_other = sum(other.intensity.values())126        sum_other = sum(other.intensity.values())
125        return sum_self > sum_other127        return sum_self > sum_other
n126    n128 
127    def __lt__(self, other):129    def __lt__(self, other):
128        if self.used or other.used:130        if self.used or other.used:
129            raise TypeError("Potion is now part of something bigger than itself.")131            raise TypeError("Potion is now part of something bigger than itself.")
n130        n132 
131        sum_self = sum(self.intensity.values())133        sum_self = sum(self.intensity.values())
132        sum_other = sum(other.intensity.values())134        sum_other = sum(other.intensity.values())
133        return sum_self < sum_other135        return sum_self < sum_other
n134    n136 
135    def apply_effect(self, target, effect):137    def apply_effect(self, target, effect):
136        if self.used:138        if self.used:
137            raise TypeError("Potion is now part of something bigger than itself.")139            raise TypeError("Potion is now part of something bigger than itself.")
138        if self.used_effects[effect]:140        if self.used_effects[effect]:
139            raise TypeError("Effect is depleted.")141            raise TypeError("Effect is depleted.")
n140        for _ in range(int(self.intensity[effect])): n142        for _ in range(int(self.intensity[effect])):
141            self.effects[effect](target)143            self.effects[effect](target)
142        self.used_effects[effect] = True144        self.used_effects[effect] = True
nn145 
143146
144class ГоспожатаПоХимия:147class ГоспожатаПоХимия:
145148
146    def __init__(self):149    def __init__(self):
147        self.tick_count = 0150        self.tick_count = 0
148        self.active_potions = {}151        self.active_potions = {}
149        self.initial_states = {}152        self.initial_states = {}
150153
151    def apply(self, target, potion):154    def apply(self, target, potion):
152        if potion.used:155        if potion.used:
153            raise TypeError("Potion is depleted.")156            raise TypeError("Potion is depleted.")
n154        n157 
155        initial_state = copy.deepcopy(target)158        initial_state = copy.deepcopy(target)
156159
n157        sorted_by_molecular_mass = sorted(potion.intensity.items(), key=lambda x: sum(ord(c) for c in x[0]), reverse=True)n160        sorted_by_molecular_mass = sorted(potion.intensity.items(),
161                                          key=lambda x: sum(ord(c) for c in x[0]), reverse=True)
158        for effect in sorted_by_molecular_mass:162        for effect in sorted_by_molecular_mass:
159            for _ in range(int(effect[1])):163            for _ in range(int(effect[1])):
160                potion.apply_effect(target, effect[0])164                potion.apply_effect(target, effect[0])
161                potion.start_duration = self.tick_count165                potion.start_duration = self.tick_count
162                potion.end_duration = self.tick_count + potion.duration166                potion.end_duration = self.tick_count + potion.duration
n163        n167 
164        """168        """
165        if self.active_potions[id(target)]:169        if self.active_potions[id(target)]:
166            self.active_potions[id(target)] = potion170            self.active_potions[id(target)] = potion
167            self.initial_states[id(target)] = initial_state, target171            self.initial_states[id(target)] = initial_state, target
168        """172        """
n169        n173 
170    
171    def tick(self):174    def tick(self):
n172        #collect all applied (potions : target) in a list and subtract their potion.active variables every tickn175        #collect all applied (potions : target) in a list and subtract
176        #their potion.active variables every tick
173        #if a potion expires return to initial state of target177        #if a potion expires return to initial state of target
174        self.tick_count += 1178        self.tick_count += 1
175179
n176        expired_potions = {target_id:potion for target_id, potion in self.active_potions.items() n180        expired_potions = {target_id:potion for target_id, potion in self.active_potions.items()
177                           if potion.end_duration <= self.tick_count}181                           if potion.end_duration <= self.tick_count}
178182
t179        t
180        sorted_by_start_time = sorted(expired_potions.items(), key=lambda x: x[1].start_duration)183        sorted_by_start_time = sorted(expired_potions.items(), key=lambda x: x[1].start_duration)
181        """184        """
182        for target_id, potion in sorted_by_start_time:185        for target_id, potion in sorted_by_start_time:
183            if potion.end_duration <= self.tick_count:186            if potion.end_duration <= self.tick_count:
184187
185            self.active_potions.pop()188            self.active_potions.pop()
186            initial_state, target = self.initial_states.pop(target_id)189            initial_state, target = self.initial_states.pop(target_id)
187            self.reset_target_to_initial_state(target, initial_state)190            self.reset_target_to_initial_state(target, initial_state)
188        """191        """
189192
190    def reset_target_to_initial_state(self, target, initial_state):193    def reset_target_to_initial_state(self, target, initial_state):
191        target.__dict__.update(initial_state.__dict__)194        target.__dict__.update(initial_state.__dict__)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op