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

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

4 точки общо

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

  1class Potion:
  2
  3    def __init__(self, effects, duration) :
  4        self.effects = effects
  5        self.duration = duration
  6        self.intensity_of_effects = {effect: 1 for effect in self.effects}  
  7        self.used = False
  8        self.chemical_mix = False
  9
 10    def __add__(self, other):
 11        self.check_and_raise_error()
 12        other.check_and_raise_error()
 13
 14        combined_effects = dict(self.effects)
 15        for effect_name, effect_function in other.effects.items():
 16            if effect_name in combined_effects:
 17                combined_effects[effect_name] = lambda target: (
 18                self.effects[effect_name](target),
 19                effect_function(target)
 20                )
 21            else:
 22                combined_effects[effect_name] = effect_function
 23        result_duration = max(self.duration, other.duration)
 24        result_potion = Potion(combined_effects, result_duration)
 25        result_potion.intensity_of_effects = {
 26            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)
 27            for effect_name in combined_effects}
 28        self.used = True
 29        self.chemical_mix = True
 30        other.used = True
 31        self.chemical_mix = True
 32        return result_potion
 33
 34    def __sub__(self, other):
 35        if not set(other.effects.keys()).issubset(self.effects.keys()):
 36            raise TypeError("Cannot subtract potion with different effects.")
 37        self.check_and_raise_error()
 38        other.check_and_raise_error()
 39
 40        result_potion = Potion(dict(self.effects), self.duration)
 41        for effect_name, intensity in other.intensity_of_effects.items():
 42            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \
 43                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \
 44                else result_potion.intensity_of_effects.pop(effect_name, None)
 45        return result_potion
 46    
 47    def __mul__(self, factor):
 48        if not isinstance(factor, int) or factor <= 0:
 49            raise ValueError("Factor must be a positive integer.")
 50        self.check_and_raise_error()
 51
 52        result_potion = Potion(dict(self.effects), self.duration)
 53        result_potion.intensity_of_effects = {
 54            effect_name: round(intensity * factor) if factor < 1 else intensity * factor
 55            for effect_name, intensity in self.intensity_of_effects.items()
 56        }
 57        return result_potion
 58
 59    def __truediv__(self, divisor):
 60        if not isinstance(divisor, int) or divisor <= 0:
 61            raise ValueError("Divisor must be a positive integer.")
 62        self.check_and_raise_error()
 63        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]
 64        for effect_name, intensity in self.intensity_of_effects.items():
 65            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 1
 66            for result_potion in result_potions:
 67                result_potion.intensity_of_effects[effect_name] = divided_intensity
 68        return tuple(result_potions)
 69
 70    def __getattr__(self, name):
 71        if self.used:
 72            raise TypeError("Potion is now part of something bigger than itself.")
 73
 74        if name in self.effects:
 75            return lambda target: self.apply_effect(name, target)
 76        else:
 77            raise AttributeError(f"'Potion' object has no attribute '{name}'.")
 78
 79    def __eq__(self, other):
 80        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects
 81
 82    def __lt__(self, other):
 83        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())
 84
 85    def __gt__(self, other):
 86        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())
 87    
 88    def _check_effects(self):
 89        if self.used is False:
 90            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)
 91    
 92    def check_and_raise_error(self):
 93        if self.chemical_mix:
 94            raise TypeError("Potion is now part of something bigger than itself.")
 95        self._check_effects()
 96        if self.used:
 97            raise TypeError("Potion is depleted.")  
 98        
 99    def apply_effect(self, effect_name, target):
100        self.check_and_raise_error()
101
102        if effect_name not in self.effects:
103            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")
104
105        if self.intensity_of_effects[effect_name] == 0:
106            raise TypeError("Effect is depleted.")
107
108        self.effects[effect_name](target)
109        self.intensity_of_effects[effect_name] -= 1
110        
111
112class ГоспожатаПоХимия:
113
114    def __init__(self):
115        self.tick_count = 0
116
117    def apply(self, target, potion):
118        potion.check_and_raise_error()
119
120        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 
121        for effect_name in effects_sorted:
122            try:
123                potion.apply_effect(effect_name, target)
124            except TypeError: # in order to aplly all effects
125                continue
126        potion.used = True
127
128    def tick(self):
129        self.tick_count += 1
130
131    def reset_tick(self):
132        self.tick_count = 0

.F.F...FEFFFF...FFFF
======================================================================
ERROR: test_dilution (test.TestPotionOperations)
Test dilution of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 118, in test_dilution
half_potion = base_potion * 0.5
File "/tmp/solution.py", line 49, in __mul__
raise ValueError("Factor must be a positive integer.")
ValueError: Factor must be a positive integer.

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

During handling of the above exception, another exception occurred:

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

======================================================================
FAIL: test_equal (test.TestPotionComparison)
Test equality of potions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 298, in test_equal
self.assertEqual(potion4, potion3)
AssertionError: <solution.Potion object at 0x7f6d09306fb0> != <solution.Potion object at 0x7f6d09307010>

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

======================================================================
FAIL: test_potentiation (test.TestPotionOperations)
Test potentiation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 112, in test_potentiation
self.assertEqual(self._target.int_attr, 5 * (10 ** 3))
AssertionError: 50 != 5000

======================================================================
FAIL: test_purification (test.TestPotionOperations)
Test purification of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 168, in test_purification
with self.assertRaises(AttributeError):
AssertionError: AttributeError not raised

======================================================================
FAIL: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 215, in test_separation
self.assertEqual(self._target.int_attr, 5 * (10 ** 3))
AssertionError: 50 != 5000

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

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

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

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

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

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

FAILED (failures=11, errors=1)

Дискусия
Виктор Бечев
08.12.2023 14:09

