1import unittest
2
3from solution import *
4
5
6class SanityTest(unittest.TestCase):
7 """Sanity tests for Alchemy Workshop."""
8
9 def test_potion(self):
10 """Test Potion class."""
11 self.assertIsInstance(Potion({'do_nothing': lambda target: None}, duration=2), Potion)
12
13 def test_госпожата_по_химия(self):
14 """Test ГоспожатаПоХимия class."""
15 self.assertIsInstance(ГоспожатаПоХимия(), ГоспожатаПоХимия)
16
17
18if __name__ == '__main__':
19 unittest.main()
1import copy
2import unittest
3
4from solution import *
5
6
7class Target:
8 """Test target."""
9
10 def __init__(self, **kwargs):
11 """Initializator."""
12 self._cache = kwargs
13 for key, val in kwargs.items():
14 setattr(self, key, val)
15
16 def _refresh(self):
17 """Refresh all values to their initial state."""
18 for key, val in self._cache.items():
19 setattr(self, key, val)
20
21
22def int_attr_fun(target):
23 """Test function for altering int attribute."""
24 target.int_attr *= 10
25
26
27def float_attr_fun(target):
28 """Test function for altering float attribute."""
29 target.float_attr += 1
30
31
32def list_attr_fun(target):
33 """Test function for altering list attribute."""
34 target.list_attr.append(4)
35
36
37def dict_attr_fun(target):
38 """Test function for altering dict attribute."""
39 target.dict_attr = {val:key for key, val in target.dict_attr.items()}
40
41
42class TestBasicPotion(unittest.TestCase):
43 """Test Potion class for basic functionality."""
44
45 def setUp(self):
46 """Set up a test target."""
47 self._target = Target(int_attr=5, float_attr=3.14,
48 list_attr=[1, 2, 3],
49 dict_attr={'name': 'Борис', 'професия': 'жалбар'})
50
51 def test_empty(self):
52 """Test initialization with empty effects."""
53 potion = Potion({}, duration=0)
54 self.assertIsInstance(potion, Potion)
55
56 def test_applying(self):
57 """Test applying a potion to a target."""
58 potion = Potion({'int_attr_fun': int_attr_fun,
59 'float_attr_fun': float_attr_fun,
60 'list_attr_fun': list_attr_fun,
61 'dict_attr_fun': dict_attr_fun},
62 duration=1)
63 potion.int_attr_fun(self._target)
64 self.assertEqual(self._target.int_attr, 50)
65 potion.float_attr_fun(self._target)
66 self.assertAlmostEqual(self._target.float_attr, 4.14)
67 potion.list_attr_fun(self._target)
68 self.assertEqual(self._target.list_attr, [1, 2, 3, 4])
69 potion.dict_attr_fun(self._target)
70 self.assertEqual(self._target.dict_attr, {'Борис': 'name', 'жалбар': 'професия'})
71
72 def test_depletion(self):
73 """Test depletion of a potion effect."""
74 potion = Potion({'int_attr_fun': int_attr_fun},
75 duration=2)
76 potion.int_attr_fun(self._target)
77 self.assertEqual(self._target.int_attr, 50)
78 with self.assertRaisesRegex(TypeError, 'Effect is depleted\.'):
79 potion.int_attr_fun(self._target)
80
81
82class TestPotionOperations(unittest.TestCase):
83 """Test operations for Potion class."""
84
85 def setUp(self):
86 """Set up a test target."""
87 self._target = Target(int_attr=5, float_attr=3.14)
88
89 def test_combination_no_overlap(self):
90 """Test combining potions with no overlap."""
91 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
92 potion2 = Potion({'float_attr_fun': float_attr_fun}, duration=2)
93 potion = potion1 + potion2
94 potion.int_attr_fun(self._target)
95 potion.float_attr_fun(self._target)
96 self.assertEqual(self._target.int_attr, 50)
97 self.assertAlmostEqual(self._target.float_attr, 4.14)
98
99 def test_combination_with_overlap(self):
100 """Test combining potions with overlap."""
101 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
102 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=2)
103 potion = potion1 + potion2
104 potion.int_attr_fun(self._target)
105 self.assertEqual(self._target.int_attr, 500)
106
107 def test_potentiation(self):
108 """Test potentiation of a potion."""
109 potion = Potion({'int_attr_fun': int_attr_fun}, duration=1)
110 potion = potion * 3
111 potion.int_attr_fun(self._target)
112 self.assertEqual(self._target.int_attr, 5 * (10 ** 3))
113
114 def test_dilution(self):
115 """Test dilution of a potion."""
116 # Test at half
117 base_potion = Potion({'int_attr_fun': int_attr_fun}, duration=1)
118 half_potion = base_potion * 0.5
119 half_potion.int_attr_fun(self._target)
120 self.assertEqual(self._target.int_attr, 5)
121 # Test above half
122 self._target = copy.deepcopy(self._target)
123 self._target._refresh()
124 base_potion = Potion({'int_attr_fun': int_attr_fun}, duration=1)
125 half_potion = base_potion * 0.51
126 half_potion.int_attr_fun(self._target)
127 self.assertEqual(self._target.int_attr, 50)
128 # Test below half
129 self._target = copy.deepcopy(self._target)
130 self._target._refresh()
131 base_potion = Potion({'int_attr_fun': int_attr_fun}, duration=1)
132 half_potion = base_potion * 0.49
133 half_potion.int_attr_fun(self._target)
134 self.assertEqual(self._target.int_attr, 5)
135 # Test around zero
136 self._target = copy.deepcopy(self._target)
137 self._target._refresh()
138 base_potion = Potion({'int_attr_fun': int_attr_fun}, duration=1)
139 half_potion = base_potion * 0.0001
140 half_potion.int_attr_fun(self._target)
141 self.assertEqual(self._target.int_attr, 5)
142 # Test actual division
143 self._target = copy.deepcopy(self._target)
144 self._target._refresh()
145 base_potion = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
146 half_potion = base_potion * 0.5
147 half_potion.int_attr_fun(self._target)
148 self.assertEqual(self._target.int_attr, 50)
149 # Test rounding to odd number (built-in round() always goes to an even number)
150 self._target = copy.deepcopy(self._target)
151 self._target._refresh()
152 base_potion = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 3
153 half_potion = base_potion * 0.5
154 half_potion.int_attr_fun(self._target)
155 self.assertEqual(self._target.int_attr, 50)
156
157 def test_purification(self):
158 """Test purification of a potion."""
159 # Test normal behaviour
160 potion1 = Potion({'int_attr_fun': int_attr_fun,
161 'float_attr_fun': float_attr_fun},
162 duration=1)
163 potion2 = Potion({'int_attr_fun': int_attr_fun},
164 duration=1)
165 potion = potion1 - potion2
166 potion.float_attr_fun(self._target)
167 self.assertAlmostEqual(self._target.float_attr, 4.14)
168 with self.assertRaises(AttributeError):
169 potion.int_attr_fun(self._target)
170 # Test mismatching effects
171 self._target = copy.deepcopy(self._target)
172 self._target._refresh()
173 potion1 = Potion({'int_attr_fun': int_attr_fun,
174 'float_attr_fun': float_attr_fun},
175 duration=1)
176 potion2 = Potion({'int_attr_fun': int_attr_fun},
177 duration=1)
178 with self.assertRaises(TypeError):
179 potion2 - potion1
180 # Test with intensity
181 self._target = copy.deepcopy(self._target)
182 self._target._refresh()
183 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 3
184 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
185 potion_decorator = Potion({'float_attr_fun': float_attr_fun}, duration=1)
186 potion1 = potion1 + potion_decorator
187 potion = potion1 - potion2
188 potion.float_attr_fun(self._target)
189 self.assertAlmostEqual(self._target.float_attr, 4.14)
190 potion.int_attr_fun(self._target)
191 self.assertEqual(self._target.int_attr, 50)
192 # Test with intensity resulting in zero
193 self._target = copy.deepcopy(self._target)
194 self._target._refresh()
195 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
196 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
197 potion = potion1 - potion2
198 with self.assertRaises(AttributeError):
199 potion.int_attr_fun(self._target)
200 # Test with higher intensity on the right
201 self._target = copy.deepcopy(self._target)
202 self._target._refresh()
203 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
204 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 3
205 potion = potion1 - potion2
206 with self.assertRaises(AttributeError):
207 potion.int_attr_fun(self._target)
208
209 def test_separation(self):
210 """Test separation of a potion."""
211 # Test normal case
212 potion = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 9
213 potion1, potion2, potion3 = potion / 3
214 potion1.int_attr_fun(self._target)
215 self.assertEqual(self._target.int_attr, 5 * (10 ** 3))
216 self._target = copy.deepcopy(self._target)
217 self._target._refresh()
218 potion2.int_attr_fun(self._target)
219 self.assertEqual(self._target.int_attr, 5 * (10 ** 3))
220 self._target = copy.deepcopy(self._target)
221 self._target._refresh()
222 potion3.int_attr_fun(self._target)
223 self.assertEqual(self._target.int_attr, 5 * (10 ** 3))
224 # Test resulting in one
225 self._target = copy.deepcopy(self._target)
226 self._target._refresh()
227 potion = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 3
228 potion1, potion2, potion3 = potion / 3
229 potion1.int_attr_fun(self._target)
230 self.assertEqual(self._target.int_attr, 50)
231 self._target = copy.deepcopy(self._target)
232 self._target._refresh()
233 potion2.int_attr_fun(self._target)
234 self.assertEqual(self._target.int_attr, 50)
235 self._target = copy.deepcopy(self._target)
236 self._target._refresh()
237 potion3.int_attr_fun(self._target)
238 self.assertEqual(self._target.int_attr, 50)
239 # Test rounding to odd
240 self._target = copy.deepcopy(self._target)
241 self._target._refresh()
242 potion = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 3
243 potion1, potion2 = potion / 2
244 potion1.int_attr_fun(self._target)
245 self.assertEqual(self._target.int_attr, 50)
246 self._target = copy.deepcopy(self._target)
247 self._target._refresh()
248 potion2.int_attr_fun(self._target)
249 self.assertEqual(self._target.int_attr, 50)
250
251 def test_deprecation(self):
252 """Test deprecation of a potion."""
253 # Addition
254 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
255 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
256 potion = potion1 + potion2
257 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
258 potion1.int_attr_fun(self._target)
259 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
260 potion2.int_attr_fun(self._target)
261 # Multiplication
262 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
263 potion = potion1 * 2
264 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
265 potion1.int_attr_fun(self._target)
266 # Subtraction
267 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
268 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
269 potion = potion1 - potion2
270 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
271 potion1.int_attr_fun(self._target)
272 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
273 potion2.int_attr_fun(self._target)
274 # Division
275 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
276 potion = potion1 / 1
277 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
278 potion1.int_attr_fun(self._target)
279
280
281class TestPotionComparison(unittest.TestCase):
282 """Test comparisons for Potion class."""
283
284 def test_equal(self):
285 """Test equality of potions."""
286 # Normal case
287 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
288 potion2 = Potion({'float_attr_fun': float_attr_fun}, duration=1)
289 potion3 = Potion({'int_attr_fun': int_attr_fun,
290 'float_attr_fun': float_attr_fun},
291 duration=1)
292 self.assertEqual(potion1 + potion2, potion3)
293 # With intensity
294 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
295 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
296 potion3 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
297 potion4 = potion1 + potion2
298 self.assertEqual(potion4, potion3)
299 # Not equal due to different methods
300 potion1 = Potion({'float_attr_fun': float_attr_fun}, duration=1)
301 potion2 = Potion({'int_attr_fun': int_attr_fun,
302 'float_attr_fun': float_attr_fun},
303 duration=1)
304 self.assertNotEqual(potion1, potion2)
305 # Not equal due to different intensity
306 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
307 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
308 potion3 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 3
309 potion4 = potion1 + potion2
310 self.assertNotEqual(potion4, potion3)
311
312 def test_superbness(self):
313 """Test superbness of potions."""
314 # Normal case
315 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
316 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
317 self.assertLess(potion1, potion2)
318 self.assertGreater(potion2, potion1)
319 self.assertNotEqual(potion1, potion2)
320 # Diffetent intensity for different methods
321 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
322 potion2 = Potion({'float_attr_fun': float_attr_fun}, duration=1) * 3
323 self.assertLess(potion1, potion2)
324 self.assertGreater(potion2, potion1)
325 self.assertNotEqual(potion1, potion2)
326 # Equal intensity for different methods
327 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
328 potion2 = Potion({'float_attr_fun': float_attr_fun}, duration=1) * 2
329 self.assertFalse(potion1 > potion2)
330 self.assertFalse(potion1 < potion2)
331
332
333class TestГоспожатаПоХимия(unittest.TestCase):
334 """Test ГоспожатаПоХимия."""
335
336 def setUp(self):
337 """Set up a test target."""
338 self._target = Target(int_attr=5, float_attr=3.14,
339 list_attr=[1, 2, 3],
340 dict_attr={'name': 'Борис', 'професия': 'жалбар'})
341 self._dimitrichka = ГоспожатаПоХимия()
342
343 def test_applying_normal_case(self):
344 """Test applying a normal potion."""
345 potion = Potion({'int_attr_fun': int_attr_fun,
346 'float_attr_fun': float_attr_fun,
347 'list_attr_fun': list_attr_fun,
348 'dict_attr_fun': dict_attr_fun},
349 duration=1)
350 self._dimitrichka.apply(self._target, potion)
351 self.assertEqual(self._target.int_attr, 50)
352 self.assertAlmostEqual(self._target.float_attr, 4.14)
353 self.assertEqual(self._target.list_attr, [1, 2, 3, 4])
354 self.assertEqual(self._target.dict_attr, {'Борис': 'name', 'жалбар': 'професия'})
355
356 def test_applying_part_of_potion(self):
357 """Test applying only a part of a potion."""
358 potion = Potion({'int_attr_fun': int_attr_fun,
359 'float_attr_fun': float_attr_fun,
360 'list_attr_fun': list_attr_fun,
361 'dict_attr_fun': dict_attr_fun},
362 duration=1)
363 temp_target = Target(int_attr=5)
364 potion.int_attr_fun(temp_target)
365 self._dimitrichka.apply(self._target, potion)
366 self.assertEqual(self._target.int_attr, 5) # This should be the original value
367 self.assertAlmostEqual(self._target.float_attr, 4.14)
368 self.assertEqual(self._target.list_attr, [1, 2, 3, 4])
369 self.assertEqual(self._target.dict_attr, {'Борис': 'name', 'жалбар': 'професия'})
370
371 def test_applying_depleted_potion(self):
372 """Test applying a depleted potion or a potion that was used in a reaction."""
373 # Apply a depleted potion
374 potion = Potion({'int_attr_fun': int_attr_fun,
375 'float_attr_fun': float_attr_fun,
376 'list_attr_fun': list_attr_fun,
377 'dict_attr_fun': dict_attr_fun},
378 duration=1)
379 self._dimitrichka.apply(self._target, potion)
380 with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
381 self._dimitrichka.apply(self._target, potion)
382 with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
383 potion = potion * 2
384 # Apply a potion that was used in a reaction
385 potion = Potion({'int_attr_fun': int_attr_fun,
386 'float_attr_fun': float_attr_fun,
387 'list_attr_fun': list_attr_fun,
388 'dict_attr_fun': dict_attr_fun},
389 duration=1)
390 _ = potion * 2
391 with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
392 self._dimitrichka.apply(self._target, potion)
393
394 def test_applying_order(self):
395 """Test applying order of a potion."""
396 # aa_name should have precedence
397 def z_name(target):
398 target.int_attr += 2
399 def aa_name(target):
400 target.int_attr *= 2
401 potion = Potion({'z_name': z_name,
402 'aa_name': aa_name},
403 duration=1)
404 self._dimitrichka.apply(self._target, potion)
405 self.assertEqual(self._target.int_attr, 12)
406 # z_name should have precedence
407 self._target = copy.deepcopy(self._target)
408 self._target._refresh()
409 def z_name(target):
410 target.int_attr += 2
411 def a_name(target):
412 target.int_attr *= 2
413 potion = Potion({'z_name': z_name,
414 'a_name': a_name},
415 duration=1)
416 self._dimitrichka.apply(self._target, potion)
417 self.assertEqual(self._target.int_attr, 14)
418
419 def test_ticking_immutable(self):
420 """Test ticking after applying a potion with immutable attributes."""
421 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
422 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=2)
423 potion = potion1 + potion2 # Excepted duration is 2 with intensity of 2
424 self._dimitrichka.apply(self._target, potion)
425 self.assertEqual(self._target.int_attr, 500)
426 self._dimitrichka.tick()
427 self.assertEqual(self._target.int_attr, 500)
428 self._dimitrichka.tick()
429 self.assertEqual(self._target.int_attr, 5)
430
431 def test_ticking_mutable(self):
432 """Test ticking after applying a potion with mutable attributes."""
433 potion = Potion({'int_attr_fun': int_attr_fun,
434 'float_attr_fun': float_attr_fun,
435 'list_attr_fun': list_attr_fun,
436 'dict_attr_fun': dict_attr_fun},
437 duration=1)
438 self._dimitrichka.apply(self._target, potion)
439 self.assertEqual(self._target.int_attr, 50)
440 self.assertAlmostEqual(self._target.float_attr, 4.14)
441 self.assertEqual(self._target.list_attr, [1, 2, 3, 4])
442 self.assertEqual(self._target.dict_attr, {'Борис': 'name', 'жалбар': 'професия'})
443 self._dimitrichka.tick()
444 self.assertEqual(self._target.int_attr, 5)
445 self.assertAlmostEqual(self._target.float_attr, 3.14)
446 self.assertEqual(self._target.list_attr, [1, 2, 3])
447 self.assertEqual(self._target.dict_attr, {'name': 'Борис', 'професия': 'жалбар'})
448
449 def test_ticking_multiple_potions(self):
450 """Test ticking after applying multiple potions which affect the same attribute."""
451 # Same attribute
452 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
453 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=2)
454 self._dimitrichka.apply(self._target, potion1)
455 self._dimitrichka.apply(self._target, potion2)
456 self.assertEqual(self._target.int_attr, 500)
457 self._dimitrichka.tick()
458 self.assertEqual(self._target.int_attr, 50)
459 self._dimitrichka.tick()
460 self.assertEqual(self._target.int_attr, 5)
461 # Different attributes
462 self._target = copy.deepcopy(self._target)
463 self._target._refresh()
464 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1)
465 potion2 = Potion({'float_attr_fun': float_attr_fun}, duration=2)
466 self._dimitrichka.apply(self._target, potion1)
467 self._dimitrichka.apply(self._target, potion2)
468 self.assertEqual(self._target.int_attr, 50)
469 self.assertAlmostEqual(self._target.float_attr, 4.14)
470 self._dimitrichka.tick()
471 self.assertEqual(self._target.int_attr, 5)
472 self.assertAlmostEqual(self._target.float_attr, 4.14)
473 self._dimitrichka.tick()
474 self.assertEqual(self._target.int_attr, 5)
475 self.assertAlmostEqual(self._target.float_attr, 3.14)
476
477 def test_ticking_multiple_targets(self):
478 """Test ticking after applying a potion with mutable attributes."""
479 potion1 = Potion({'int_attr_fun': int_attr_fun}, duration=1) * 2
480 potion2 = Potion({'int_attr_fun': int_attr_fun}, duration=2)
481 target1 = self._target
482 target2 = Target(int_attr=5, float_attr=3.14,
483 list_attr=[1, 2, 3],
484 dict_attr={'name': 'Борис', 'професия': 'жалбар'})
485 self._dimitrichka.apply(target1, potion1)
486 self._dimitrichka.apply(target2, potion2)
487 self.assertEqual(target1.int_attr, 500)
488 self.assertEqual(target2.int_attr, 50)
489 self._dimitrichka.tick()
490 self.assertEqual(target1.int_attr, 5)
491 self.assertEqual(target2.int_attr, 50)
492 self._dimitrichka.tick()
493 self.assertEqual(target1.int_attr, 5)
494 self.assertEqual(target2.int_attr, 5)
495
496
497if __name__ == '__main__':
498 unittest.main()
Георги Кунчев
05.12.2023 11:18Ако ползваш отварата - potion.
Ако ползваш само ефект от нея - effect.
|
Веселина Велкова
05.12.2023 11:07В случая на grow_potion едновременно и ефектът и отварата се изчерпват. Каква грешка трябва да хвърлим effect is depleted or potion is depleted?
|
Михаил Цанков
05.12.2023 08:05Ето още малко тестове https://pastebin.com/HPSDewDa
Ако някой нещо му гърми 🤙
|
Костадин Русалов
05.12.2023 03:16Ето малко тестове, като тук-там може да има някой изпуснат кейс или някой недефиниран, или някой грешен (дано няма такива)
```
import unittest
grow = {'grow': lambda _: setattr(_, 'size', _.size * 2)}
heal = {'heal': lambda _: setattr(_, 'health', _.health + 10)}
strengthen = {'strengthen': lambda _: setattr(_, 'strength', _.strength + 20)}
fly = {'fly': lambda _: setattr(_, 'fly', True)}
invisible = {'invisible': lambda _: setattr(_, 'invisible', True)}
glow = {'glow': lambda _: setattr(_, 'glow', _.glow * 3)}
armor = {'armor': lambda _: setattr(_, 'armor', _.armor + 5)}
speed = {'speed': lambda _: setattr(_, 'speed', _.speed * 2)}
power = {'power': lambda _: setattr(_, 'power', 200)}
TRANSCENDED = 'Potion is now part of something bigger than itself.'
DEPLETED_P = 'Potion is depleted.'
DEPLETED_E = 'Effect is depleted.'
class Target:
def __init__(self, **kwargs):
for prop, val in kwargs.items():
setattr(self, prop, val)
class PotionTest(unittest.TestCase):
def test_use_potion_effect_once(self):
grow_potion = Potion(grow, 1)
target = Target(size=10)
grow_potion.grow(target)
self.assertEqual(20, target.size)
with self.assertRaises(TypeError) as e:
grow_potion.grow(target)
self.assertEqual(DEPLETED_E, str(e.exception))
def test_combined_potion_has_all_effects(self):
grow_heal_potion = Potion(grow | heal, 1)
fly_invis_potion = Potion(fly | invisible, 1)
all_potion = grow_heal_potion + fly_invis_potion
self.assertTrue('grow' in dir(all_potion))
self.assertTrue('heal' in dir(all_potion))
self.assertTrue('invisible' in dir(all_potion))
self.assertTrue('fly' in dir(all_potion))
def test_combined_potion_has_increased_intensity(self):
triple_grow_potion = Potion(grow, 1) + Potion(grow, 1) + Potion(grow, 1)
target = Target(size=8)
triple_grow_potion.grow(target)
self.assertEqual(64, target.size)
def test_combined_potion_has_longer_duration(self):
heal_potion = Potion(heal, 10)
grow_potion = Potion(grow, 5)
fly_potion = Potion(fly, 7)
triple_potion = heal_potion + grow_potion + fly_potion
self.assertEqual(10, triple_potion.duration)
def test_potented_potion_has_increased_intensity(self):
heal_grow_potion = Potion(heal | grow, 1)
potented_potion = heal_grow_potion * 5
target = Target(size=1, health=19)
potented_potion.heal(target)
potented_potion.grow(target)
self.assertEqual(69, target.health)
self.assertEqual(32, target.size)
def test_diluted_potion_has_decreased_intensity_rounded_half_down(self):
heal_2_grow_4_potion = Potion(heal, 1) * 2 + Potion(grow, 1) * 4
diluted_grow_potion = heal_2_grow_4_potion * 0.625
target = Target(size=25, health=10)
diluted_grow_potion.grow(target)
diluted_grow_potion.heal(target)
self.assertEqual(100, target.size)
self.assertEqual(20, target.health)
def test_diluted_potion_has_decreased_intensity_rounded_half_up(self):
triple_heal_potion = Potion(heal, 1) * 3
diluted_potion = triple_heal_potion * 0.6
target = Target(health=10)
diluted_potion.heal(target)
self.assertEqual(30, target.health)
def test_diluted_potion_with_zero_intensity(self):
fly_potion = Potion(fly, 1) * 0
target = Target(fly=False)
self.assertTrue('fly' in dir(fly_potion))
fly_potion.fly(target)
self.assertFalse(target.fly)
def test_purify_with_potion_that_has_more_effects(self):
heal_grow_potion = Potion(heal | grow, 1)
heal_fly_potion = Potion(heal | fly, 1)
with self.assertRaises(TypeError):
heal_grow_potion - heal_fly_potion
def test_purify_potion_decreases_intensities_removes_non_positive_effects(self):
heal_grow_power_armor_speed_potion = (Potion(armor, 1) * 3 + Potion(grow, 1) * 4
+ Potion(heal, 1) * 3 + Potion(power, 1) + Potion(speed, 8) * 2)
heal_grow_power_armor_potion = (Potion(grow, 1) * 2 + Potion(heal, 1) * 3
+ Potion(power, 1) * 3 + Potion(armor, 1) * 0)
grow_armor_speed_potion = heal_grow_power_armor_speed_potion - heal_grow_power_armor_potion
with self.assertRaises(AttributeError):
grow_armor_speed_potion.heal
with self.assertRaises(AttributeError):
grow_armor_speed_potion.power
target = Target(armor=10, size=20, speed=10)
grow_armor_speed_potion.grow(target)
grow_armor_speed_potion.armor(target)
grow_armor_speed_potion.speed(target)
self.assertEqual(80, target.size)
self.assertEqual(25, target.armor)
self.assertEqual(40, target.speed)
def test_purify_potion_that_has_used_effect(self):
heal_grow_potion = Potion(heal | grow, 1) * 3
heal_grow_potion.grow(Target(size=0))
grow_potion = Potion(grow, 2) * 2
heal_potion = heal_grow_potion - grow_potion
with self.assertRaises(AttributeError):
heal_potion.grow
target = Target(health=60)
heal_potion.heal(target)
self.assertEqual(90, target.health)
def test_purify_potion_with_one_that_has_used_effects(self):
power_speed_potion = Potion(power, 1) * 3 + Potion(speed, 1)
speed_potion = Potion(speed, 1)
speed_potion.speed(Target(speed=0))
purified_power_speed_potion = power_speed_potion - speed_potion
target = Target(power=10, speed=40)
purified_power_speed_potion.power(target)
purified_power_speed_potion.speed(target)
self.assertEqual(200, target.power)
self.assertEqual(80, target.speed)
@unittest.skip
def test_purify_potion_undefined_case_vol_1(self):
heal_grow_potion = Potion(heal, 1) * 2 + Potion(grow, 2) * 0
used_grow_potion = Potion(grow, 1)
used_grow_potion.grow(Target())
target = Target(size=10)
(heal_grow_potion - used_grow_potion).grow(target)
self.assertEqual(10, target.size)
@unittest.skip
def test_purify_potion_undefined_case_vol_2(self):
heal_fly_potion = Potion(heal | fly, 2) * 3
heal_fly_potion.heal(Target())
fly_potion = Potion(fly, 2) * 10
with self.assertRaises(AttributeError):
(heal_fly_potion - fly_potion).heal(Target())
def test_purify_potion_removes_all_effects(self):
heal_potion = Potion(heal, 1)
double_heal_potion = Potion(heal, 2) * 2
empty_potion = heal_potion - double_heal_potion
with self.assertRaises(AttributeError):
empty_potion.heal(Target())
def test_divide_potion_has_divided_intensity(self):
fly_heal_grow_strengthen = (Potion(fly, 1) * 4 + Potion(heal, 1) * 10 +
Potion(grow, 1) * 5 + Potion(strengthen, 1) * 15)
fly_heal_grow_strengthen.fly(Target())
one_fourth_1, one_fourth_2, one_fourth_3, one_fourth_4 = fly_heal_grow_strengthen / 4
with self.assertRaises(AttributeError):
one_fourth_2.fly(Target())
target1 = Target(health=0)
one_fourth_1.heal(target1)
self.assertEqual(20, target1.health)
target2 = Target(size=10, strength=20, health=10)
one_fourth_2.heal(target2)
one_fourth_2.grow(target2)
one_fourth_2.strengthen(target2)
self.assertEqual(30, target2.health)
self.assertEqual(20, target2.size)
self.assertEqual(100, target2.strength)
target3 = Target(size=20)
one_fourth_3.grow(target3)
self.assertEqual(40, target3.size)
target4 = Target(strength=100)
one_fourth_4.strengthen(target4)
self.assertEqual(180, target4.strength)
def test_potion_transcends_after_sum(self):
heal_potion = Potion(heal, 1)
power_grow_potion = Potion(power | grow, 3)
fly_potion = Potion(fly, 1)
heal_potion + power_grow_potion + fly_potion
with self.assertRaises(TypeError) as e:
heal_potion.heal(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
power_grow_potion.power(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
power_grow_potion.grow(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
fly_potion.fly(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
def test_transcends_after_potention(self):
power_grow_potion = Potion(power | grow, 1)
power_grow_potion * 69
with self.assertRaises(TypeError) as e:
power_grow_potion.grow(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
power_grow_potion.power(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
def test_transcends_after_dilution(self):
speed_potion = Potion(speed, 0)
speed_potion * 0.1
with self.assertRaises(TypeError) as e:
speed_potion.speed(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
def test_transcends_after_purification(self):
heal_grow_potion = Potion(heal | grow, 1)
grow_potion = Potion(grow, 1)
heal_grow_potion - grow_potion
with self.assertRaises(TypeError) as e:
heal_grow_potion.heal(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_grow_potion.grow(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
grow_potion.grow(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
def test_transcends_after_division(self):
power_armor_potion = Potion(power | armor, 1)
power_armor_potion / 10
with self.assertRaises(TypeError) as e:
power_armor_potion.power(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
with self.assertRaises(TypeError) as e:
power_armor_potion.armor(Target())
self.assertEqual(TRANSCENDED, str(e.exception))
def test_combine_potions(self):
heal_grow_speed_glow = (Potion(heal, 1) * 2 + Potion(grow, 1) * 5
+ Potion(speed, 1) + Potion(glow, 1))
heal_grow_speed_glow.heal(Target(health=0))
heal_grow_speed_glow.glow(Target(glow=0))
heal_speed_grow_glow_armor = (Potion(heal, 1) * 3 + Potion(speed, 1) * 2
+ Potion(grow, 1) * 2 + Potion(glow, 2) * 2 + Potion(armor, 2) * 0)
heal_speed_grow_glow_armor.speed(Target(speed=0))
heal_speed_grow_glow_armor.glow(Target(glow=0))
combined = heal_grow_speed_glow + heal_speed_grow_glow_armor
with self.assertRaises(AttributeError):
combined.glow
target = Target(health=10, size=1, speed=10, armor=20)
combined.heal(target)
combined.grow(target)
combined.speed(target)
combined.armor(target)
self.assertEqual(40, target.health)
self.assertEqual(128, target.size)
self.assertEqual(20, target.speed)
self.assertEqual(20, target.armor)
def test_potent_potion(self):
heal_grow_speed = Potion(heal | grow | speed, 1)
heal_grow_speed.heal(Target(health=0))
eleventh = heal_grow_speed * 11
with self.assertRaises(AttributeError):
eleventh.heal(Target(health=10))
target = Target(size=1, speed=1)
eleventh.speed(target)
eleventh.grow(target)
self.assertEqual((2048, 2048), (target.speed, target.size))
def test_comparing_potions(self):
grow_potion = Potion(grow, 1)
double_grow_potion = Potion(grow, 1) * 2
invisible_fly_potion = Potion(invisible | fly, 1)
self.assertTrue(grow_potion == grow_potion)
self.assertFalse(grow_potion < grow_potion)
self.assertTrue(double_grow_potion > grow_potion)
self.assertTrue(invisible_fly_potion > grow_potion)
self.assertFalse(double_grow_potion < invisible_fly_potion)
self.assertFalse(double_grow_potion > invisible_fly_potion)
def test_compare_potions_with_used_effects(self):
grow_heal_speed_potion = Potion(grow, 1) * 0 + Potion(heal, 1) * 2 + Potion(speed, 2)
used_grow_heal_speed_potion = Potion(grow | speed, 4) + Potion(heal, 2) * 2
used_grow_heal_speed_potion.grow(Target(size=0))
self.assertTrue(grow_heal_speed_potion == used_grow_heal_speed_potion)
grow_heal_speed_potion -= Potion(grow, 1)
self.assertFalse(grow_heal_speed_potion == used_grow_heal_speed_potion)
def test_apply_potion_sorted_by_mass(self):
grow_potion = Potion(grow | {'little_grow': lambda _: setattr(_, 'size', _.size + 20),
'shr': lambda _: setattr(_, 'size', _.size - 10)}, 1)
target = Target(size=10)
ГоспожатаПоХимия().apply(target, grow_potion)
self.assertEqual(50, target.size)
def test_deplete_potion_after_appy(self):
heal_potion = Potion(heal, 1)
target = Target(health=90)
ГоспожатаПоХимия().apply(target, heal_potion)
with self.assertRaises(TypeError) as e:
heal_potion.heal(target)
self.assertEqual(100, target.health)
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_potion + Potion({}, 1)
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_potion - Potion({}, 1)
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_potion * Potion({}, 1)
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_potion / 2
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_potion == Potion({}, 1)
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
heal_potion < Potion({}, 1)
self.assertEqual(DEPLETED_P, str(e.exception))
with self.assertRaises(TypeError) as e:
ГоспожатаПоХимия().apply(Target(), heal_potion)
self.assertEqual(DEPLETED_P, str(e.exception))
def test_dimitrichka_with_zero_duration_potion(self):
grow_potion = Potion(grow, 0)
target = Target(size=10)
димитричка = ГоспожатаПоХимия()
димитричка.apply(target, grow_potion)
self.assertEqual(10, target.size)
def test_dimitrichka_with_used_effects(self):
heal_grow_power_potion = Potion(heal | grow | power, 1)
heal_grow_power_potion.power(Target())
pastichka = ГоспожатаПоХимия()
target = Target(health=10, size=10, power=10)
pastichka.apply(target, heal_grow_power_potion)
self.assertEqual(20, target.health)
self.assertEqual(20, target.size)
self.assertEqual(10, target.power)
def test_dimitrichka_with_one_poor_addict(self):
heal_invisible_fly_potion = Potion(heal, 2) * 3 + Potion(fly | invisible, 3)
target = Target(health=30, fly=False, invisible=False)
пастичка = ГоспожатаПоХимия()
пастичка.apply(target, heal_invisible_fly_potion)
self.assertEqual(60, target.health)
self.assertTrue(target.fly)
self.assertTrue(target.invisible)
пастичка.tick()
self.assertEqual(60, target.health)
self.assertTrue(target.fly)
self.assertTrue(target.invisible)
пастичка.tick()
self.assertEqual(60, target.health)
self.assertTrue(target.fly)
self.assertTrue(target.invisible)
пастичка.tick()
self.assertEqual(30, target.health)
self.assertFalse(target.fly)
self.assertFalse(target.invisible)
def test_dimitrichka_with_strong_drugs(self):
power_potion = Potion(power, 2)
target = Target()
power_dimitrichka = ГоспожатаПоХимия()
power_dimitrichka.apply(target, power_potion)
self.assertEqual(200, target.power)
power_dimitrichka.tick()
power_dimitrichka.tick()
self.assertFalse(hasattr(target, 'power'))
def test_dimitrichka_with_one_rich_addict(self):
heal_strengthen_potion = Potion(heal, 2) * 2 + Potion(strengthen, 1)
grow_potion = Potion(grow, 2)
target = Target(size=10, health=10, strength=10)
narco = ГоспожатаПоХимия()
narco.apply(target, heal_strengthen_potion)
narco.tick()
narco.apply(target, grow_potion)
self.assertEqual(20, target.size)
self.assertEqual(30, target.health)
self.assertEqual(30, target.strength)
narco.tick()
self.assertEqual(20, target.size)
self.assertEqual(10, target.health)
self.assertEqual(10, target.strength)
narco.tick()
self.assertEqual(10, target.size)
self.assertEqual(10, target.health)
self.assertEqual(10, target.strength)
def test_dimitrichka_with_potion_that_add_attributes(self):
power_potion = Potion(power, 5)
target = Target()
narco = ГоспожатаПоХимия()
narco.apply(target, power_potion)
self.assertEqual(200, target.power)
narco.tick()
narco.tick()
narco.tick()
narco.tick()
narco.tick()
self.assertFalse(hasattr(target, 'power'))
def test_dimitrichka_with_potion_that_removes_attributes(self):
fmi_potion = Potion({'insomnia': lambda _: delattr(_, 'sleep')}, 3)
student = Target(sleep='lovely')
narco = ГоспожатаПоХимия()
narco.apply(student, fmi_potion)
self.assertFalse(hasattr(student, 'sleep'))
narco.tick()
narco.tick()
narco.tick()
self.assertTrue('lovely', student.sleep)
```
|
Мирослав Стояновски
05.12.2023 01:39https://ibb.co/vm2T7bK
В този пример, защо на последния ред пише, че се хвърля Attribute Error ? Тъй като на първия ред, когато правим пречистването, grow_and_immunity_potion и grow_potion и двете отвари имат grow ефект в себе си, и на двете grow ефекта е с интензитет 1, когато се извадят в получената отвара би трябвало да има grow ефект с интензитет 0(По условие, само ефекти с интензитети < 0 се трият, другите остават). След това, когато извикаме purified_immunity_potion.grow(target), се вика ефект с интензитет 0. Тогава би трябвало да не се хвърля никаква грешка, а да се изпълни ефекта 0 пъти. Защо се хвърля Attribute Error ?
|
Димитър Христов
04.12.2023 23:40https://www.youtube.com/watch?v=R_FQU4KzN7A&ab_channel=JustinKuritzkes
|
Даниел Йорданов
04.12.2023 22:57При операцията пречистване, ако и двете страни на '-' съдържат един и същ вече използван ефект, то трябва ли да
сравняваме техните интензитети(както правим при неизползваните ефекти), за да решим дали да изтрием дадения такъв
("Ако отварата отдясно има по-голям интензитет, не получаваме негативен такъв а считаме ефектът за изцяло премахнат. Не с интензитет 0, изцяло премахнат."),
тъй като говорихме, че интензитетът на използваните ефекти може да бъде разгледан като нула.
Или винаги използваните ефекти не подлежат на сравнение и биват премахвани при тази операция?
|
Виктор Бечев
04.12.2023 22:49Напълно възможно е.
|
Мирослав Стояновски
04.12.2023 22:35Възможно ли е модифицираните от Potion-ки атрибути да бъдат от тип, различен от число ? Тоест възможно ли е target да има нечислен атрибут, и някой Potion да го модифицира ?
|
Георги Кунчев
04.12.2023 22:33В този сценарий правилният вариант е вариант 1.
|