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

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

7 точки общо

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

  1import math
  2
  3class Potion:
  4    def __init__(self, effects, duration):
  5        self.duration = duration
  6        self.effects = effects
  7        for effect in effects:
  8            setattr(self, effect, effects[effect])
  9        self.intensity = {effect : 1 for effect in effects}
 10        self.used_effects = []
 11        self.used = False
 12    
 13    def __intensify(self, effect):
 14        def effect_with_intensity(target):
 15            if self.used:
 16                raise TypeError('Potion is now part of something bigger than itself.')
 17            if effect in self.used_effects:
 18                raise TypeError('Effect is depleted.')
 19            self.used_effects.append(effect)
 20            for _ in range(self.intensity[effect]):
 21                self.effects[effect](target)
 22        return effect_with_intensity
 23    
 24    def __getattribute__(self, name):
 25        if name in object.__getattribute__(self, 'effects'):
 26            return self.__intensify(name)
 27        return object.__getattribute__(self, name)
 28        
 29    def __add__(self, other):
 30        self.used = True
 31        other.used = True
 32        combined_potion_effects = dict(self.effects)
 33        combined_potion_intensity = dict(self.intensity)
 34        for effect in other.effects:
 35            if effect not in combined_potion_effects:
 36                combined_potion_effects[effect] = other.effects[effect]
 37                combined_potion_intensity[effect] = other.intensity[effect]
 38            else:
 39                combined_potion_intensity[effect] += other.intensity[effect]
 40        combined_potion_duration = max(self.duration, other.duration)
 41        combined_potion = Potion(combined_potion_effects, combined_potion_duration)
 42        combined_potion.intensity = combined_potion_intensity
 43        return combined_potion
 44    
 45    def __mul__(self, other):
 46        self.used = True
 47        potentiated_potion = Potion(dict(self.effects), self.duration)
 48        potentiated_potion.intensity = dict(self.intensity)
 49        for effect in potentiated_potion.effects:
 50            effect_intensity = potentiated_potion.intensity[effect]
 51            effect_intensity *= other
 52            potentiated_potion.intensity[effect] = math.floor(effect_intensity) if effect_intensity - int(effect_intensity) <= 0.5 else math.ceil(effect_intensity)
 53        return potentiated_potion
 54    
 55    def __sub__(self, other):
 56        self.used = True
 57        other.used = True
 58        purified_potion = Potion(dict(self.effects), self.duration)
 59        purified_potion.intensity = dict(self.intensity)
 60        for effect in other.effects:
 61            if effect not in purified_potion.effects:
 62                raise TypeError('(╯°□°)╯︵ ┻━┻')
 63            if purified_potion.intensity[effect] > other.intensity[effect]:
 64                purified_potion.intensity[effect] -= other.intensity[effect]
 65            else:
 66                delattr(purified_potion, effect)
 67                del purified_potion.effects[effect]
 68                del purified_potion.intensity[effect]
 69        return purified_potion
 70    
 71    def __truediv__(self, other):
 72        self.used = True
 73        return tuple(self * (1 / other) for _ in range(other))
 74
 75    def __eq__(self, other):
 76        return self.effects == other.effects and self.intensity == other.intensity
 77    
 78    def __lt__(self, other):
 79        return sum(self.intensity.values()) < sum(other.intensity.values())
 80    
 81    def __gt__(self, other):
 82        return other < self and self != other
 83    
 84class ГоспожатаПоХимия:
 85    def __init__(self):
 86        self.applied_potions = []
 87        self.applied_potions_to_targets = {}
 88        self.targets_initial_state = {}
 89    
 90    def apply(self, target, potion):
 91        if potion in self.applied_potions or potion.used:
 92            raise TypeError('Potion is depleted.') # TODO
 93        self.applied_potions.append(potion)
 94        if target in self.applied_potions_to_targets:
 95            self.applied_potions_to_targets[target].append([potion, 0])
 96        else :
 97            self.applied_potions_to_targets[target] = [[potion, 0]]
 98            self.targets_initial_state[target] = dict(target.__dict__)
 99        effects_to_apply = []
100        for effect in potion.effects:
101            if effect not in potion.used_effects:
102                effects_to_apply.append(effect)
103        effects_to_apply.sort(key = lambda name : sum(ord(ch) for ch in name))
104        for effect in effects_to_apply:
105            potion.effects[effect](target)
106        potion.used = True # idk
107    
108    def tick(self):
109        effect_wore_off = False
110        for target in self.applied_potions_to_targets:
111            for potions in self.applied_potions_to_targets[target]:
112                potions[1] += 1
113                if(potions[1] >= potions[0].duration):
114                    self.applied_potions_to_targets[target].remove(potions)
115                    effect_wore_off = True
116        if effect_wore_off:
117            for target in self.applied_potions_to_targets:
118                target.__dict__ = dict(self.targets_initial_state[target])
119                for potions in self.applied_potions_to_targets[target]:
120                    potion = potions[0]
121                    potion.used = False
122                    self.applied_potions.remove(potion)
123                    self.apply(target, potion)

............F.F.FEFF
======================================================================
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 455, in test_ticking_multiple_potions
self._dimitrichka.apply(self._target, potion2)
File "/tmp/solution.py", line 92, in apply
raise TypeError('Potion is depleted.') # TODO
TypeError: Potion is depleted.

======================================================================
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 382, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
AssertionError: TypeError not raised

======================================================================
FAIL: test_applying_order (test.TestГоспожатаПоХимия)
Test applying order of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 405, in test_applying_order
self.assertEqual(self._target.int_attr, 12)
AssertionError: 14 != 12

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

======================================================================
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 446, in test_ticking_mutable
self.assertEqual(self._target.list_attr, [1, 2, 3])
AssertionError: Lists differ: [1, 2, 3, 4] != [1, 2, 3]

First list contains 1 additional elements.
First extra element 3:
4

- [1, 2, 3, 4]
? ---

+ [1, 2, 3]

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

FAILED (failures=5, errors=1)

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

Честно казано стилистично нямам какво да коментирам (сигурно бих могъл ако задълбая, но на този етап ще е излишно). П.П. На места ми е тромав и тежък за четене, което обаче вероятно е по-скоро функция на логиката, отколкото на стила.
История
Това решение има само една версия.