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

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

5 точки общо

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

  1import functools
  2from copy import deepcopy
  3
  4
  5class Potion:
  6
  7    def __init__(self, effects, duration):
  8        self.effects = effects
  9        self.duration = duration
 10        #self.__dict__.update(effects)
 11        self.effects_intensity = {}
 12        for effect in effects:
 13            self.effects_intensity[effect] = 1
 14        for effect_name, effect_func in self.effects.items():
 15            self.__dict__[effect_name] = self.__effects_decorator(effect_name, effect_func)
 16        self.is_used = False
 17    
 18    def __effects_decorator(self, effect_name, effect_func):
 19        def composed_effect(target):
 20            if self.effects_intensity[effect_name] == 0:
 21                raise TypeError ("Effect is depleted.")
 22            while self.effects_intensity[effect_name] != 0:
 23                self.effects_intensity[effect_name] -= 1
 24                effect_func(target)
 25        return composed_effect
 26
 27    @staticmethod
 28    def __potion_result(effects, effects_intensity, duration):
 29        result = Potion(effects, duration)
 30        result.effects_intensity = effects_intensity
 31        return result
 32        
 33    def __add__(self, other):
 34        if self.is_used:
 35             raise TypeError("Potion is now part of something bigger than itself.")
 36        resultring_effects = dict(self.effects)
 37        resultring_effects_intensity = dict(self.effects_intensity)
 38        for effect in other.effects_intensity:
 39            if effect in resultring_effects_intensity:
 40                resultring_effects_intensity[effect] += other.effects_intensity[effect]
 41            else:
 42                resultring_effects[effect] = other.effects[effect]
 43                resultring_effects_intensity[effect] = 1
 44        self.is_used = True
 45        return Potion.__potion_result(resultring_effects, resultring_effects_intensity, max(self.duration, other.duration))
 46    
 47    def __mul__(self, value):
 48        if self.is_used:
 49             raise TypeError("Potion is now part of something bigger than itself.")
 50        resulting_effects_intensity = dict(self.effects_intensity)
 51        for effect in resulting_effects_intensity:
 52            resulting_effects_intensity[effect] = int(resulting_effects_intensity[effect] * value)
 53        self.is_used = True
 54        return Potion.__potion_result(dict(self.effects), resulting_effects_intensity, self.duration) 
 55
 56    def __sub__(self, other):
 57        if self.is_used:
 58             raise TypeError("Potion is now part of something bigger than itself.")
 59        if not all(map(lambda x : x in self.effects , other.effects)):
 60            raise TypeError
 61        resulting_effects = dict(self.effects)
 62        resulting_effects_intensity = dict(self.effects_intensity)
 63        for effect in other.effects:
 64            if resulting_effects_intensity[effect] > other.effects_intensity[effect]:
 65                resulting_effects_intensity[effect] -= other.effects_intensity[effect]
 66            else:
 67                resulting_effects.pop(effect)
 68                resulting_effects_intensity.pop(effect)
 69        self.is_used = True
 70        return Potion.__potion_result(resulting_effects, resulting_effects_intensity, self.duration)
 71    
 72    def __truediv__(self, value):
 73        if self.is_used:
 74             raise TypeError("Potion is now part of something bigger than itself.")
 75        resulting_effects = dict(self.effects)
 76        resulting_effects_intensity = dict(self.effects_intensity)
 77        for effect in resulting_effects_intensity:
 78            resulting_effects_intensity[effect] //= value
 79        result = ()
 80        for _ in range(value):
 81            result += (Potion.__potion_result(resulting_effects, resulting_effects_intensity, self.duration), )
 82        self.is_used = True
 83        return result
 84    
 85    def __eq__(self, other):
 86        return self.effects_intensity == other.effects_intensity
 87    
 88    def __lt__(self, other):
 89        res_self = functools.reduce(lambda a, b : a + self.effects_intensity[b], self.effects_intensity, 0)
 90        res_other = functools.reduce(lambda a, b : a + other.effects_intensity[b], other.effects_intensity, 0)
 91        print(res_self)
 92        print(res_other)
 93        return res_self < res_other
 94    
 95    def __gt__(self, other):
 96        res_self = functools.reduce(lambda a, b : a + self.effects_intensity[b], self.effects_intensity, 0)
 97        res_other = functools.reduce(lambda a, b : a + other.effects_intensity[b], other.effects_intensity, 0)
 98        print(self.effects_intensity)
 99        print(other.effects_intensity)
