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

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

4 точки общо

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

  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 по-горе - нямам забележки по стила.
История
Това решение има само една версия.