1import re
2
3class Singleton(type):
4
5 _instances = {}
6
7 def __call__(cls, *args, **kwargs):
8 if cls not in cls._instances:
9 cls._instances[cls] = super().__call__(*args, **kwargs)
10 return cls._instances[cls]
11
12
13class Santa(metaclass=Singleton):
14
15 _presents = {}
16
17 def __init__(self):
18 pass
19
20 def __call__(self, kid, message):
21 wish = re.search(r'(?<=(["\']))(\s*\w*)+(?=\1)', message).group()
22 self._presents[kid] = wish
23
24 def __matmul__(self, letter):
25 signature = re.search(r'^\s*\d+\s*$', letter, re.M).group()
26 wish = re.search(r'(?<=(["\']))(\s*\w*)+(?=\1)', letter).group()
27 for kid in self._presents.keys():
28 if str(id(kid)) == signature:
29 self._presents[kid] = wish
30 break
31
32 def __iter__(self):
33 return iter(self._presents.values())
34
35 def _find_most_popular_present(self):
36 presents_popularity = {}
37 for present in self._presents.values():
38 if present:
39 val = presents_popularity.get(present, 0)
40 presents_popularity[present] = val + 1
41 if presents_popularity:
42 return max(presents_popularity, key=presents_popularity.get)
43 else:
44 return -1
45
46 def xmas(self):
47 self._presents = {kid : present for kid, present in self._presents.items() if kid.age < 5}
48 most_popular = self._find_most_popular_present()
49 if most_popular == -1:
50 for kid in self._presents.keys():
51 kid.age_up() # тъпо е да е тук, но уви
52 return
53 for kid, present in self._presents.items():
54 if kid.is_bad():
55 kid('coal')
56 else:
57 if present:
58 kid(present)
59 else:
60 kid(most_popular)
61 kid.age_up()
62 self._presents = {kid : None for kid in self._presents.keys()}
63
64 def add_kid(self, kid):
65 self._presents[kid] = None
66
67
68class Kid(type):
69
70 _santa = Santa()
71
72 def _exception_decorator(func):
73 def decorated(self, *args, **kwargs):
74 try:
75 return func(self, *args, **kwargs)
76 except Exception:
77 self._has_thrown_exception = True
78 raise
79 return decorated
80
81 def _age_up(kid):
82 kid.age += 1
83 kid._has_thrown_exception = False
84
85 def __new__(cls, name, bases, attr_dict):
86 if '__call__' not in attr_dict:
87 raise NotImplementedError
88 attr_dict['_has_thrown_exception'] = False
89 attr_dict['age'] = 0
90 attr_dict['age_up'] = lambda self: cls._age_up(self)
91 attr_dict['is_bad'] = lambda self: self._has_thrown_exception
92
93 for attr, value in attr_dict.items():
94 if not attr.startswith('_') and callable(value):
95 attr_dict[attr] = cls._exception_decorator(value)
96 return type.__new__(cls, name, bases, attr_dict)
97
98 def __call__(cls, *args, **kwds):
99 obj = super().__call__(*args, **kwds)
100 cls._santa.add_kid(obj)
101 return obj
......FFF...........
======================================================================
FAIL: test_present_matching (test.TestSanta.test_present_matching)
Test matching signature in the letter.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 92, in test_present_matching
self.assertEqual(list(self.santa), ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 '])
AssertionError: Lists differ: [None, None] != ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 ']
First differing element 0:
None
'toy4'
- [None, None]
+ ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 ']
======================================================================
FAIL: test_santa_gift_order (test.TestSanta.test_santa_gift_order)
Test ordering of the Santa iterator.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 260, in test_santa_gift_order
self.assertEqual(list(self.santa), ["toy2v2", "toy3", "toy1"])
AssertionError: Lists differ: ['toy1', 'toy2v2', 'toy3'] != ['toy2v2', 'toy3', 'toy1']
First differing element 0:
'toy1'
'toy2v2'
- ['toy1', 'toy2v2', 'toy3']
+ ['toy2v2', 'toy3', 'toy1']
======================================================================
FAIL: test_signature_matching (test.TestSanta.test_signature_matching)
Test matching present in the letter / call.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 118, in test_signature_matching
self.assertEqual(kid1.SECRET_PRESENT, 'toy1')
AssertionError: None != 'toy1'
----------------------------------------------------------------------
Ran 20 tests in 0.045s
FAILED (failures=3)
19.12.2024 15:27
19.12.2024 15:28
19.12.2024 15:28
19.12.2024 15:29
19.12.2024 15:31
19.12.2024 15:32