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

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

4 точки общо

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

  1def asciiSort(list_of_names):
  2    return sum(map(ord, list_of_names))
  3
  4
  5class Potion():
  6    def __init__(self, effects, duration):
  7        self.effects = effects
  8        self.duration = duration
  9        self._effects_names = {}
 10        self._set_attributes()
 11        self._used_effects_list = []
 12        self.changed = False
 13        self.depleted = False
 14
 15    def _set_attributes(self):
 16        for name, effect in self.effects.items():
 17            if name not in self._effects_names:
 18                self._effects_names[name] = 1
 19            else:
 20                self._effects_names[name] = self._effects_names[name] + 1
 21            setattr(self, name, lambda argument,
 22                    effect=effect, name=name: self._call_filter(name, argument, effect))
 23
 24    def _call_filter(self, name, argument, effect):
 25        if name in self._used_effects_list:
 26            raise TypeError("Effect is depleted.")
 27
 28        if self.changed:
 29            raise TypeError(
 30                "Potion is now part of something bigger than itself.")
 31
 32        self._used_effects_list.append(name)
 33
 34        for i in range(self._effects_names[name]):
 35            effect(argument)
 36
 37        if len(self._used_effects_list) == len(self._effects_names):
 38            self.depleted = True
 39
 40    def __add__(self, other):
 41        if self.depleted:
 42            raise TypeError("Potion is depleted.")
 43        self.changed = True
 44        combined_effects = self.effects | other.effects
 45        max_duration = max(self.duration, other.duration)
 46
 47        combined_potion = Potion(combined_effects, max_duration)
 48
 49        for name, intensity in self._effects_names.items():
 50            if name in other._effects_names:
 51                combined_potion._effects_names[name] = intensity + \
 52                    other._effects_names[name]
 53
 54        return combined_potion
 55
 56    def __sub__(self, other):
 57        if self.depleted:
 58            raise TypeError("Potion is depleted.")
 59        self.changed = True
 60
 61        # check if other has different effects from self
 62        for name, intensity in other._effects_names.items():
 63            if name not in self._effects_names:
 64                raise TypeError("Invalid subtraction")
 65
 66        new_effects = {}
 67        new_effects_names = {}
 68        for name, action in self.effects.items():
 69            if name in other._effects_names:
 70                new_intensity = self._effects_names[name] - \
 71                    other._effects_names[name]
 72                if new_intensity >= 1:
 73                    new_effects[name] = action
 74                    new_effects_names[name] = new_intensity
 75            else:
 76                new_effects[name] = action
 77                new_effects_names[name] = self._effects_names[name]
 78
 79        new_potion = Potion(new_effects, self.duration)
 80        new_potion._effects_names = new_effects_names
 81
 82        return new_potion
 83
 84    def __mul__(self, multiply_num):
 85        if self.depleted:
 86            raise TypeError("Potion is depleted.")
 87        self.changed = True
 88
 89        if not isinstance(multiply_num, int):
 90            raise TypeError("Multiplier must be an integer")
 91
 92        multiplied_poition = Potion(self.effects, self.duration)
 93
 94        if multiply_num != 0:
 95            for name, intensity in self._effects_names.items():
 96                # if new intensity is zero, set it to one
 97                new_intensity = max(round(intensity * multiply_num), 1)
 98                multiplied_poition._effects_names[name] = new_intensity
 99
100        return multiplied_poition
101
102    def __truediv__(self, devide_num):
103        if self.depleted:
104            raise TypeError("Potion is depleted.")
105        self.changed = True
106
107        if not isinstance(devide_num, int):
108            raise TypeError("Divider must be an integer")
109
110        if devide_num <= 0:
111            raise ValueError("Divider must be a positive integer")
112
113    def __eq__(self, other):
114        return self._effects_names == other._effects_names and self.effects == other.effects
115
116    def __lt__(self, other):
117        self_intensity = 0
118        other_intensity = 0
119
120        for name, intensity in self._effects_names.items():
121            self_intensity = self_intensity + intensity
122
123        for name, intensity in other._effects_names.items():
124            other_intensity = other_intensity + intensity
125
126        return self_intensity < other_intensity
127
128    def __gt__(self, other):
129        self_intensity = 0
130        other_intensity = 0
131
132        for name, intensity in self._effects_names.items():
133            self_intensity = self_intensity + intensity
134
135        for name, intensity in other._effects_names.items():
136            other_intensity = other_intensity + intensity
137
138        return self_intensity > other_intensity
139
140
141class ГоспожатаПоХимия():
142    def __init__(self):
143        self.potion = None
144        self.ticks = None
145
146    def apply(self, target, potion):
147        if potion.depleted:
148            raise TypeError("Potion is depleted.")
149
150        self.potion = potion
151        self.ticks = potion.duration
152
153        # sort by molecular mass
154        list_to_execute = list(potion.effects.keys())
155        list_to_execute = sorted(list_to_execute, key=asciiSort)
156        print(list_to_execute)
157
158        for name in list_to_execute:
159            try:
160                for i in range(potion._effects_names[name]):
161                    effect = getattr(potion, name)
162                    effect(target)
163            except TypeError as error:
164                if "Effect is depleted." in str(error):
165                    pass
166                else:
167                    print(error)
168
169    def tick(self):
170        self.ticks = self.ticks-1