Единственото нещо, което ми бърка в очите е разделянето на стейтмънти с \. Бих използвал или някакви променливи или ако се налага - можеш да ограждаш със скоби: ``` (statement_which_is_very_long_number_one() and x < y) ```
История

t1class Potion:t1class Potion:
22
3    def __init__(self, effects, duration) :3    def __init__(self, effects, duration) :
4        self.effects = effects4        self.effects = effects
5        self.duration = duration5        self.duration = duration
6        self.intensity_of_effects = {effect: 1 for effect in self.effects}  6        self.intensity_of_effects = {effect: 1 for effect in self.effects}  
7        self.used = False7        self.used = False
8        self.chemical_mix = False8        self.chemical_mix = False
99
10    def __add__(self, other):10    def __add__(self, other):
11        self.check_and_raise_error()11        self.check_and_raise_error()
12        other.check_and_raise_error()12        other.check_and_raise_error()
1313
14        combined_effects = dict(self.effects)14        combined_effects = dict(self.effects)
15        for effect_name, effect_function in other.effects.items():15        for effect_name, effect_function in other.effects.items():
16            if effect_name in combined_effects:16            if effect_name in combined_effects:
17                combined_effects[effect_name] = lambda target: (17                combined_effects[effect_name] = lambda target: (
18                self.effects[effect_name](target),18                self.effects[effect_name](target),
19                effect_function(target)19                effect_function(target)
20                )20                )
21            else:21            else:
22                combined_effects[effect_name] = effect_function22                combined_effects[effect_name] = effect_function
23        result_duration = max(self.duration, other.duration)23        result_duration = max(self.duration, other.duration)
24        result_potion = Potion(combined_effects, result_duration)24        result_potion = Potion(combined_effects, result_duration)
25        result_potion.intensity_of_effects = {25        result_potion.intensity_of_effects = {
26            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)26            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)
27            for effect_name in combined_effects}27            for effect_name in combined_effects}
28        self.used = True28        self.used = True
29        self.chemical_mix = True29        self.chemical_mix = True
30        other.used = True30        other.used = True
31        self.chemical_mix = True31        self.chemical_mix = True
32        return result_potion32        return result_potion
3333
34    def __sub__(self, other):34    def __sub__(self, other):
35        if not set(other.effects.keys()).issubset(self.effects.keys()):35        if not set(other.effects.keys()).issubset(self.effects.keys()):
36            raise TypeError("Cannot subtract potion with different effects.")36            raise TypeError("Cannot subtract potion with different effects.")
37        self.check_and_raise_error()37        self.check_and_raise_error()
38        other.check_and_raise_error()38        other.check_and_raise_error()
3939
40        result_potion = Potion(dict(self.effects), self.duration)40        result_potion = Potion(dict(self.effects), self.duration)
41        for effect_name, intensity in other.intensity_of_effects.items():41        for effect_name, intensity in other.intensity_of_effects.items():
42            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \42            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \
43                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \43                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \
44                else result_potion.intensity_of_effects.pop(effect_name, None)44                else result_potion.intensity_of_effects.pop(effect_name, None)
45        return result_potion45        return result_potion
46    46    
47    def __mul__(self, factor):47    def __mul__(self, factor):
48        if not isinstance(factor, int) or factor <= 0:48        if not isinstance(factor, int) or factor <= 0:
49            raise ValueError("Factor must be a positive integer.")49            raise ValueError("Factor must be a positive integer.")
50        self.check_and_raise_error()50        self.check_and_raise_error()
5151
52        result_potion = Potion(dict(self.effects), self.duration)52        result_potion = Potion(dict(self.effects), self.duration)
53        result_potion.intensity_of_effects = {53        result_potion.intensity_of_effects = {
54            effect_name: round(intensity * factor) if factor < 1 else intensity * factor54            effect_name: round(intensity * factor) if factor < 1 else intensity * factor
55            for effect_name, intensity in self.intensity_of_effects.items()55            for effect_name, intensity in self.intensity_of_effects.items()
56        }56        }
57        return result_potion57        return result_potion
5858
59    def __truediv__(self, divisor):59    def __truediv__(self, divisor):
60        if not isinstance(divisor, int) or divisor <= 0:60        if not isinstance(divisor, int) or divisor <= 0:
61            raise ValueError("Divisor must be a positive integer.")61            raise ValueError("Divisor must be a positive integer.")
62        self.check_and_raise_error()62        self.check_and_raise_error()
63        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]63        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]
64        for effect_name, intensity in self.intensity_of_effects.items():64        for effect_name, intensity in self.intensity_of_effects.items():
65            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 165            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 1
66            for result_potion in result_potions:66            for result_potion in result_potions:
67                result_potion.intensity_of_effects[effect_name] = divided_intensity67                result_potion.intensity_of_effects[effect_name] = divided_intensity
68        return tuple(result_potions)68        return tuple(result_potions)
6969
70    def __getattr__(self, name):70    def __getattr__(self, name):
71        if self.used:71        if self.used:
72            raise TypeError("Potion is now part of something bigger than itself.")72            raise TypeError("Potion is now part of something bigger than itself.")
7373
74        if name in self.effects:74        if name in self.effects:
75            return lambda target: self.apply_effect(name, target)75            return lambda target: self.apply_effect(name, target)
76        else:76        else:
77            raise AttributeError(f"'Potion' object has no attribute '{name}'.")77            raise AttributeError(f"'Potion' object has no attribute '{name}'.")
7878
79    def __eq__(self, other):79    def __eq__(self, other):
80        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects80        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects
8181
82    def __lt__(self, other):82    def __lt__(self, other):
83        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())83        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())
8484
85    def __gt__(self, other):85    def __gt__(self, other):
86        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())86        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())
87    87    
88    def _check_effects(self):88    def _check_effects(self):
89        if self.used is False:89        if self.used is False:
90            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)90            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)
91    91    
92    def check_and_raise_error(self):92    def check_and_raise_error(self):
93        if self.chemical_mix:93        if self.chemical_mix:
94            raise TypeError("Potion is now part of something bigger than itself.")94            raise TypeError("Potion is now part of something bigger than itself.")
95        self._check_effects()95        self._check_effects()
96        if self.used:96        if self.used:
97            raise TypeError("Potion is depleted.")  97            raise TypeError("Potion is depleted.")  
98        98        
99    def apply_effect(self, effect_name, target):99    def apply_effect(self, effect_name, target):
100        self.check_and_raise_error()100        self.check_and_raise_error()
101101
102        if effect_name not in self.effects:102        if effect_name not in self.effects:
103            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")103            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")
104104
105        if self.intensity_of_effects[effect_name] == 0:105        if self.intensity_of_effects[effect_name] == 0:
106            raise TypeError("Effect is depleted.")106            raise TypeError("Effect is depleted.")
107107
108        self.effects[effect_name](target)108        self.effects[effect_name](target)
109        self.intensity_of_effects[effect_name] -= 1109        self.intensity_of_effects[effect_name] -= 1
110        110        
111111
112class ГоспожатаПоХимия:112class ГоспожатаПоХимия:
113113
114    def __init__(self):114    def __init__(self):
115        self.tick_count = 0115        self.tick_count = 0
116116
117    def apply(self, target, potion):117    def apply(self, target, potion):
118        potion.check_and_raise_error()118        potion.check_and_raise_error()
119119
120        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 120        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 
121        for effect_name in effects_sorted:121        for effect_name in effects_sorted:
122            try:122            try:
123                potion.apply_effect(effect_name, target)123                potion.apply_effect(effect_name, target)
124            except TypeError: # in order to aplly all effects124            except TypeError: # in order to aplly all effects
125                continue125                continue
126        potion.used = True126        potion.used = True
127127
128    def tick(self):128    def tick(self):
129        self.tick_count += 1129        self.tick_count += 1
130130
131    def reset_tick(self):131    def reset_tick(self):
132        self.tick_count = 0132        self.tick_count = 0
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Potion:f1class Potion:
nn2 
2    def __init__(self, effects, duration) :3    def __init__(self, effects, duration) :
3        self.effects = effects4        self.effects = effects
4        self.duration = duration5        self.duration = duration
5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  6        self.intensity_of_effects = {effect: 1 for effect in self.effects}  
6        self.used = False7        self.used = False
7        self.chemical_mix = False8        self.chemical_mix = False
89
9    def __add__(self, other):10    def __add__(self, other):
10        self.check_and_raise_error()11        self.check_and_raise_error()
11        other.check_and_raise_error()12        other.check_and_raise_error()
1213
13        combined_effects = dict(self.effects)14        combined_effects = dict(self.effects)
14        for effect_name, effect_function in other.effects.items():15        for effect_name, effect_function in other.effects.items():
15            if effect_name in combined_effects:16            if effect_name in combined_effects:
16                combined_effects[effect_name] = lambda target: (17                combined_effects[effect_name] = lambda target: (
17                self.effects[effect_name](target),18                self.effects[effect_name](target),
n18                effect_function(target))n19                effect_function(target)
20                )
19            else:21            else:
20                combined_effects[effect_name] = effect_function22                combined_effects[effect_name] = effect_function
21        result_duration = max(self.duration, other.duration)23        result_duration = max(self.duration, other.duration)
22        result_potion = Potion(combined_effects, result_duration)24        result_potion = Potion(combined_effects, result_duration)
23        result_potion.intensity_of_effects = {25        result_potion.intensity_of_effects = {
24            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)26            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)
25            for effect_name in combined_effects}27            for effect_name in combined_effects}
26        self.used = True28        self.used = True
27        self.chemical_mix = True29        self.chemical_mix = True
28        other.used = True30        other.used = True
29        self.chemical_mix = True31        self.chemical_mix = True
30        return result_potion32        return result_potion
3133
32    def __sub__(self, other):34    def __sub__(self, other):
33        if not set(other.effects.keys()).issubset(self.effects.keys()):35        if not set(other.effects.keys()).issubset(self.effects.keys()):
34            raise TypeError("Cannot subtract potion with different effects.")36            raise TypeError("Cannot subtract potion with different effects.")
35        self.check_and_raise_error()37        self.check_and_raise_error()
36        other.check_and_raise_error()38        other.check_and_raise_error()
3739
38        result_potion = Potion(dict(self.effects), self.duration)40        result_potion = Potion(dict(self.effects), self.duration)
39        for effect_name, intensity in other.intensity_of_effects.items():41        for effect_name, intensity in other.intensity_of_effects.items():
40            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \42            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \
41                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \43                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \
42                else result_potion.intensity_of_effects.pop(effect_name, None)44                else result_potion.intensity_of_effects.pop(effect_name, None)
43        return result_potion45        return result_potion
44    46    
45    def __mul__(self, factor):47    def __mul__(self, factor):
46        if not isinstance(factor, int) or factor <= 0:48        if not isinstance(factor, int) or factor <= 0:
47            raise ValueError("Factor must be a positive integer.")49            raise ValueError("Factor must be a positive integer.")
48        self.check_and_raise_error()50        self.check_and_raise_error()
4951
50        result_potion = Potion(dict(self.effects), self.duration)52        result_potion = Potion(dict(self.effects), self.duration)
51        result_potion.intensity_of_effects = {53        result_potion.intensity_of_effects = {
52            effect_name: round(intensity * factor) if factor < 1 else intensity * factor54            effect_name: round(intensity * factor) if factor < 1 else intensity * factor
53            for effect_name, intensity in self.intensity_of_effects.items()55            for effect_name, intensity in self.intensity_of_effects.items()
54        }56        }
55        return result_potion57        return result_potion
5658
57    def __truediv__(self, divisor):59    def __truediv__(self, divisor):
58        if not isinstance(divisor, int) or divisor <= 0:60        if not isinstance(divisor, int) or divisor <= 0:
59            raise ValueError("Divisor must be a positive integer.")61            raise ValueError("Divisor must be a positive integer.")
60        self.check_and_raise_error()62        self.check_and_raise_error()
61        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]63        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]
62        for effect_name, intensity in self.intensity_of_effects.items():64        for effect_name, intensity in self.intensity_of_effects.items():
63            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 165            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 1
64            for result_potion in result_potions:66            for result_potion in result_potions:
65                result_potion.intensity_of_effects[effect_name] = divided_intensity67                result_potion.intensity_of_effects[effect_name] = divided_intensity
66        return tuple(result_potions)68        return tuple(result_potions)
6769
68    def __getattr__(self, name):70    def __getattr__(self, name):
69        if self.used:71        if self.used:
70            raise TypeError("Potion is now part of something bigger than itself.")72            raise TypeError("Potion is now part of something bigger than itself.")
7173
72        if name in self.effects:74        if name in self.effects:
73            return lambda target: self.apply_effect(name, target)75            return lambda target: self.apply_effect(name, target)
74        else:76        else:
75            raise AttributeError(f"'Potion' object has no attribute '{name}'.")77            raise AttributeError(f"'Potion' object has no attribute '{name}'.")
7678
77    def __eq__(self, other):79    def __eq__(self, other):
78        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects80        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects
7981
80    def __lt__(self, other):82    def __lt__(self, other):
81        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())83        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())
8284
83    def __gt__(self, other):85    def __gt__(self, other):
84        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())86        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())
85    87    
86    def _check_effects(self):88    def _check_effects(self):
87        if self.used is False:89        if self.used is False:
88            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)90            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)
89    91    
90    def check_and_raise_error(self):92    def check_and_raise_error(self):
91        if self.chemical_mix:93        if self.chemical_mix:
92            raise TypeError("Potion is now part of something bigger than itself.")94            raise TypeError("Potion is now part of something bigger than itself.")
93        self._check_effects()95        self._check_effects()
94        if self.used:96        if self.used:
95            raise TypeError("Potion is depleted.")  97            raise TypeError("Potion is depleted.")  
96        98        
97    def apply_effect(self, effect_name, target):99    def apply_effect(self, effect_name, target):
98        self.check_and_raise_error()100        self.check_and_raise_error()
n99        n101 
100        if effect_name not in self.effects:102        if effect_name not in self.effects:
101            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")103            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")
102104
103        if self.intensity_of_effects[effect_name] == 0:105        if self.intensity_of_effects[effect_name] == 0:
104            raise TypeError("Effect is depleted.")106            raise TypeError("Effect is depleted.")
105107
106        self.effects[effect_name](target)108        self.effects[effect_name](target)
107        self.intensity_of_effects[effect_name] -= 1109        self.intensity_of_effects[effect_name] -= 1
108        110        
109111
110class ГоспожатаПоХимия:112class ГоспожатаПоХимия:
tt113 
111    def __init__(self):114    def __init__(self):
112        self.tick_count = 0115        self.tick_count = 0
113116
114    def apply(self, target, potion):117    def apply(self, target, potion):
115        potion.check_and_raise_error()118        potion.check_and_raise_error()
116119
117        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 120        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 
118        for effect_name in effects_sorted:121        for effect_name in effects_sorted:
119            try:122            try:
120                potion.apply_effect(effect_name, target)123                potion.apply_effect(effect_name, target)
121            except TypeError: # in order to aplly all effects124            except TypeError: # in order to aplly all effects
122                continue125                continue
123        potion.used = True126        potion.used = True
124127
125    def tick(self):128    def tick(self):
126        self.tick_count += 1129        self.tick_count += 1
127130
128    def reset_tick(self):131    def reset_tick(self):
129        self.tick_count = 0132        self.tick_count = 0
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Potion:f1class Potion:
2    def __init__(self, effects, duration) :2    def __init__(self, effects, duration) :
3        self.effects = effects3        self.effects = effects
4        self.duration = duration4        self.duration = duration
5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  
6        self.used = False6        self.used = False
7        self.chemical_mix = False7        self.chemical_mix = False
88
9    def __add__(self, other):9    def __add__(self, other):
10        self.check_and_raise_error()10        self.check_and_raise_error()
11        other.check_and_raise_error()11        other.check_and_raise_error()
1212
13        combined_effects = dict(self.effects)13        combined_effects = dict(self.effects)
14        for effect_name, effect_function in other.effects.items():14        for effect_name, effect_function in other.effects.items():
15            if effect_name in combined_effects:15            if effect_name in combined_effects:
16                combined_effects[effect_name] = lambda target: (16                combined_effects[effect_name] = lambda target: (
17                self.effects[effect_name](target),17                self.effects[effect_name](target),
18                effect_function(target))18                effect_function(target))
19            else:19            else:
20                combined_effects[effect_name] = effect_function20                combined_effects[effect_name] = effect_function
21        result_duration = max(self.duration, other.duration)21        result_duration = max(self.duration, other.duration)
22        result_potion = Potion(combined_effects, result_duration)22        result_potion = Potion(combined_effects, result_duration)
23        result_potion.intensity_of_effects = {23        result_potion.intensity_of_effects = {
24            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)24            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)
n25            for effect_name in combined_effectsn25            for effect_name in combined_effects}
26        }
27        self.used = True26        self.used = True
28        self.chemical_mix = True27        self.chemical_mix = True
29        other.used = True28        other.used = True
30        self.chemical_mix = True29        self.chemical_mix = True
31        return result_potion30        return result_potion
3231
33    def __sub__(self, other):32    def __sub__(self, other):
34        if not set(other.effects.keys()).issubset(self.effects.keys()):33        if not set(other.effects.keys()).issubset(self.effects.keys()):
35            raise TypeError("Cannot subtract potion with different effects.")34            raise TypeError("Cannot subtract potion with different effects.")
36        self.check_and_raise_error()35        self.check_and_raise_error()
37        other.check_and_raise_error()36        other.check_and_raise_error()
3837
39        result_potion = Potion(dict(self.effects), self.duration)38        result_potion = Potion(dict(self.effects), self.duration)
40        for effect_name, intensity in other.intensity_of_effects.items():39        for effect_name, intensity in other.intensity_of_effects.items():
41            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \40            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \
42                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \41                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \
43                else result_potion.intensity_of_effects.pop(effect_name, None)42                else result_potion.intensity_of_effects.pop(effect_name, None)
44        return result_potion43        return result_potion
45    44    
46    def __mul__(self, factor):45    def __mul__(self, factor):
47        if not isinstance(factor, int) or factor <= 0:46        if not isinstance(factor, int) or factor <= 0:
48            raise ValueError("Factor must be a positive integer.")47            raise ValueError("Factor must be a positive integer.")
49        self.check_and_raise_error()48        self.check_and_raise_error()
n50        n49 
51        result_potion = Potion(dict(self.effects), self.duration)50        result_potion = Potion(dict(self.effects), self.duration)
52        result_potion.intensity_of_effects = {51        result_potion.intensity_of_effects = {
53            effect_name: round(intensity * factor) if factor < 1 else intensity * factor52            effect_name: round(intensity * factor) if factor < 1 else intensity * factor
54            for effect_name, intensity in self.intensity_of_effects.items()53            for effect_name, intensity in self.intensity_of_effects.items()
55        }54        }
56        return result_potion55        return result_potion
5756
58    def __truediv__(self, divisor):57    def __truediv__(self, divisor):
59        if not isinstance(divisor, int) or divisor <= 0:58        if not isinstance(divisor, int) or divisor <= 0:
60            raise ValueError("Divisor must be a positive integer.")59            raise ValueError("Divisor must be a positive integer.")
61        self.check_and_raise_error()60        self.check_and_raise_error()
62        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]61        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]
63        for effect_name, intensity in self.intensity_of_effects.items():62        for effect_name, intensity in self.intensity_of_effects.items():
64            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 163            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 1
65            for result_potion in result_potions:64            for result_potion in result_potions:
66                result_potion.intensity_of_effects[effect_name] = divided_intensity65                result_potion.intensity_of_effects[effect_name] = divided_intensity
67        return tuple(result_potions)66        return tuple(result_potions)
6867
69    def __getattr__(self, name):68    def __getattr__(self, name):
70        if self.used:69        if self.used:
71            raise TypeError("Potion is now part of something bigger than itself.")70            raise TypeError("Potion is now part of something bigger than itself.")
7271
73        if name in self.effects:72        if name in self.effects:
74            return lambda target: self.apply_effect(name, target)73            return lambda target: self.apply_effect(name, target)
75        else:74        else:
76            raise AttributeError(f"'Potion' object has no attribute '{name}'.")75            raise AttributeError(f"'Potion' object has no attribute '{name}'.")
7776
78    def __eq__(self, other):77    def __eq__(self, other):
79        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects78        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects
8079
81    def __lt__(self, other):80    def __lt__(self, other):
82        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())81        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())
8382
84    def __gt__(self, other):83    def __gt__(self, other):
85        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())84        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())
86    85    
87    def _check_effects(self):86    def _check_effects(self):
88        if self.used is False:87        if self.used is False:
89            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)88            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)
90    89    
91    def check_and_raise_error(self):90    def check_and_raise_error(self):
92        if self.chemical_mix:91        if self.chemical_mix:
93            raise TypeError("Potion is now part of something bigger than itself.")92            raise TypeError("Potion is now part of something bigger than itself.")
94        self._check_effects()93        self._check_effects()
95        if self.used:94        if self.used:
n96            raise TypeError("Potion is depleted.")n95            raise TypeError("Potion is depleted.")  
97        
98    def apply(self, target):
99        self.check_and_raise_error()
100        for effect_name, effect_function in self.effects.items():
101            effect_function(target)
102        self.used = True   
103        96        
104    def apply_effect(self, effect_name, target):97    def apply_effect(self, effect_name, target):
nn98        self.check_and_raise_error()
99        
105        if effect_name not in self.effects:100        if effect_name not in self.effects:
106            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")101            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")
107102
108        if self.intensity_of_effects[effect_name] == 0:103        if self.intensity_of_effects[effect_name] == 0:
109            raise TypeError("Effect is depleted.")104            raise TypeError("Effect is depleted.")
110105
111        self.effects[effect_name](target)106        self.effects[effect_name](target)
112        self.intensity_of_effects[effect_name] -= 1107        self.intensity_of_effects[effect_name] -= 1
113        108        
114109
115class ГоспожатаПоХимия:110class ГоспожатаПоХимия:
116    def __init__(self):111    def __init__(self):
117        self.tick_count = 0112        self.tick_count = 0
118113
119    def apply(self, target, potion):114    def apply(self, target, potion):
120        potion.check_and_raise_error()115        potion.check_and_raise_error()
121116
122        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 117        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 
123        for effect_name in effects_sorted:118        for effect_name in effects_sorted:
tt119            try:
124            potion.apply_effect(effect_name, target)120                potion.apply_effect(effect_name, target)
121            except TypeError: # in order to aplly all effects
122                continue
125        potion.used = True123        potion.used = True
126124
127    def tick(self):125    def tick(self):
128        self.tick_count += 1126        self.tick_count += 1
129127
130    def reset_tick(self):128    def reset_tick(self):
131        self.tick_count = 0129        self.tick_count = 0
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Potion:f1class Potion:
2    def __init__(self, effects, duration) :2    def __init__(self, effects, duration) :
3        self.effects = effects3        self.effects = effects
4        self.duration = duration4        self.duration = duration
5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  
6        self.used = False6        self.used = False
7        self.chemical_mix = False7        self.chemical_mix = False
88
9    def __add__(self, other):9    def __add__(self, other):
10        self.check_and_raise_error()10        self.check_and_raise_error()
11        other.check_and_raise_error()11        other.check_and_raise_error()
nn12 
12        combined_effects = dict(self.effects)13        combined_effects = dict(self.effects)
n13 n
14        for effect_name, effect_function in other.effects.items():14        for effect_name, effect_function in other.effects.items():
15            if effect_name in combined_effects:15            if effect_name in combined_effects:
16                combined_effects[effect_name] = lambda target: (16                combined_effects[effect_name] = lambda target: (
17                self.effects[effect_name](target),17                self.effects[effect_name](target),
18                effect_function(target))18                effect_function(target))
19            else:19            else:
20                combined_effects[effect_name] = effect_function20                combined_effects[effect_name] = effect_function
21        result_duration = max(self.duration, other.duration)21        result_duration = max(self.duration, other.duration)
22        result_potion = Potion(combined_effects, result_duration)22        result_potion = Potion(combined_effects, result_duration)
23        result_potion.intensity_of_effects = {23        result_potion.intensity_of_effects = {
24            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)24            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)
25            for effect_name in combined_effects25            for effect_name in combined_effects
26        }26        }
27        self.used = True27        self.used = True
28        self.chemical_mix = True28        self.chemical_mix = True
29        other.used = True29        other.used = True
30        self.chemical_mix = True30        self.chemical_mix = True
31        return result_potion31        return result_potion
3232
33    def __sub__(self, other):33    def __sub__(self, other):
34        if not set(other.effects.keys()).issubset(self.effects.keys()):34        if not set(other.effects.keys()).issubset(self.effects.keys()):
35            raise TypeError("Cannot subtract potion with different effects.")35            raise TypeError("Cannot subtract potion with different effects.")
36        self.check_and_raise_error()36        self.check_and_raise_error()
37        other.check_and_raise_error()37        other.check_and_raise_error()
nn38 
38        result_potion = Potion(dict(self.effects), self.duration)39        result_potion = Potion(dict(self.effects), self.duration)
39        for effect_name, intensity in other.intensity_of_effects.items():40        for effect_name, intensity in other.intensity_of_effects.items():
40            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \41            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \
41                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \42                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \
42                else result_potion.intensity_of_effects.pop(effect_name, None)43                else result_potion.intensity_of_effects.pop(effect_name, None)
43        return result_potion44        return result_potion
44    45    
45    def __mul__(self, factor):46    def __mul__(self, factor):
46        if not isinstance(factor, int) or factor <= 0:47        if not isinstance(factor, int) or factor <= 0:
47            raise ValueError("Factor must be a positive integer.")48            raise ValueError("Factor must be a positive integer.")
48        self.check_and_raise_error()49        self.check_and_raise_error()
tt50        
49        result_potion = Potion(dict(self.effects), self.duration)51        result_potion = Potion(dict(self.effects), self.duration)
50        result_potion.intensity_of_effects = {52        result_potion.intensity_of_effects = {
51            effect_name: round(intensity * factor) if factor < 1 else intensity * factor53            effect_name: round(intensity * factor) if factor < 1 else intensity * factor
52            for effect_name, intensity in self.intensity_of_effects.items()54            for effect_name, intensity in self.intensity_of_effects.items()
53        }55        }
54        return result_potion56        return result_potion
5557
56    def __truediv__(self, divisor):58    def __truediv__(self, divisor):
57        if not isinstance(divisor, int) or divisor <= 0:59        if not isinstance(divisor, int) or divisor <= 0:
58            raise ValueError("Divisor must be a positive integer.")60            raise ValueError("Divisor must be a positive integer.")
59        self.check_and_raise_error()61        self.check_and_raise_error()
60        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]62        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]
61        for effect_name, intensity in self.intensity_of_effects.items():63        for effect_name, intensity in self.intensity_of_effects.items():
62            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 164            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 1
63            for result_potion in result_potions:65            for result_potion in result_potions:
64                result_potion.intensity_of_effects[effect_name] = divided_intensity66                result_potion.intensity_of_effects[effect_name] = divided_intensity
65        return tuple(result_potions)67        return tuple(result_potions)
6668
67    def __getattr__(self, name):69    def __getattr__(self, name):
68        if self.used:70        if self.used:
69            raise TypeError("Potion is now part of something bigger than itself.")71            raise TypeError("Potion is now part of something bigger than itself.")
7072
71        if name in self.effects:73        if name in self.effects:
72            return lambda target: self.apply_effect(name, target)74            return lambda target: self.apply_effect(name, target)
73        else:75        else:
74            raise AttributeError(f"'Potion' object has no attribute '{name}'.")76            raise AttributeError(f"'Potion' object has no attribute '{name}'.")
7577
76    def __eq__(self, other):78    def __eq__(self, other):
77        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects79        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects
7880
79    def __lt__(self, other):81    def __lt__(self, other):
80        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())82        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())
8183
82    def __gt__(self, other):84    def __gt__(self, other):
83        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())85        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())
84    86    
85    def _check_effects(self):87    def _check_effects(self):
86        if self.used is False:88        if self.used is False:
87            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)89            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)
88    90    
89    def check_and_raise_error(self):91    def check_and_raise_error(self):
90        if self.chemical_mix:92        if self.chemical_mix:
91            raise TypeError("Potion is now part of something bigger than itself.")93            raise TypeError("Potion is now part of something bigger than itself.")
92        self._check_effects()94        self._check_effects()
93        if self.used:95        if self.used:
94            raise TypeError("Potion is depleted.")96            raise TypeError("Potion is depleted.")
95        97        
96    def apply(self, target):98    def apply(self, target):
97        self.check_and_raise_error()99        self.check_and_raise_error()
98        for effect_name, effect_function in self.effects.items():100        for effect_name, effect_function in self.effects.items():
99            effect_function(target)101            effect_function(target)
100        self.used = True   102        self.used = True   
101        103        
102    def apply_effect(self, effect_name, target):104    def apply_effect(self, effect_name, target):
103        if effect_name not in self.effects:105        if effect_name not in self.effects:
104            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")106            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")
105107
106        if self.intensity_of_effects[effect_name] == 0:108        if self.intensity_of_effects[effect_name] == 0:
107            raise TypeError("Effect is depleted.")109            raise TypeError("Effect is depleted.")
108110
109        self.effects[effect_name](target)111        self.effects[effect_name](target)
110        self.intensity_of_effects[effect_name] -= 1112        self.intensity_of_effects[effect_name] -= 1
111        113        
112114
113class ГоспожатаПоХимия:115class ГоспожатаПоХимия:
114    def __init__(self):116    def __init__(self):
115        self.tick_count = 0117        self.tick_count = 0
116118
117    def apply(self, target, potion):119    def apply(self, target, potion):
118        potion.check_and_raise_error()120        potion.check_and_raise_error()
119121
120        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 122        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 
121        for effect_name in effects_sorted:123        for effect_name in effects_sorted:
122            potion.apply_effect(effect_name, target)124            potion.apply_effect(effect_name, target)
123        potion.used = True125        potion.used = True
124126
125    def tick(self):127    def tick(self):
126        self.tick_count += 1128        self.tick_count += 1
127129
128    def reset_tick(self):130    def reset_tick(self):
129        self.tick_count = 0131        self.tick_count = 0
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Potion:f1class Potion:
2    def __init__(self, effects, duration) :2    def __init__(self, effects, duration) :
3        self.effects = effects3        self.effects = effects
4        self.duration = duration4        self.duration = duration
5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  5        self.intensity_of_effects = {effect: 1 for effect in self.effects}  
6        self.used = False6        self.used = False
7        self.chemical_mix = False7        self.chemical_mix = False
88
9    def __add__(self, other):9    def __add__(self, other):
10        self.check_and_raise_error()10        self.check_and_raise_error()
11        other.check_and_raise_error()11        other.check_and_raise_error()
t12        if self.chemical_mix or other._chemical_mix:t
13            raise TypeError("Potion is now part of something bigger than itself.")
14        if self.used or other.used: # if potion is mixed then it is used as well
15            raise TypeError("Potion is depleted.")
16        combined_effects = dict(self.effects)12        combined_effects = dict(self.effects)
1713
18        for effect_name, effect_function in other.effects.items():14        for effect_name, effect_function in other.effects.items():
19            if effect_name in combined_effects:15            if effect_name in combined_effects:
20                combined_effects[effect_name] = lambda target: (16                combined_effects[effect_name] = lambda target: (
21                self.effects[effect_name](target),17                self.effects[effect_name](target),
22                effect_function(target))18                effect_function(target))
23            else:19            else:
24                combined_effects[effect_name] = effect_function20                combined_effects[effect_name] = effect_function
25        result_duration = max(self.duration, other.duration)21        result_duration = max(self.duration, other.duration)
26        result_potion = Potion(combined_effects, result_duration)22        result_potion = Potion(combined_effects, result_duration)
27        result_potion.intensity_of_effects = {23        result_potion.intensity_of_effects = {
28            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)24            effect_name: self.intensity_of_effects.get(effect_name, 0) + other.intensity_of_effects.get(effect_name, 0)
29            for effect_name in combined_effects25            for effect_name in combined_effects
30        }26        }
31        self.used = True27        self.used = True
32        self.chemical_mix = True28        self.chemical_mix = True
33        other.used = True29        other.used = True
34        self.chemical_mix = True30        self.chemical_mix = True
35        return result_potion31        return result_potion
3632
37    def __sub__(self, other):33    def __sub__(self, other):
38        if not set(other.effects.keys()).issubset(self.effects.keys()):34        if not set(other.effects.keys()).issubset(self.effects.keys()):
39            raise TypeError("Cannot subtract potion with different effects.")35            raise TypeError("Cannot subtract potion with different effects.")
40        self.check_and_raise_error()36        self.check_and_raise_error()
41        other.check_and_raise_error()37        other.check_and_raise_error()
42        result_potion = Potion(dict(self.effects), self.duration)38        result_potion = Potion(dict(self.effects), self.duration)
43        for effect_name, intensity in other.intensity_of_effects.items():39        for effect_name, intensity in other.intensity_of_effects.items():
44            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \40            result_potion.intensity_of_effects[effect_name] = result_potion.intensity_of_effects[effect_name] - intensity \
45                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \41                if (result_potion.intensity_of_effects[effect_name] - intensity) > 0 \
46                else result_potion.intensity_of_effects.pop(effect_name, None)42                else result_potion.intensity_of_effects.pop(effect_name, None)
47        return result_potion43        return result_potion
48    44    
49    def __mul__(self, factor):45    def __mul__(self, factor):
50        if not isinstance(factor, int) or factor <= 0:46        if not isinstance(factor, int) or factor <= 0:
51            raise ValueError("Factor must be a positive integer.")47            raise ValueError("Factor must be a positive integer.")
52        self.check_and_raise_error()48        self.check_and_raise_error()
53        result_potion = Potion(dict(self.effects), self.duration)49        result_potion = Potion(dict(self.effects), self.duration)
54        result_potion.intensity_of_effects = {50        result_potion.intensity_of_effects = {
55            effect_name: round(intensity * factor) if factor < 1 else intensity * factor51            effect_name: round(intensity * factor) if factor < 1 else intensity * factor
56            for effect_name, intensity in self.intensity_of_effects.items()52            for effect_name, intensity in self.intensity_of_effects.items()
57        }53        }
58        return result_potion54        return result_potion
5955
60    def __truediv__(self, divisor):56    def __truediv__(self, divisor):
61        if not isinstance(divisor, int) or divisor <= 0:57        if not isinstance(divisor, int) or divisor <= 0:
62            raise ValueError("Divisor must be a positive integer.")58            raise ValueError("Divisor must be a positive integer.")
63        self.check_and_raise_error()59        self.check_and_raise_error()
64        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]60        result_potions = [Potion(dict(self.effects), self.duration) for _ in range(divisor)]
65        for effect_name, intensity in self.intensity_of_effects.items():61        for effect_name, intensity in self.intensity_of_effects.items():
66            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 162            divided_intensity = int(intensity / divisor) if intensity % divisor <= 0.5 else int(intensity / divisor) + 1
67            for result_potion in result_potions:63            for result_potion in result_potions:
68                result_potion.intensity_of_effects[effect_name] = divided_intensity64                result_potion.intensity_of_effects[effect_name] = divided_intensity
69        return tuple(result_potions)65        return tuple(result_potions)
7066
71    def __getattr__(self, name):67    def __getattr__(self, name):
72        if self.used:68        if self.used:
73            raise TypeError("Potion is now part of something bigger than itself.")69            raise TypeError("Potion is now part of something bigger than itself.")
7470
75        if name in self.effects:71        if name in self.effects:
76            return lambda target: self.apply_effect(name, target)72            return lambda target: self.apply_effect(name, target)
77        else:73        else:
78            raise AttributeError(f"'Potion' object has no attribute '{name}'.")74            raise AttributeError(f"'Potion' object has no attribute '{name}'.")
7975
80    def __eq__(self, other):76    def __eq__(self, other):
81        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects77        return self.effects == other.effects and self.intensity_of_effects == other.intensity_of_effects
8278
83    def __lt__(self, other):79    def __lt__(self, other):
84        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())80        return sum(self.intensity_of_effects.values()) < sum(other.intensity_of_effects.values())
8581
86    def __gt__(self, other):82    def __gt__(self, other):
87        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())83        return sum(self.intensity_of_effects.values()) > sum(other.intensity_of_effects.values())
88    84    
89    def _check_effects(self):85    def _check_effects(self):
90        if self.used is False:86        if self.used is False:
91            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)87            self.used = all(self.intensity_of_effects[effect_name] == 0 for effect_name in self.effects)
92    88    
93    def check_and_raise_error(self):89    def check_and_raise_error(self):
94        if self.chemical_mix:90        if self.chemical_mix:
95            raise TypeError("Potion is now part of something bigger than itself.")91            raise TypeError("Potion is now part of something bigger than itself.")
96        self._check_effects()92        self._check_effects()
97        if self.used:93        if self.used:
98            raise TypeError("Potion is depleted.")94            raise TypeError("Potion is depleted.")
99        95        
100    def apply(self, target):96    def apply(self, target):
101        self.check_and_raise_error()97        self.check_and_raise_error()
102        for effect_name, effect_function in self.effects.items():98        for effect_name, effect_function in self.effects.items():
103            effect_function(target)99            effect_function(target)
104        self.used = True   100        self.used = True   
105        101        
106    def apply_effect(self, effect_name, target):102    def apply_effect(self, effect_name, target):
107        if effect_name not in self.effects:103        if effect_name not in self.effects:
108            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")104            raise ValueError(f"Effect '{effect_name}' not found in potion effects.")
109105
110        if self.intensity_of_effects[effect_name] == 0:106        if self.intensity_of_effects[effect_name] == 0:
111            raise TypeError("Effect is depleted.")107            raise TypeError("Effect is depleted.")
112108
113        self.effects[effect_name](target)109        self.effects[effect_name](target)
114        self.intensity_of_effects[effect_name] -= 1110        self.intensity_of_effects[effect_name] -= 1
115        111        
116112
117class ГоспожатаПоХимия:113class ГоспожатаПоХимия:
118    def __init__(self):114    def __init__(self):
119        self.tick_count = 0115        self.tick_count = 0
120116
121    def apply(self, target, potion):117    def apply(self, target, potion):
122        potion.check_and_raise_error()118        potion.check_and_raise_error()
123119
124        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 120        effects_sorted = sorted(potion.effects.keys(), key=lambda effect: sum(map(ord, effect)), reverse=True) 
125        for effect_name in effects_sorted:121        for effect_name in effects_sorted:
126            potion.apply_effect(effect_name, target)122            potion.apply_effect(effect_name, target)
127        potion.used = True123        potion.used = True
128124
129    def tick(self):125    def tick(self):
130        self.tick_count += 1126        self.tick_count += 1
131127
132    def reset_tick(self):128    def reset_tick(self):
133        self.tick_count = 0129        self.tick_count = 0
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op