1import math
2
3class Potion:
4
5 def __init__(self, effects, duration):
6 self.effects = effects
7 self.duration = duration
8 self.effects_intensity = dict.fromkeys(effects, 1)
9 self.applied_effects = set()
10 self.potion_is_applied = False
11
12 def apply(self, target):
13 self.__check_if_potion_is_applied()
14 self.potion_is_applied = True
15 sorted_effects = sorted(self.effects.items(), key=lambda item: sum(ord(char) for char in item[0]), reverse=True)
16 for effect in sorted_effects:
17 if effect not in self.applied_effects:
18 self.effects[effect](target)
19
20 def __check_if_potion_is_applied(self):
21 if self.potion_is_applied or len(self.applied_effects) == len(self.effects):
22 raise TypeError("Potion is now part of something bigger than itself.")
23
24
25 def __run_with_intensity(self, effect_to_run, intensity):
26 def run(target):
27 for i in range(intensity):
28 effect_to_run(target)
29 return run
30
31 def __getattr__(self, effect):
32 self.__check_if_potion_is_applied()
33
34 if effect in self.effects:
35 if effect in self.applied_effects:
36 raise TypeError("Effect is depleted.")
37 self.applied_effects.add(effect)
38 return self.__run_with_intensity(self.effects[effect], self.effects_intensity[effect])
39 raise AttributeError("No such effect.")
40
41 def copy_potion(self):
42 potion = Potion(self.effects, self.duration)
43 potion.effects_intensity = self.effects_intensity
44 potion.applied_effects = self.applied_effects
45 potion.potion_is_applied = False
46 return potion
47
48 def __add__(self, other):
49 self.__check_if_potion_is_applied()
50 self.potion_is_applied = True
51
52 for effect in other.effects:
53 if effect in self.effects:
54 self.effects_intensity[effect] += other.effects_intensity[effect]
55 else:
56 self.effects[effect] = other.effects[effect]
57 self.effects_intensity[effect] = other.effects_intensity[effect]
58
59 self.duration = max(self.duration, other.duration)
60
61 return self.copy_potion()
62
63 def __mul__(self, factor):
64 self.__check_if_potion_is_applied()
65 self.potion_is_applied = True
66
67 if factor > 1 and isinstance(factor, int):
68 for effect in self.effects_intensity:
69 self.effects_intensity[effect] *= factor
70 elif factor >= 0 and factor < 1:
71 for effect in self.effects_intensity:
72 intensity = self.effects_intensity[effect] * factor
73 intensity_int = int(intensity)
74 if intensity - intensity_int > 0.5:
75 intensity = math.ceil(intensity)
76 else:
77 intensity = math.floor(intensity)
78 self.effects_intensity[effect] = intensity
79
80 return self.copy_potion()
81
82 def __truediv__(self, divisor):
83 self.__check_if_potion_is_applied()
84 self.potion_is_applied = True
85
86 list_of_potion = []
87 for effect in self.effects:
88 intensity = self.effects_intensity[effect] / divisor
89 intensity_int = int(intensity)
90 if intensity - intensity_int > 0.5:
91 intensity = math.ceil(intensity)
92 else:
93 intensity = math.floor(intensity)
94 self.effects_intensity[effect] = intensity
95
96 for i in range(divisor):
97 list_of_potion.append(self)
98 return list_of_potion
99
100 def __sub__(self, other):
101 self.__check_if_potion_is_applied()
102 self.potion_is_applied = True
103 to_remove = []
104 for effect in self.effects:
105 if effect not in other.effects:
106 raise TypeError("There is no effect with that name in the left side potion")
107 else:
108 if self.effects_intensity[effect] < other.effects_intensity[effect]:
109 to_remove.append(effect)
110 else:
111 self.effects_intensity[effect] -= other.effects_intensity[effect]
112
113 for effect in to_remove:
114 self.effects.pop(effect)
115 self.effects_intensity.pop(effect)
116
117 self.duration = other.duration
118 return self.copy_potion()
119
120
121 def __eq__(self, other):
122 if len(self.effects) != len(other.effects):
123 return False
124
125 for effect, intensity in self.effects_intensity.items():
126 if effect not in other.effects_intensity or intensity != other.effects_intensity[effect]:
127 return False
128 return True
129
130 def __gt__(self, other):
131 return sum(self.effects_intensity.values()) > sum(other.effects_intensity.values())
132
133 def __lt__(self, other):
134 return other > self
135
136class ГоспожатаПоХимия:
137 def __init__(self):
138 self.applied_potions = set()
139
140 def apply(self, target, potion):
141 if potion in self.applied_potions:
142 raise TypeError("Potion is depleted.")
143 potion.apply(target)
144 self.applied_potions.add(potion)
145
146 def tick(self):
147 pass
.F.....F..EEEEEEEEEE
======================================================================
ERROR: test_purification (test.TestPotionOperations)
Test purification of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 165, in test_purification
potion = potion1 - potion2
File "/tmp/solution.py", line 106, in __sub__
raise TypeError("There is no effect with that name in the left side potion")
TypeError: There is no effect with that name in the left side potion
======================================================================
ERROR: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 214, in test_separation
potion1.int_attr_fun(self._target)
File "/tmp/solution.py", line 32, in __getattr__
self.__check_if_potion_is_applied()
File "/tmp/solution.py", line 22, in __check_if_potion_is_applied
raise TypeError("Potion is now part of something bigger than itself.")
TypeError: Potion is now part of something bigger than itself.
======================================================================
ERROR: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 379, in test_applying_depleted_potion
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
ERROR: test_applying_normal_case (test.TestГоспожатаПоХимия)
Test applying a normal potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 350, in test_applying_normal_case
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
ERROR: test_applying_order (test.TestГоспожатаПоХимия)
Test applying order of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 404, in test_applying_order
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
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 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
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 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
ERROR: test_ticking_multiple_potions (test.TestГоспожатаПоХимия)
Test ticking after applying multiple potions which affect the same attribute.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 454, in test_ticking_multiple_potions
self._dimitrichka.apply(self._target, potion1)
File "/tmp/solution.py", line 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
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 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
ERROR: test_ticking_mutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 438, in test_ticking_mutable
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 141, in apply
if potion in self.applied_potions:
TypeError: unhashable type: 'Potion'
======================================================================
FAIL: test_depletion (test.TestBasicPotion)
Test depletion of a potion effect.
----------------------------------------------------------------------
TypeError: Potion is now part of something bigger than itself.
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 now part of something bigger than itself."
======================================================================
FAIL: test_deprecation (test.TestPotionOperations)
Test deprecation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 259, in test_deprecation
with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
AssertionError: TypeError not raised
----------------------------------------------------------------------
Ran 20 tests in 0.002s
FAILED (failures=2, errors=10)
Виктор Бечев
05.12.2023 16:52Отвъд дребния hint по-горе - нямам забележки по стила.
|
05.12.2023 16:48