.......FE.EEF
Stdout:
['int_attr_fun', 'dict_attr_fun', 'list_attr_fun', 'float_attr_fun']
['int_attr_fun', 'dict_attr_fun', 'list_attr_fun', 'float_attr_fun']
Potion is now part of something bigger than itself.
Potion is now part of something bigger than itself.
Potion is now part of something bigger than itself.
Potion is now part of something bigger than itself.
.F
Stdout:
['z_name', 'aa_name']
.F
Stdout:
['int_attr_fun']
F
Stdout:
['int_attr_fun']
['int_attr_fun']
F
Stdout:
['int_attr_fun']
['int_attr_fun']
F
Stdout:
['int_attr_fun', 'dict_attr_fun', 'list_attr_fun', 'float_attr_fun']

======================================================================
ERROR: test_dilution (test.TestPotionOperations)
Test dilution of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 118, in test_dilution
half_potion = base_potion * 0.5
File "/tmp/solution.py", line 90, in __mul__
raise TypeError("Multiplier must be an integer")
TypeError: Multiplier must be an integer

======================================================================
ERROR: test_purification (test.TestPotionOperations)
Test purification of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 190, in test_purification
potion.int_attr_fun(self._target)
AttributeError: 'Potion' object has no attribute 'int_attr_fun'

======================================================================
ERROR: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 213, in test_separation
potion1, potion2, potion3 = potion / 3
TypeError: cannot unpack non-iterable NoneType object

======================================================================
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

======================================================================
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 391, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
AssertionError: TypeError not raised

Stdout:
['int_attr_fun', 'dict_attr_fun', 'list_attr_fun', 'float_attr_fun']
['int_attr_fun', 'dict_attr_fun', 'list_attr_fun', 'float_attr_fun']
Potion is now part of something bigger than itself.
Potion is now part of something bigger than itself.
Potion is now part of something bigger than itself.
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

Stdout:
['z_name', 'aa_name']

======================================================================
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

Stdout:
['int_attr_fun']

======================================================================
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

Stdout:
['int_attr_fun']
['int_attr_fun']

======================================================================
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

Stdout:
['int_attr_fun']
['int_attr_fun']

======================================================================
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

Stdout:
['int_attr_fun', 'dict_attr_fun', 'list_attr_fun', 'float_attr_fun']

----------------------------------------------------------------------
Ran 20 tests in 0.002s

FAILED (failures=7, errors=3)

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

