1import re
2
3
4class Santa:
5 _instance = None
6
7 def __new__(cls):
8 if cls._instance is None:
9 cls._instance = super(Santa, cls).__new__(cls)
10 return cls._instance
11
12 def __init__(self):
13 self.kids_requested = []
14 self.requested_presents = []
15 self.all_kids_ages = []
16
17 def __valid_kid_age(self, kid):
18 for small_kid in self.all_kids_ages:
19 if small_kid[0] == kid:
20 return False if small_kid[1] > 5 else True
21 return True
22
23 def __call__(self, kid, wish):
24 match = re.search(r"([\'\"])[a-zA-Z0-9 ]*(\1)", wish)
25
26 if match:
27 present = match.group(0).strip("'\"")
28
29 for index, kid_requested in enumerate(self.kids_requested):
30 if kid == kid_requested:
31 self.requested_presents[index] = present
32 break
33 else:
34 self.kids_requested.append(kid)
35 self.requested_presents.append(present)
36 else:
37 raise ValueError("Error in searching for requested present")
38
39 def __matmul__(self, wish):
40 present_match = re.search(r"([\'\"])[a-zA-Z0-9 ]*(\1)", wish)
41 signature_line_match = re.search(r"^\s*\d+\s*$", wish, re.MULTILINE)
42
43 if present_match and signature_line_match:
44 present = present_match.group(0).strip("'\"")
45 signature = signature_line_match.group(0).strip()
46 kid = Kid.get_instance(signature)
47
48 for index, kid_requested in enumerate(self.kids_requested):
49 if kid == kid_requested:
50 self.requested_presents[index] = present
51 break
52 else:
53 self.kids_requested.append(kid)
54 self.requested_presents.append(present)
55 elif present_match:
56 raise ValueError("Error in searching for signature")
57 elif signature_line_match:
58 raise ValueError("Error in searching for requested present")
59
60 def __get_kids_not_requested(self):
61 kids_not_requested = []
62
63 for kid in Kid.get_all_instances():
64 for kid_requested in self.kids_requested:
65 if kid == kid_requested:
66 break
67 else:
68 kids_not_requested.append(kid)
69
70 return kids_not_requested
71
72 def __update_kid_age(self, kid_to_update):
73 for index, (kid, age) in enumerate(self.all_kids_ages):
74 if kid == kid_to_update:
75 self.all_kids_ages[index][1] += 1
76 break
77 else:
78 self.all_kids_ages.append([kid_to_update, 1])
79
80 def xmas(self):
81 if len(self.kids_requested) == 0:
82 for kid in Kid.get_all_instances():
83 self.__update_kid_age(kid)
84 return
85
86 for index, kid_requested in enumerate(self.kids_requested):
87 self.__update_kid_age(kid_requested)
88 if not self.__valid_kid_age(kid_requested):
89 continue
90
91 if getattr(kid_requested, "is_naughty", False) and kid_requested.is_naughty:
92 kid_requested("coal")
93 kid_requested.is_naughty = False
94 else:
95 kid_requested(self.requested_presents[index])
96
97 most_frequent_present = max(set(self.requested_presents), key=self.requested_presents.count)
98
99 for index, kid_not_requested in enumerate(self.__get_kids_not_requested()):
100 self.__update_kid_age(kid_not_requested)
101 if not self.__valid_kid_age(kid_not_requested):
102 continue
103
104 if getattr(kid_not_requested, "is_naughty", False) and kid_not_requested.is_naughty:
105 kid_not_requested("coal")
106 kid_not_requested.is_naughty = False
107 else:
108 kid_not_requested(most_frequent_present)
109
110 self.kids_requested = []
111 self.requested_presents = []
112
113 def __iter__(self):
114 return self.requested_presents.__iter__()
115
116
117class Kid(type):
118 _instances = []
119
120 def __new__(cls, name, bases, class_dict):
121 for attr_name, attr_value in class_dict.items():
122 if callable(attr_value) and not attr_name.startswith("_"):
123 class_dict[attr_name] = cls.wrap_method(attr_value)
124
125 return super().__new__(cls, name, bases, class_dict)
126
127 def __init__(cls, name, bases, dct):
128 if '__call__' not in dct:
129 raise NotImplementedError(f"Class {name} must implement __call__ method.")
130 super().__init__(name, bases, dct)
131
132 def __call__(cls, *args, **kwargs):
133 kid_instance = super().__call__(*args, **kwargs)
134 cls._instances.append(kid_instance)
135
136 return kid_instance
137
138 @staticmethod
139 def wrap_method(method):
140 def wrapped_method(self, *args, **kwargs):
141 result = 0
142
143 try:
144 result = method(self, *args, **kwargs)
145 except Exception:
146 self.is_naughty = True
147
148 return result
149
150 return wrapped_method
151
152 @classmethod
153 def get_instance(cls, identification):
154 for instance in cls._instances:
155 if id(instance) == int(identification):
156 return instance
157
158 raise ValueError("No instance with given identification")
159
160 @classmethod
161 def get_all_instances(cls):
162 return cls._instances[:]
.............F......
======================================================================
FAIL: test_xmass_naughty (test.TestSanta.test_xmass_naughty)
Test a Christmas with naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 222, in test_xmass_naughty
with self.assertRaises(ZeroDivisionError):
AssertionError: ZeroDivisionError not raised
----------------------------------------------------------------------
Ran 20 tests in 0.024s
FAILED (failures=1)
16.12.2024 10:38
16.12.2024 10:40
16.12.2024 10:41
16.12.2024 10:42
16.12.2024 10:43
16.12.2024 10:45
16.12.2024 10:46
16.12.2024 10:49
16.12.2024 10:51
16.12.2024 10:52
16.12.2024 10:53
16.12.2024 10:54
16.12.2024 10:57
16.12.2024 10:56
16.12.2024 10:56