Домашни > Работилница за отвари! > Решения > Решението на Михаела Илиева

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

5 точки общо

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

  1class Effect:
  2
  3    def __init__(self, name, function):
  4        self.name = name
  5        self.function = function
  6        self.intensity = 1
  7
  8    def __call__(self, argument_of_function):
  9        if self.intensity == 0:
 10            raise TypeError("Effect is depleted.")
 11        else:
 12            for _ in range(self.intensity):
 13                self.function(argument_of_function)
 14
 15
 16class Potion:
 17
 18    def __init__(self, effects, duration):
 19        self.effects = dict()
 20        self.duration = duration
 21        self.is_potion_used = False
 22        for name, function in effects.items():
 23            if name in self.effects.keys():
 24                self.effects[name].intensity += 1
 25            else:
 26                self.effects[name] = Effect(name, function)
 27        for name, effect in self.effects.items():
 28            setattr(self, name, effect)
 29
 30    def __add__(self, other_potion):
 31        new_duration = max(self.duration, other_potion.duration)
 32        new_potion = Potion(self.effects, new_duration)
 33        for name, effect in other_potion.effects.items():
 34            if name in new_potion.effects.keys():
 35                new_potion.effects[name].intensity += effect.intensity
 36            else:
 37                new_potion.effects[name] = Effect(name, effect.function)
 38                new_potion.effects[name].intensity = effect.intensity
 39        return new_potion
 40    
 41    def __mul__(self, intensity):
 42        #potentiation
 43        if isinstance(intensity, int) and intensity >= 1:
 44            new_potion = Potion(self.effects, self.duration)
 45            for name, effect in self.effects.items():
 46                new_potion.effects[name].intensity *= intensity
 47            return new_potion
 48        #dilution
 49        elif isinstance(intensity, float) and intensity > 0 and intensity < 1:
 50            new_potion = Potion(self.effects, self.duration)
 51            for name, effect in new_potion.effects.items():
 52                current_result = effect.intensity * intensity
 53                if current_result.is_integer():
 54                    new_potion.effects[name].intensity = current_result
 55                else:
 56                    current_result_fractional_part = current_result % 1
 57                    if current_result_fractional_part <= 0.5:
 58                        new_potion.effects[name].intensity = int(current_result // 1)
 59                    else:
 60                        new_potion.effects[name].intensity = int(current_result // 1 + 1)
 61            return new_potion
 62
 63    def __sub__(self, other_potion):
 64        for name, effect in other_potion.effects.items():
 65            if name not in self.effects.keys():
 66                raise TypeError("Invalid purification")
 67        new_potion = Potion(self.effects,self.duration)
 68        for name, effect in self.effects.items():
 69            if name in other_potion.effects.keys():
 70                current_intensity = self.effects[name].intensity - other_potion.effects[name].intensity
 71                if current_intensity <= 0:
 72                    del new_potion.effects[name]
 73                else:
 74                    new_potion.effects[name].intensity = current_intensity
 75        return new_potion
 76    
 77    # didn't quite understand this one
 78    def __truediv__(self, parts):
 79        new_collections = tuple(Potion(self.effects, self.duration) for _ in range(parts))
 80        return new_collections
 81    
 82    def __eq__(self, other_potion):
 83        return self.effects == other_potion.effects and self.duration == other_potion.duration
 84    
 85    def __lt__(self, other_potion):
 86        first_flask_intensity = 0
 87        second_flask_intensity = 0
 88        for name, effect in self.effects.items():
 89            first_flask_intensity += effect.intensity
 90        for name, effect in other_potion.effects.items():
 91            second_flask_intensity += effect.intensity
 92        return first_flask_intensity < second_flask_intensity
 93    
 94    def __gt__(self, other_potion):
 95        first_flask_intensity = 0
 96        second_flask_intensity = 0
 97        for name, effect in self.effects.items():
 98            first_flask_intensity += effect.intensity
 99        for name, effect in other_potion.effects.items():
100            second_flask_intensity += effect.intensity
101        return first_flask_intensity > second_flask_intensity
102    
103
104class ГоспожатаПоХимия:
105    def __init__(self):
106        self.name = "Димитричка, обаче настояват да я наричат Диди"
107        self.applied_potions = []
108
109    def apply(self, target, potion):
110        if potion.is_potion_used:
111            raise TypeError("Potion is depleted.")
112        if potion in self.applied_potions:
113            raise TypeError("Potion is now part of something bigger than itself.") 
114        sorted_effects = sorted(potion.effects.values(), key=lambda effect: sum(map(ord, effect.name)), reverse=True)
115        for effect in sorted_effects:
116            effect(target)
117        self.applied_potions.append(potion)
118        potion.is_potion_used = True
119
120    def tick(self):
121        for potion in self.applied_potions:
122            potion.duration -= 1
123            if potion.duration <= 0:
124                self.applied_potions.remove(potion)

.F.F.E.FE.FFF..FFFFF
======================================================================
ERROR: test_combination_no_overlap (test.TestPotionOperations)
Test combining potions with no overlap.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 95, in test_combination_no_overlap
potion.float_attr_fun(self._target)
AttributeError: 'Potion' object has no attribute 'float_attr_fun'

======================================================================
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 10, in __call__
raise TypeError("Effect is depleted.")
TypeError: Effect is depleted.

======================================================================
FAIL: test_depletion (test.TestBasicPotion)
Test depletion of a potion effect.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 78, in test_depletion
with self.assertRaisesRegex(TypeError, 'Effect is depleted\.'):
AssertionError: TypeError not raised

======================================================================
FAIL: test_equal (test.TestPotionComparison)
Test equality of potions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 292, in test_equal
self.assertEqual(potion1 + potion2, potion3)
AssertionError: <solution.Potion object at 0x7f31c37e7430> != <solution.Potion object at 0x7f31c37e56c0>

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

======================================================================
FAIL: 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 366, in test_applying_part_of_potion
self.assertEqual(self._target.int_attr, 5) # This should be the original value
AssertionError: 50 != 5

======================================================================
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 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=11, errors=2)

Дискусия
Георги Кунчев
05.12.2023 10:07

По принцип имаш чист код. Да, не е напълно верен. Не е изряден, но като стил си се справила добре. Това, плюс името на Димитричка, е достатъчно да ти дам една бонус точка.
История

f1class Effect:f1class Effect:
22
3    def __init__(self, name, function):3    def __init__(self, name, function):
4        self.name = name4        self.name = name
5        self.function = function5        self.function = function
6        self.intensity = 16        self.intensity = 1
77
8    def __call__(self, argument_of_function):8    def __call__(self, argument_of_function):
9        if self.intensity == 0:9        if self.intensity == 0:
10            raise TypeError("Effect is depleted.")10            raise TypeError("Effect is depleted.")
11        else:11        else:
12            for _ in range(self.intensity):12            for _ in range(self.intensity):
13                self.function(argument_of_function)13                self.function(argument_of_function)
1414
1515
16class Potion:16class Potion:
1717
18    def __init__(self, effects, duration):18    def __init__(self, effects, duration):
19        self.effects = dict()19        self.effects = dict()
20        self.duration = duration20        self.duration = duration
21        self.is_potion_used = False21        self.is_potion_used = False
22        for name, function in effects.items():22        for name, function in effects.items():
23            if name in self.effects.keys():23            if name in self.effects.keys():
24                self.effects[name].intensity += 124                self.effects[name].intensity += 1
25            else:25            else:
26                self.effects[name] = Effect(name, function)26                self.effects[name] = Effect(name, function)
27        for name, effect in self.effects.items():27        for name, effect in self.effects.items():
28            setattr(self, name, effect)28            setattr(self, name, effect)
2929
30    def __add__(self, other_potion):30    def __add__(self, other_potion):
31        new_duration = max(self.duration, other_potion.duration)31        new_duration = max(self.duration, other_potion.duration)
32        new_potion = Potion(self.effects, new_duration)32        new_potion = Potion(self.effects, new_duration)
33        for name, effect in other_potion.effects.items():33        for name, effect in other_potion.effects.items():
34            if name in new_potion.effects.keys():34            if name in new_potion.effects.keys():
35                new_potion.effects[name].intensity += effect.intensity35                new_potion.effects[name].intensity += effect.intensity
36            else:36            else:
37                new_potion.effects[name] = Effect(name, effect.function)37                new_potion.effects[name] = Effect(name, effect.function)
38                new_potion.effects[name].intensity = effect.intensity38                new_potion.effects[name].intensity = effect.intensity
39        return new_potion39        return new_potion
40    40    
41    def __mul__(self, intensity):41    def __mul__(self, intensity):
42        #potentiation42        #potentiation
43        if isinstance(intensity, int) and intensity >= 1:43        if isinstance(intensity, int) and intensity >= 1:
44            new_potion = Potion(self.effects, self.duration)44            new_potion = Potion(self.effects, self.duration)
45            for name, effect in self.effects.items():45            for name, effect in self.effects.items():
46                new_potion.effects[name].intensity *= intensity46                new_potion.effects[name].intensity *= intensity
47            return new_potion47            return new_potion
48        #dilution48        #dilution
49        elif isinstance(intensity, float) and intensity > 0 and intensity < 1:49        elif isinstance(intensity, float) and intensity > 0 and intensity < 1:
50            new_potion = Potion(self.effects, self.duration)50            new_potion = Potion(self.effects, self.duration)
51            for name, effect in new_potion.effects.items():51            for name, effect in new_potion.effects.items():
52                current_result = effect.intensity * intensity52                current_result = effect.intensity * intensity
53                if current_result.is_integer():53                if current_result.is_integer():
54                    new_potion.effects[name].intensity = current_result54                    new_potion.effects[name].intensity = current_result
55                else:55                else:
56                    current_result_fractional_part = current_result % 156                    current_result_fractional_part = current_result % 1
57                    if current_result_fractional_part <= 0.5:57                    if current_result_fractional_part <= 0.5:
58                        new_potion.effects[name].intensity = int(current_result // 1)58                        new_potion.effects[name].intensity = int(current_result // 1)
59                    else:59                    else:
60                        new_potion.effects[name].intensity = int(current_result // 1 + 1)60                        new_potion.effects[name].intensity = int(current_result // 1 + 1)
61            return new_potion61            return new_potion
6262
63    def __sub__(self, other_potion):63    def __sub__(self, other_potion):
64        for name, effect in other_potion.effects.items():64        for name, effect in other_potion.effects.items():
65            if name not in self.effects.keys():65            if name not in self.effects.keys():
66                raise TypeError("Invalid purification")66                raise TypeError("Invalid purification")
67        new_potion = Potion(self.effects,self.duration)67        new_potion = Potion(self.effects,self.duration)
68        for name, effect in self.effects.items():68        for name, effect in self.effects.items():
69            if name in other_potion.effects.keys():69            if name in other_potion.effects.keys():
70                current_intensity = self.effects[name].intensity - other_potion.effects[name].intensity70                current_intensity = self.effects[name].intensity - other_potion.effects[name].intensity
71                if current_intensity <= 0:71                if current_intensity <= 0:
72                    del new_potion.effects[name]72                    del new_potion.effects[name]
73                else:73                else:
74                    new_potion.effects[name].intensity = current_intensity74                    new_potion.effects[name].intensity = current_intensity
75        return new_potion75        return new_potion
76    76    
77    # didn't quite understand this one77    # didn't quite understand this one
78    def __truediv__(self, parts):78    def __truediv__(self, parts):
n79        new_collections = (Potion(self.effects, self.duration) for _ in range(parts))n79        new_collections = tuple(Potion(self.effects, self.duration) for _ in range(parts))
80        return new_collections80        return new_collections
81    81    
82    def __eq__(self, other_potion):82    def __eq__(self, other_potion):
83        return self.effects == other_potion.effects and self.duration == other_potion.duration83        return self.effects == other_potion.effects and self.duration == other_potion.duration
84    84    
85    def __lt__(self, other_potion):85    def __lt__(self, other_potion):
86        first_flask_intensity = 086        first_flask_intensity = 0
87        second_flask_intensity = 087        second_flask_intensity = 0
88        for name, effect in self.effects.items():88        for name, effect in self.effects.items():
89            first_flask_intensity += effect.intensity89            first_flask_intensity += effect.intensity
90        for name, effect in other_potion.effects.items():90        for name, effect in other_potion.effects.items():
91            second_flask_intensity += effect.intensity91            second_flask_intensity += effect.intensity
92        return first_flask_intensity < second_flask_intensity92        return first_flask_intensity < second_flask_intensity
93    93    
94    def __gt__(self, other_potion):94    def __gt__(self, other_potion):
95        first_flask_intensity = 095        first_flask_intensity = 0
96        second_flask_intensity = 096        second_flask_intensity = 0
97        for name, effect in self.effects.items():97        for name, effect in self.effects.items():
98            first_flask_intensity += effect.intensity98            first_flask_intensity += effect.intensity
99        for name, effect in other_potion.effects.items():99        for name, effect in other_potion.effects.items():
100            second_flask_intensity += effect.intensity100            second_flask_intensity += effect.intensity
101        return first_flask_intensity > second_flask_intensity101        return first_flask_intensity > second_flask_intensity
102    102    
103103
104class ГоспожатаПоХимия:104class ГоспожатаПоХимия:
t105    t
106    def __init__(self):105    def __init__(self):
107        self.name = "Димитричка, обаче настояват да я наричат Диди"106        self.name = "Димитричка, обаче настояват да я наричат Диди"
108        self.applied_potions = []107        self.applied_potions = []
109108
110    def apply(self, target, potion):109    def apply(self, target, potion):
111        if potion.is_potion_used:110        if potion.is_potion_used:
112            raise TypeError("Potion is depleted.")111            raise TypeError("Potion is depleted.")
113        if potion in self.applied_potions:112        if potion in self.applied_potions:
114            raise TypeError("Potion is now part of something bigger than itself.") 113            raise TypeError("Potion is now part of something bigger than itself.") 
115        sorted_effects = sorted(potion.effects.values(), key=lambda effect: sum(map(ord, effect.name)), reverse=True)114        sorted_effects = sorted(potion.effects.values(), key=lambda effect: sum(map(ord, effect.name)), reverse=True)
116        for effect in sorted_effects:115        for effect in sorted_effects:
117            effect(target)116            effect(target)
118        self.applied_potions.append(potion)117        self.applied_potions.append(potion)
119        potion.is_potion_used = True118        potion.is_potion_used = True
120119
121    def tick(self):120    def tick(self):
122        for potion in self.applied_potions:121        for potion in self.applied_potions:
123            potion.duration -= 1122            potion.duration -= 1
124            if potion.duration <= 0:123            if potion.duration <= 0:
125                self.applied_potions.remove(potion)124                self.applied_potions.remove(potion)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op