f1def asciiSort(list_of_names):f1def asciiSort(list_of_names):
2    return sum(map(ord, list_of_names))2    return sum(map(ord, list_of_names))
33
44
5class Potion():5class Potion():
6    def __init__(self, effects, duration):6    def __init__(self, effects, duration):
7        self.effects = effects7        self.effects = effects
8        self.duration = duration8        self.duration = duration
9        self._effects_names = {}9        self._effects_names = {}
10        self._set_attributes()10        self._set_attributes()
11        self._used_effects_list = []11        self._used_effects_list = []
12        self.changed = False12        self.changed = False
13        self.depleted = False13        self.depleted = False
1414
15    def _set_attributes(self):15    def _set_attributes(self):
16        for name, effect in self.effects.items():16        for name, effect in self.effects.items():
17            if name not in self._effects_names:17            if name not in self._effects_names:
18                self._effects_names[name] = 118                self._effects_names[name] = 1
19            else:19            else:
20                self._effects_names[name] = self._effects_names[name] + 120                self._effects_names[name] = self._effects_names[name] + 1
21            setattr(self, name, lambda argument,21            setattr(self, name, lambda argument,
22                    effect=effect, name=name: self._call_filter(name, argument, effect))22                    effect=effect, name=name: self._call_filter(name, argument, effect))
2323
24    def _call_filter(self, name, argument, effect):24    def _call_filter(self, name, argument, effect):
25        if name in self._used_effects_list:25        if name in self._used_effects_list:
26            raise TypeError("Effect is depleted.")26            raise TypeError("Effect is depleted.")
2727
28        if self.changed:28        if self.changed:
29            raise TypeError(29            raise TypeError(
30                "Potion is now part of something bigger than itself.")30                "Potion is now part of something bigger than itself.")
3131
32        self._used_effects_list.append(name)32        self._used_effects_list.append(name)
3333
34        for i in range(self._effects_names[name]):34        for i in range(self._effects_names[name]):
n35            print("call")n
36            print(name)
37            effect(argument)35            effect(argument)
3836
39        if len(self._used_effects_list) == len(self._effects_names):37        if len(self._used_effects_list) == len(self._effects_names):
40            self.depleted = True38            self.depleted = True
t41 t
42    def print(self):
43        print(self._effects_names)
44        print(self.duration)
4539
46    def __add__(self, other):40    def __add__(self, other):
47        if self.depleted:41        if self.depleted:
48            raise TypeError("Potion is depleted.")42            raise TypeError("Potion is depleted.")
49        self.changed = True43        self.changed = True
50        combined_effects = self.effects | other.effects44        combined_effects = self.effects | other.effects
51        max_duration = max(self.duration, other.duration)45        max_duration = max(self.duration, other.duration)
5246
53        combined_potion = Potion(combined_effects, max_duration)47        combined_potion = Potion(combined_effects, max_duration)
5448
55        for name, intensity in self._effects_names.items():49        for name, intensity in self._effects_names.items():
56            if name in other._effects_names:50            if name in other._effects_names:
57                combined_potion._effects_names[name] = intensity + \51                combined_potion._effects_names[name] = intensity + \
58                    other._effects_names[name]52                    other._effects_names[name]
5953
60        return combined_potion54        return combined_potion
6155
62    def __sub__(self, other):56    def __sub__(self, other):
63        if self.depleted:57        if self.depleted:
64            raise TypeError("Potion is depleted.")58            raise TypeError("Potion is depleted.")
65        self.changed = True59        self.changed = True
6660
67        # check if other has different effects from self61        # check if other has different effects from self
68        for name, intensity in other._effects_names.items():62        for name, intensity in other._effects_names.items():
69            if name not in self._effects_names:63            if name not in self._effects_names:
70                raise TypeError("Invalid subtraction")64                raise TypeError("Invalid subtraction")
7165
72        new_effects = {}66        new_effects = {}
73        new_effects_names = {}67        new_effects_names = {}
74        for name, action in self.effects.items():68        for name, action in self.effects.items():
75            if name in other._effects_names:69            if name in other._effects_names:
76                new_intensity = self._effects_names[name] - \70                new_intensity = self._effects_names[name] - \
77                    other._effects_names[name]71                    other._effects_names[name]
78                if new_intensity >= 1:72                if new_intensity >= 1:
79                    new_effects[name] = action73                    new_effects[name] = action
80                    new_effects_names[name] = new_intensity74                    new_effects_names[name] = new_intensity
81            else:75            else:
82                new_effects[name] = action76                new_effects[name] = action
83                new_effects_names[name] = self._effects_names[name]77                new_effects_names[name] = self._effects_names[name]
8478
85        new_potion = Potion(new_effects, self.duration)79        new_potion = Potion(new_effects, self.duration)
86        new_potion._effects_names = new_effects_names80        new_potion._effects_names = new_effects_names
8781
88        return new_potion82        return new_potion
8983
90    def __mul__(self, multiply_num):84    def __mul__(self, multiply_num):
91        if self.depleted:85        if self.depleted:
92            raise TypeError("Potion is depleted.")86            raise TypeError("Potion is depleted.")
93        self.changed = True87        self.changed = True
9488
95        if not isinstance(multiply_num, int):89        if not isinstance(multiply_num, int):
96            raise TypeError("Multiplier must be an integer")90            raise TypeError("Multiplier must be an integer")
9791
98        multiplied_poition = Potion(self.effects, self.duration)92        multiplied_poition = Potion(self.effects, self.duration)
9993
100        if multiply_num != 0:94        if multiply_num != 0:
101            for name, intensity in self._effects_names.items():95            for name, intensity in self._effects_names.items():
102                # if new intensity is zero, set it to one96                # if new intensity is zero, set it to one
103                new_intensity = max(round(intensity * multiply_num), 1)97                new_intensity = max(round(intensity * multiply_num), 1)
104                multiplied_poition._effects_names[name] = new_intensity98                multiplied_poition._effects_names[name] = new_intensity
10599
106        return multiplied_poition100        return multiplied_poition
107101
108    def __truediv__(self, devide_num):102    def __truediv__(self, devide_num):
109        if self.depleted:103        if self.depleted:
110            raise TypeError("Potion is depleted.")104            raise TypeError("Potion is depleted.")
111        self.changed = True105        self.changed = True
112106
113        if not isinstance(devide_num, int):107        if not isinstance(devide_num, int):
114            raise TypeError("Divider must be an integer")108            raise TypeError("Divider must be an integer")
115109
116        if devide_num <= 0:110        if devide_num <= 0:
117            raise ValueError("Divider must be a positive integer")111            raise ValueError("Divider must be a positive integer")
118112
119    def __eq__(self, other):113    def __eq__(self, other):
120        return self._effects_names == other._effects_names and self.effects == other.effects114        return self._effects_names == other._effects_names and self.effects == other.effects
121115
122    def __lt__(self, other):116    def __lt__(self, other):
123        self_intensity = 0117        self_intensity = 0
124        other_intensity = 0118        other_intensity = 0
125119
126        for name, intensity in self._effects_names.items():120        for name, intensity in self._effects_names.items():
127            self_intensity = self_intensity + intensity121            self_intensity = self_intensity + intensity
128122
129        for name, intensity in other._effects_names.items():123        for name, intensity in other._effects_names.items():
130            other_intensity = other_intensity + intensity124            other_intensity = other_intensity + intensity
131125
132        return self_intensity < other_intensity126        return self_intensity < other_intensity
133127
134    def __gt__(self, other):128    def __gt__(self, other):
135        self_intensity = 0129        self_intensity = 0
136        other_intensity = 0130        other_intensity = 0
137131
138        for name, intensity in self._effects_names.items():132        for name, intensity in self._effects_names.items():
139            self_intensity = self_intensity + intensity133            self_intensity = self_intensity + intensity
140134
141        for name, intensity in other._effects_names.items():135        for name, intensity in other._effects_names.items():
142            other_intensity = other_intensity + intensity136            other_intensity = other_intensity + intensity
143137
144        return self_intensity > other_intensity138        return self_intensity > other_intensity
145139
146140
147class ГоспожатаПоХимия():141class ГоспожатаПоХимия():
148    def __init__(self):142    def __init__(self):
149        self.potion = None143        self.potion = None
150        self.ticks = None144        self.ticks = None
151145
152    def apply(self, target, potion):146    def apply(self, target, potion):
153        if potion.depleted:147        if potion.depleted:
154            raise TypeError("Potion is depleted.")148            raise TypeError("Potion is depleted.")
155149
156        self.potion = potion150        self.potion = potion
157        self.ticks = potion.duration151        self.ticks = potion.duration
158152
159        # sort by molecular mass153        # sort by molecular mass
160        list_to_execute = list(potion.effects.keys())154        list_to_execute = list(potion.effects.keys())
161        list_to_execute = sorted(list_to_execute, key=asciiSort)155        list_to_execute = sorted(list_to_execute, key=asciiSort)
162        print(list_to_execute)156        print(list_to_execute)
163157
164        for name in list_to_execute:158        for name in list_to_execute:
165            try:159            try:
166                for i in range(potion._effects_names[name]):160                for i in range(potion._effects_names[name]):
167                    effect = getattr(potion, name)161                    effect = getattr(potion, name)
168                    effect(target)162                    effect(target)
169            except TypeError as error:163            except TypeError as error:
170                if "Effect is depleted." in str(error):164                if "Effect is depleted." in str(error):
171                    pass165                    pass
172                else:166                else:
173                    print(error)167                    print(error)
174168
175    def tick(self):169    def tick(self):
176        self.ticks = self.ticks-1170        self.ticks = self.ticks-1
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op