100        print(res_self)
101        print(res_other)
102        return res_self > res_other
103    
104    def apply(self, target):
105        if not self.is_used:
106            for effect in self.effects:
107                self.is_used = True
108                self.__dict__[effect](target)
109        else:
110            raise TypeError("Potion is now part of something bigger than itself.")
111    
112    def apply_for_consistancy(self, target):
113        if not self.is_used:
114            for effect in self.effects:
115                self.__dict__[effect](target)
116        else:
117            raise TypeError("Potion is now part of something bigger than itself.")
118
119
120class ГоспожатаПоХимия:
121
122    def __init__(self):
123        self.time = 0
124        self.reverser = []
125    
126    def apply(self, target, potion):
127        try:
128            self.reverser.append([potion.duration + self.time, target, deepcopy(target)])
129            for change in self.reverser:
130                if change[1] == target and change[0] < potion.duration + self.time:
131                    potion.apply_for_consistancy(change[2])
132            potion.apply(target)
133        except TypeError:
134            raise TypeError("Potion is depleted.")
135        
136    def tick(self):
137        self.time += 1
138        for change in self.reverser:
139            if self.time == change[0]:
140                change[1] = change[2]

.......FE..EF.FEFEFF
======================================================================
ERROR: test_dilution (test.TestPotionOperations)
Test dilution of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 119, in test_dilution
half_potion.int_attr_fun(self._target)
File "/tmp/solution.py", line 21, in composed_effect
raise TypeError ("Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
ERROR: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 218, in test_separation
potion2.int_attr_fun(self._target)
File "/tmp/solution.py", line 21, in composed_effect
raise TypeError ("Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
ERROR: test_applying_part_of_potion (test.TestГоспожатаПоХимия)
Test applying only a part of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/solution.py", line 132, in apply
potion.apply(target)
File "/tmp/solution.py", line 108, in apply
self.__dict__[effect](target)
File "/tmp/solution.py", line 21, in composed_effect
raise TypeError ("Effect is depleted.")
TypeError: Effect is depleted.

During handling of the above exception, another exception occurred:

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 134, in apply
raise TypeError("Potion is depleted.")
TypeError: Potion is depleted.

======================================================================
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/solution.py", line 132, in apply
potion.apply(target)
File "/tmp/solution.py", line 108, in apply
self.__dict__[effect](target)
File "/tmp/solution.py", line 21, in composed_effect
raise TypeError ("Effect is depleted.")
TypeError: Effect is depleted.

During handling of the above exception, another exception occurred:

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 134, in apply
raise TypeError("Potion is depleted.")
TypeError: Potion is depleted.

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

======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
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 382, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
AssertionError: "Potion is depleted\." does not match "Potion is now part of something bigger than itself."

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

======================================================================
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 490, in test_ticking_multiple_targets
self.assertEqual(target1.int_attr, 5)
AssertionError: 500 != 5

======================================================================
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=6, errors=4)

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

f1import functoolsf1import functools
2from copy import deepcopy2from copy import deepcopy
33
44
5class Potion:5class Potion:
66
7    def __init__(self, effects, duration):7    def __init__(self, effects, duration):
8        self.effects = effects8        self.effects = effects
9        self.duration = duration9        self.duration = duration
10        #self.__dict__.update(effects)10        #self.__dict__.update(effects)
11        self.effects_intensity = {}11        self.effects_intensity = {}
12        for effect in effects:12        for effect in effects:
13            self.effects_intensity[effect] = 113            self.effects_intensity[effect] = 1
14        for effect_name, effect_func in self.effects.items():14        for effect_name, effect_func in self.effects.items():
15            self.__dict__[effect_name] = self.__effects_decorator(effect_name, effect_func)15            self.__dict__[effect_name] = self.__effects_decorator(effect_name, effect_func)
16        self.is_used = False16        self.is_used = False
17    17    
18    def __effects_decorator(self, effect_name, effect_func):18    def __effects_decorator(self, effect_name, effect_func):
19        def composed_effect(target):19        def composed_effect(target):
20            if self.effects_intensity[effect_name] == 0:20            if self.effects_intensity[effect_name] == 0:
21                raise TypeError ("Effect is depleted.")21                raise TypeError ("Effect is depleted.")
22            while self.effects_intensity[effect_name] != 0:22            while self.effects_intensity[effect_name] != 0:
23                self.effects_intensity[effect_name] -= 123                self.effects_intensity[effect_name] -= 1
24                effect_func(target)24                effect_func(target)
25        return composed_effect25        return composed_effect
2626
27    @staticmethod27    @staticmethod
28    def __potion_result(effects, effects_intensity, duration):28    def __potion_result(effects, effects_intensity, duration):
29        result = Potion(effects, duration)29        result = Potion(effects, duration)
30        result.effects_intensity = effects_intensity30        result.effects_intensity = effects_intensity
31        return result31        return result
32        32        
33    def __add__(self, other):33    def __add__(self, other):
34        if self.is_used:34        if self.is_used:
35             raise TypeError("Potion is now part of something bigger than itself.")35             raise TypeError("Potion is now part of something bigger than itself.")
36        resultring_effects = dict(self.effects)36        resultring_effects = dict(self.effects)
37        resultring_effects_intensity = dict(self.effects_intensity)37        resultring_effects_intensity = dict(self.effects_intensity)
38        for effect in other.effects_intensity:38        for effect in other.effects_intensity:
39            if effect in resultring_effects_intensity:39            if effect in resultring_effects_intensity:
40                resultring_effects_intensity[effect] += other.effects_intensity[effect]40                resultring_effects_intensity[effect] += other.effects_intensity[effect]
41            else:41            else:
42                resultring_effects[effect] = other.effects[effect]42                resultring_effects[effect] = other.effects[effect]
43                resultring_effects_intensity[effect] = 143                resultring_effects_intensity[effect] = 1
44        self.is_used = True44        self.is_used = True
45        return Potion.__potion_result(resultring_effects, resultring_effects_intensity, max(self.duration, other.duration))45        return Potion.__potion_result(resultring_effects, resultring_effects_intensity, max(self.duration, other.duration))
46    46    
47    def __mul__(self, value):47    def __mul__(self, value):
48        if self.is_used:48        if self.is_used:
49             raise TypeError("Potion is now part of something bigger than itself.")49             raise TypeError("Potion is now part of something bigger than itself.")
50        resulting_effects_intensity = dict(self.effects_intensity)50        resulting_effects_intensity = dict(self.effects_intensity)
51        for effect in resulting_effects_intensity:51        for effect in resulting_effects_intensity:
n52            resulting_effects_intensity[effect] =int(resulting_effects_intensity[effect] * value)n52            resulting_effects_intensity[effect] = int(resulting_effects_intensity[effect] * value)
53        self.is_used = True53        self.is_used = True
54        return Potion.__potion_result(dict(self.effects), resulting_effects_intensity, self.duration) 54        return Potion.__potion_result(dict(self.effects), resulting_effects_intensity, self.duration) 
5555
56    def __sub__(self, other):56    def __sub__(self, other):
57        if self.is_used:57        if self.is_used:
58             raise TypeError("Potion is now part of something bigger than itself.")58             raise TypeError("Potion is now part of something bigger than itself.")
59        if not all(map(lambda x : x in self.effects , other.effects)):59        if not all(map(lambda x : x in self.effects , other.effects)):
60            raise TypeError60            raise TypeError
61        resulting_effects = dict(self.effects)61        resulting_effects = dict(self.effects)
62        resulting_effects_intensity = dict(self.effects_intensity)62        resulting_effects_intensity = dict(self.effects_intensity)
63        for effect in other.effects:63        for effect in other.effects:
64            if resulting_effects_intensity[effect] > other.effects_intensity[effect]:64            if resulting_effects_intensity[effect] > other.effects_intensity[effect]:
65                resulting_effects_intensity[effect] -= other.effects_intensity[effect]65                resulting_effects_intensity[effect] -= other.effects_intensity[effect]
66            else:66            else:
67                resulting_effects.pop(effect)67                resulting_effects.pop(effect)
68                resulting_effects_intensity.pop(effect)68                resulting_effects_intensity.pop(effect)
69        self.is_used = True69        self.is_used = True
70        return Potion.__potion_result(resulting_effects, resulting_effects_intensity, self.duration)70        return Potion.__potion_result(resulting_effects, resulting_effects_intensity, self.duration)
71    71    
72    def __truediv__(self, value):72    def __truediv__(self, value):
73        if self.is_used:73        if self.is_used:
74             raise TypeError("Potion is now part of something bigger than itself.")74             raise TypeError("Potion is now part of something bigger than itself.")
75        resulting_effects = dict(self.effects)75        resulting_effects = dict(self.effects)
76        resulting_effects_intensity = dict(self.effects_intensity)76        resulting_effects_intensity = dict(self.effects_intensity)
77        for effect in resulting_effects_intensity:77        for effect in resulting_effects_intensity:
78            resulting_effects_intensity[effect] //= value78            resulting_effects_intensity[effect] //= value
79        result = ()79        result = ()
80        for _ in range(value):80        for _ in range(value):
81            result += (Potion.__potion_result(resulting_effects, resulting_effects_intensity, self.duration), )81            result += (Potion.__potion_result(resulting_effects, resulting_effects_intensity, self.duration), )
82        self.is_used = True82        self.is_used = True
83        return result83        return result
84    84    
85    def __eq__(self, other):85    def __eq__(self, other):
86        return self.effects_intensity == other.effects_intensity86        return self.effects_intensity == other.effects_intensity
87    87    
88    def __lt__(self, other):88    def __lt__(self, other):
89        res_self = functools.reduce(lambda a, b : a + self.effects_intensity[b], self.effects_intensity, 0)89        res_self = functools.reduce(lambda a, b : a + self.effects_intensity[b], self.effects_intensity, 0)
90        res_other = functools.reduce(lambda a, b : a + other.effects_intensity[b], other.effects_intensity, 0)90        res_other = functools.reduce(lambda a, b : a + other.effects_intensity[b], other.effects_intensity, 0)
91        print(res_self)91        print(res_self)
92        print(res_other)92        print(res_other)
93        return res_self < res_other93        return res_self < res_other
94    94    
95    def __gt__(self, other):95    def __gt__(self, other):
96        res_self = functools.reduce(lambda a, b : a + self.effects_intensity[b], self.effects_intensity, 0)96        res_self = functools.reduce(lambda a, b : a + self.effects_intensity[b], self.effects_intensity, 0)
97        res_other = functools.reduce(lambda a, b : a + other.effects_intensity[b], other.effects_intensity, 0)97        res_other = functools.reduce(lambda a, b : a + other.effects_intensity[b], other.effects_intensity, 0)
98        print(self.effects_intensity)98        print(self.effects_intensity)
99        print(other.effects_intensity)99        print(other.effects_intensity)
100        print(res_self)100        print(res_self)
101        print(res_other)101        print(res_other)
102        return res_self > res_other102        return res_self > res_other
103    103    
104    def apply(self, target):104    def apply(self, target):
105        if not self.is_used:105        if not self.is_used:
106            for effect in self.effects:106            for effect in self.effects:
107                self.is_used = True107                self.is_used = True
108                self.__dict__[effect](target)108                self.__dict__[effect](target)
109        else:109        else:
110            raise TypeError("Potion is now part of something bigger than itself.")110            raise TypeError("Potion is now part of something bigger than itself.")
111    111    
112    def apply_for_consistancy(self, target):112    def apply_for_consistancy(self, target):
113        if not self.is_used:113        if not self.is_used:
114            for effect in self.effects:114            for effect in self.effects:
115                self.__dict__[effect](target)115                self.__dict__[effect](target)
116        else:116        else:
117            raise TypeError("Potion is now part of something bigger than itself.")117            raise TypeError("Potion is now part of something bigger than itself.")
118118
119119
120class ГоспожатаПоХимия:120class ГоспожатаПоХимия:
121121
t122    def __init__(self) -> None:t122    def __init__(self):
123        self.time=0123        self.time = 0
124        self.reverser = []124        self.reverser = []
125    125    
126    def apply(self, target, potion):126    def apply(self, target, potion):
127        try:127        try:
128            self.reverser.append([potion.duration + self.time, target, deepcopy(target)])128            self.reverser.append([potion.duration + self.time, target, deepcopy(target)])
129            for change in self.reverser:129            for change in self.reverser:
130                if change[1] == target and change[0] < potion.duration + self.time:130                if change[1] == target and change[0] < potion.duration + self.time:
131                    potion.apply_for_consistancy(change[2])131                    potion.apply_for_consistancy(change[2])
132            potion.apply(target)132            potion.apply(target)
133        except TypeError:133        except TypeError:
134            raise TypeError("Potion is depleted.")134            raise TypeError("Potion is depleted.")
135        135        
136    def tick(self):136    def tick(self):
137        self.time += 1137        self.time += 1
138        for change in self.reverser:138        for change in self.reverser:
139            if self.time == change[0]:139            if self.time == change[0]:
140                change[1] = change[2]140                change[1] = change[2]
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op