1import random
2import re
3import threading
4import time
5from collections import defaultdict, Counter, OrderedDict
6from datetime import datetime
7
8
9class CSI:
10 """Central Santa Intelligence."""
11
12 _instance = None
13 _naughty_list = defaultdict(OrderedDict)
14 _individuals_under_observation = {}
15
16 def __new__(cls, *args, **kwargs):
17 """There can be only one CSI."""
18 if cls._instance is None:
19 cls._instance = super().__new__(cls, *args, **kwargs)
20 return cls._instance
21
22 @classmethod
23 def notify_about_new_baby(cls, individual):
24 """Here's your package of earthworms. How are Kevin and the kids?"""
25 cls._individuals_under_observation[id(individual)] = individual
26
27 def notify_about_transgression(method):
28 """CSI sees EVERYTHING."""
29 def decorated(*args, **kwargs):
30 try:
31 result = method(individual, *args, **kwargs)
32 except Exception as err:
33 time_of_naughtiness = datetime.now()
34 print(f"Individual {individual} has caused a problem at {time_of_naughtiness} - {err}.")
35 CSI._naughty_list[individual][time_of_naughtiness] = err
36 raise
37 return result
38 return decorated
39
40 for attr_name, obj in type(individual).__dict__.items():
41 if callable(obj) and not attr_name.startswith('_'):
42 setattr(individual, attr_name, notify_about_transgression(obj))
43
44 @property
45 def all_individuals(self):
46 return self._individuals_under_observation.values()
47
48 def identify_sender(self, text):
49 """Santa leaves espionage to the CSI."""
50 sender_id = int(match.group().strip() if (match := re.search(r'^\s*\d+\s*$', text, re.M)) else None)
51 return self._individuals_under_observation[sender_id]
52
53 def is_naughty(self, individual):
54 """Assess if the individual has erred this year."""
55 return individual in self._naughty_list
56
57 def prepare_for_next_christmass(self):
58 """Update the ages of people and give everyone another chance for the new year."""
59 self._naughty_list = defaultdict(OrderedDict)
60
61
62class Santa:
63 """Saint Nicholas... Or however he's called in your culture."""
64
65 _csi = CSI()
66 _wishes = OrderedDict()
67 _instance = None
68 _santas_private_list = {}
69
70 def __new__(cls, *args, **kwargs):
71 """There can be only one Santa!"""
72 if cls._instance is None:
73 cls._instance = super().__new__(cls, *args, **kwargs)
74 return cls._instance
75
76 def __call__(self, kid, request):
77 """Call santa with a gift request."""
78 self._wishes[kid] = self._extract_gift(request)
79
80 def __matmul__(self, letter):
81 """Write a letter to Santa."""
82 kid = self._csi.identify_sender(letter)
83 self._wishes[kid] = self._extract_gift(letter)
84
85 def __iter__(self):
86 """Santa is iterable, if you didn't know."""
87 return iter(self._wishes.values())
88
89 def _extract_gift(self, text):
90 """Santa takes notes of all gifts."""
91 return match.group() if (match := re.search(r'(?<=[\'"])[a-zA-Z\d\s]+?(?=[\'"])', text)) else None
92
93 def xmas(self):
94 """Deliver gifts."""
95 most_wanted = common[0][0] if (common := Counter(self._wishes.values()).most_common()) else None
96 # Make sure to give presents to the ones who called or sent letters first
97 kids_with_wishes = list(self._wishes.keys())
98 kids_without_wishes = list(set(self._csi.all_individuals) - set(kids_with_wishes))
99 for kid in kids_with_wishes + kids_without_wishes:
100 if kid.age >= 18 and self._csi.is_naughty(kid):
101 self._santas_private_list.add(kid)
102 continue
103 # If there weren't any wishes, Santa doesn't care anymore and he's a bit sad
104 if kids_with_wishes and kid.age < 5:
105 if self._csi.is_naughty(kid):
106 present = 'coal'
107 else:
108 present = self._wishes.get(kid, most_wanted)
109 kid(present)
110 else:
111 kid(None) # A Christmas is a Christmas even without the presents
112 self._prepare_for_next_christmass()
113
114 def _prepare_for_next_christmass(self):
115 """Prepare for next Christmas by giving everyone the benefit of the doubt."""
116 self._csi.prepare_for_next_christmass()
117 self._wishes = OrderedDict()
118
119
120class Kid(type):
121
122 @staticmethod
123 def _better_init(original_init):
124 """Because sometimes people need a push in the right direction."""
125 def decorated(self, *args, **kwargs):
126 original_init(self, *args, **kwargs)
127 Person.__init__(self)
128 return decorated
129
130 @staticmethod
131 def _better_new(*genetic_information):
132 """Because this is how babies are made, canonically speaking."""
133 return Stork.deliver_baby(genetic_information)
134
135 @staticmethod
136 def _better_call(original_call): # Saul
137 """Add an increase of age to the original call."""
138 def decorated(self, *args, **kwargs):
139 result = original_call(self, *args, **kwargs)
140 self.age += 1
141 return result
142 return decorated
143
144 def __new__(cls, name, bases, attr_dict):
145 """Create a type of kid."""
146 if '__call__' not in attr_dict:
147 raise NotImplementedError
148 attr_dict['__init__'] = cls._better_init(attr_dict.get('__init__', lambda _: None))
149 attr_dict['__new__'] = cls._better_new
150 attr_dict['__call__'] = cls._better_call(attr_dict['__call__'])
151 return super().__new__(cls, name, bases + (Person,), attr_dict)
152
153
154class Person:
155 """What is a person?"""
156
157 def __init__(self):
158 """Initialize age for each person."""
159 self.age = 0
160
161 def __hash__(self):
162 """Can you hash a person?"""
163 return hash(id(self))
164
165
166class Stork:
167 """A main worker in the baby-delivery service."""
168
169 _available_storks = []
170
171 def __init__(self):
172 """Initialize carrying space for babies for the current stork."""
173 self.baby = []
174
175 def _procure_a_baby(self, genetic_information):
176 """Where from? No idea."""
177 # Part of an old implementation, left here only for the joke
178 # self.baby = [Baby('Baby', tuple(type(parent) for parent in parents), ({}))] # He-he
179 self.baby = [object.__new__(*genetic_information)]
180 self._____notify_CSI()
181
182 def _____notify_CSI(self):
183 """Nothing to see here, move along."""
184 CSI.notify_about_new_baby(self.baby[0])
185
186 def _deliver_baby(self):
187 """Hehe, *pop*."""
188 return self.baby.pop()
189
190 @classmethod
191 def deliver_baby(cls, genetic_information):
192 """Deliver a baby to the happy parents."""
193 threading.Thread(target=cls._request_storks).start()
194 while not cls._available_storks:
195 print("There are no storks available, please wait as your call is important to us!")
196 time.sleep(0.03)
197 return cls._dispatch_stork(genetic_information)
198
199 @classmethod
200 def _request_storks(cls):
201 """Request for adding storks to the stork pool."""
202 time.sleep(0.09)
203 storks = [cls() for _ in range(random.randint(1, 10))]
204 cls._available_storks.extend(storks)
205 print("Thank you for your patience. Storks are ready for dispatch!")
206
207 @classmethod
208 def _dispatch_stork(cls, genetic_information):
209 """Dispatch an available stork in the area."""
210 stork_index = random.randint(0, len(cls._available_storks) - 1)
211 stork = cls._available_storks.pop(stork_index)
212 stork._procure_a_baby(genetic_information)
213 print("Stork dispatched, please wait for your delivery.")
214 return stork._deliver_baby()
Timed out.
Георги Кунчев
19.12.2024 15:46I've got you, bro!
Here - take these 10 bonus points.
|
Виктор Бечев
19.12.2024 14:32Лол, това заслужавам, таймаут. :rofl:
|
| f | 1 | import random | f | 1 | import random |
| 2 | import re | 2 | import re | ||
| 3 | import threading | 3 | import threading | ||
| 4 | import time | 4 | import time | ||
| 5 | from collections import defaultdict, Counter, OrderedDict | 5 | from collections import defaultdict, Counter, OrderedDict | ||
| 6 | from datetime import datetime | 6 | from datetime import datetime | ||
| 7 | 7 | ||||
| 8 | 8 | ||||
| 9 | class CSI: | 9 | class CSI: | ||
| 10 | """Central Santa Intelligence.""" | 10 | """Central Santa Intelligence.""" | ||
| 11 | 11 | ||||
| 12 | _instance = None | 12 | _instance = None | ||
| 13 | _naughty_list = defaultdict(OrderedDict) | 13 | _naughty_list = defaultdict(OrderedDict) | ||
| 14 | _individuals_under_observation = {} | 14 | _individuals_under_observation = {} | ||
| 15 | 15 | ||||
| 16 | def __new__(cls, *args, **kwargs): | 16 | def __new__(cls, *args, **kwargs): | ||
| 17 | """There can be only one CSI.""" | 17 | """There can be only one CSI.""" | ||
| 18 | if cls._instance is None: | 18 | if cls._instance is None: | ||
| 19 | cls._instance = super().__new__(cls, *args, **kwargs) | 19 | cls._instance = super().__new__(cls, *args, **kwargs) | ||
| 20 | return cls._instance | 20 | return cls._instance | ||
| 21 | 21 | ||||
| 22 | @classmethod | 22 | @classmethod | ||
| 23 | def notify_about_new_baby(cls, individual): | 23 | def notify_about_new_baby(cls, individual): | ||
| 24 | """Here's your package of earthworms. How are Kevin and the kids?""" | 24 | """Here's your package of earthworms. How are Kevin and the kids?""" | ||
| 25 | cls._individuals_under_observation[id(individual)] = individual | 25 | cls._individuals_under_observation[id(individual)] = individual | ||
| 26 | 26 | ||||
| 27 | def notify_about_transgression(method): | 27 | def notify_about_transgression(method): | ||
| 28 | """CSI sees EVERYTHING.""" | 28 | """CSI sees EVERYTHING.""" | ||
| 29 | def decorated(*args, **kwargs): | 29 | def decorated(*args, **kwargs): | ||
| 30 | try: | 30 | try: | ||
| 31 | result = method(individual, *args, **kwargs) | 31 | result = method(individual, *args, **kwargs) | ||
| 32 | except Exception as err: | 32 | except Exception as err: | ||
| 33 | time_of_naughtiness = datetime.now() | 33 | time_of_naughtiness = datetime.now() | ||
| 34 | print(f"Individual {individual} has caused a problem at {time_of_naughtiness} - {err}.") | 34 | print(f"Individual {individual} has caused a problem at {time_of_naughtiness} - {err}.") | ||
| 35 | CSI._naughty_list[individual][time_of_naughtiness] = err | 35 | CSI._naughty_list[individual][time_of_naughtiness] = err | ||
| 36 | raise | 36 | raise | ||
| 37 | return result | 37 | return result | ||
| 38 | return decorated | 38 | return decorated | ||
| 39 | 39 | ||||
| 40 | for attr_name, obj in type(individual).__dict__.items(): | 40 | for attr_name, obj in type(individual).__dict__.items(): | ||
| 41 | if callable(obj) and not attr_name.startswith('_'): | 41 | if callable(obj) and not attr_name.startswith('_'): | ||
| 42 | setattr(individual, attr_name, notify_about_transgression(obj)) | 42 | setattr(individual, attr_name, notify_about_transgression(obj)) | ||
| 43 | 43 | ||||
| 44 | @property | 44 | @property | ||
| 45 | def all_individuals(self): | 45 | def all_individuals(self): | ||
| 46 | return self._individuals_under_observation.values() | 46 | return self._individuals_under_observation.values() | ||
| 47 | 47 | ||||
| 48 | def identify_sender(self, text): | 48 | def identify_sender(self, text): | ||
| 49 | """Santa leaves espionage to the CSI.""" | 49 | """Santa leaves espionage to the CSI.""" | ||
| 50 | sender_id = int(match.group().strip() if (match := re.search(r'^\s*\d+\s*$', text, re.M)) else None) | 50 | sender_id = int(match.group().strip() if (match := re.search(r'^\s*\d+\s*$', text, re.M)) else None) | ||
| 51 | return self._individuals_under_observation[sender_id] | 51 | return self._individuals_under_observation[sender_id] | ||
| 52 | 52 | ||||
| 53 | def is_naughty(self, individual): | 53 | def is_naughty(self, individual): | ||
| 54 | """Assess if the individual has erred this year.""" | 54 | """Assess if the individual has erred this year.""" | ||
| 55 | return individual in self._naughty_list | 55 | return individual in self._naughty_list | ||
| 56 | 56 | ||||
| 57 | def prepare_for_next_christmass(self): | 57 | def prepare_for_next_christmass(self): | ||
| 58 | """Update the ages of people and give everyone another chance for the new year.""" | 58 | """Update the ages of people and give everyone another chance for the new year.""" | ||
| 59 | self._naughty_list = defaultdict(OrderedDict) | 59 | self._naughty_list = defaultdict(OrderedDict) | ||
| 60 | 60 | ||||
| 61 | 61 | ||||
| 62 | class Santa: | 62 | class Santa: | ||
| 63 | """Saint Nicholas... Or however he's called in your culture.""" | 63 | """Saint Nicholas... Or however he's called in your culture.""" | ||
| 64 | 64 | ||||
| 65 | _csi = CSI() | 65 | _csi = CSI() | ||
| 66 | _wishes = OrderedDict() | 66 | _wishes = OrderedDict() | ||
| 67 | _instance = None | 67 | _instance = None | ||
| 68 | _santas_private_list = {} | 68 | _santas_private_list = {} | ||
| 69 | 69 | ||||
| 70 | def __new__(cls, *args, **kwargs): | 70 | def __new__(cls, *args, **kwargs): | ||
| 71 | """There can be only one Santa!""" | 71 | """There can be only one Santa!""" | ||
| 72 | if cls._instance is None: | 72 | if cls._instance is None: | ||
| 73 | cls._instance = super().__new__(cls, *args, **kwargs) | 73 | cls._instance = super().__new__(cls, *args, **kwargs) | ||
| 74 | return cls._instance | 74 | return cls._instance | ||
| 75 | 75 | ||||
| 76 | def __call__(self, kid, request): | 76 | def __call__(self, kid, request): | ||
| 77 | """Call santa with a gift request.""" | 77 | """Call santa with a gift request.""" | ||
| 78 | self._wishes[kid] = self._extract_gift(request) | 78 | self._wishes[kid] = self._extract_gift(request) | ||
| 79 | 79 | ||||
| 80 | def __matmul__(self, letter): | 80 | def __matmul__(self, letter): | ||
| 81 | """Write a letter to Santa.""" | 81 | """Write a letter to Santa.""" | ||
| 82 | kid = self._csi.identify_sender(letter) | 82 | kid = self._csi.identify_sender(letter) | ||
| 83 | self._wishes[kid] = self._extract_gift(letter) | 83 | self._wishes[kid] = self._extract_gift(letter) | ||
| 84 | 84 | ||||
| 85 | def __iter__(self): | 85 | def __iter__(self): | ||
| 86 | """Santa is iterable, if you didn't know.""" | 86 | """Santa is iterable, if you didn't know.""" | ||
| 87 | return iter(self._wishes.values()) | 87 | return iter(self._wishes.values()) | ||
| 88 | 88 | ||||
| 89 | def _extract_gift(self, text): | 89 | def _extract_gift(self, text): | ||
| 90 | """Santa takes notes of all gifts.""" | 90 | """Santa takes notes of all gifts.""" | ||
| 91 | return match.group() if (match := re.search(r'(?<=[\'"])[a-zA-Z\d\s]+?(?=[\'"])', text)) else None | 91 | return match.group() if (match := re.search(r'(?<=[\'"])[a-zA-Z\d\s]+?(?=[\'"])', text)) else None | ||
| 92 | 92 | ||||
| 93 | def xmas(self): | 93 | def xmas(self): | ||
| 94 | """Deliver gifts.""" | 94 | """Deliver gifts.""" | ||
| 95 | most_wanted = common[0][0] if (common := Counter(self._wishes.values()).most_common()) else None | 95 | most_wanted = common[0][0] if (common := Counter(self._wishes.values()).most_common()) else None | ||
| 96 | # Make sure to give presents to the ones who called or sent letters first | 96 | # Make sure to give presents to the ones who called or sent letters first | ||
| 97 | kids_with_wishes = list(self._wishes.keys()) | 97 | kids_with_wishes = list(self._wishes.keys()) | ||
| 98 | kids_without_wishes = list(set(self._csi.all_individuals) - set(kids_with_wishes)) | 98 | kids_without_wishes = list(set(self._csi.all_individuals) - set(kids_with_wishes)) | ||
| 99 | for kid in kids_with_wishes + kids_without_wishes: | 99 | for kid in kids_with_wishes + kids_without_wishes: | ||
| 100 | if kid.age >= 18 and self._csi.is_naughty(kid): | 100 | if kid.age >= 18 and self._csi.is_naughty(kid): | ||
| 101 | self._santas_private_list.add(kid) | 101 | self._santas_private_list.add(kid) | ||
| 102 | continue | 102 | continue | ||
| 103 | # If there weren't any wishes, Santa doesn't care anymore and he's a bit sad | 103 | # If there weren't any wishes, Santa doesn't care anymore and he's a bit sad | ||
| 104 | if kids_with_wishes and kid.age < 5: | 104 | if kids_with_wishes and kid.age < 5: | ||
| 105 | if self._csi.is_naughty(kid): | 105 | if self._csi.is_naughty(kid): | ||
| 106 | present = 'coal' | 106 | present = 'coal' | ||
| 107 | else: | 107 | else: | ||
| 108 | present = self._wishes.get(kid, most_wanted) | 108 | present = self._wishes.get(kid, most_wanted) | ||
| 109 | kid(present) | 109 | kid(present) | ||
| 110 | else: | 110 | else: | ||
| 111 | kid(None) # A Christmas is a Christmas even without the presents | 111 | kid(None) # A Christmas is a Christmas even without the presents | ||
| 112 | self._prepare_for_next_christmass() | 112 | self._prepare_for_next_christmass() | ||
| 113 | 113 | ||||
| 114 | def _prepare_for_next_christmass(self): | 114 | def _prepare_for_next_christmass(self): | ||
| 115 | """Prepare for next Christmas by giving everyone the benefit of the doubt.""" | 115 | """Prepare for next Christmas by giving everyone the benefit of the doubt.""" | ||
| 116 | self._csi.prepare_for_next_christmass() | 116 | self._csi.prepare_for_next_christmass() | ||
| 117 | self._wishes = OrderedDict() | 117 | self._wishes = OrderedDict() | ||
| 118 | 118 | ||||
| 119 | 119 | ||||
| 120 | class Kid(type): | 120 | class Kid(type): | ||
| 121 | 121 | ||||
| 122 | @staticmethod | 122 | @staticmethod | ||
| 123 | def _better_init(original_init): | 123 | def _better_init(original_init): | ||
| 124 | """Because sometimes people need a push in the right direction.""" | 124 | """Because sometimes people need a push in the right direction.""" | ||
| 125 | def decorated(self, *args, **kwargs): | 125 | def decorated(self, *args, **kwargs): | ||
| 126 | original_init(self, *args, **kwargs) | 126 | original_init(self, *args, **kwargs) | ||
| 127 | Person.__init__(self) | 127 | Person.__init__(self) | ||
| 128 | return decorated | 128 | return decorated | ||
| 129 | 129 | ||||
| 130 | @staticmethod | 130 | @staticmethod | ||
| 131 | def _better_new(*genetic_information): | 131 | def _better_new(*genetic_information): | ||
| 132 | """Because this is how babies are made, canonically speaking.""" | 132 | """Because this is how babies are made, canonically speaking.""" | ||
| 133 | return Stork.deliver_baby(genetic_information) | 133 | return Stork.deliver_baby(genetic_information) | ||
| 134 | 134 | ||||
| 135 | @staticmethod | 135 | @staticmethod | ||
| 136 | def _better_call(original_call): # Saul | 136 | def _better_call(original_call): # Saul | ||
| 137 | """Add an increase of age to the original call.""" | 137 | """Add an increase of age to the original call.""" | ||
| 138 | def decorated(self, *args, **kwargs): | 138 | def decorated(self, *args, **kwargs): | ||
| 139 | result = original_call(self, *args, **kwargs) | 139 | result = original_call(self, *args, **kwargs) | ||
| 140 | self.age += 1 | 140 | self.age += 1 | ||
| 141 | return result | 141 | return result | ||
| 142 | return decorated | 142 | return decorated | ||
| 143 | 143 | ||||
| 144 | def __new__(cls, name, bases, attr_dict): | 144 | def __new__(cls, name, bases, attr_dict): | ||
| 145 | """Create a type of kid.""" | 145 | """Create a type of kid.""" | ||
| 146 | if '__call__' not in attr_dict: | 146 | if '__call__' not in attr_dict: | ||
| 147 | raise NotImplementedError | 147 | raise NotImplementedError | ||
| 148 | attr_dict['__init__'] = cls._better_init(attr_dict.get('__init__', lambda _: None)) | 148 | attr_dict['__init__'] = cls._better_init(attr_dict.get('__init__', lambda _: None)) | ||
| 149 | attr_dict['__new__'] = cls._better_new | 149 | attr_dict['__new__'] = cls._better_new | ||
| 150 | attr_dict['__call__'] = cls._better_call(attr_dict['__call__']) | 150 | attr_dict['__call__'] = cls._better_call(attr_dict['__call__']) | ||
| 151 | return super().__new__(cls, name, bases + (Person,), attr_dict) | 151 | return super().__new__(cls, name, bases + (Person,), attr_dict) | ||
| 152 | 152 | ||||
| 153 | 153 | ||||
| 154 | class Person: | 154 | class Person: | ||
| 155 | """What is a person?""" | 155 | """What is a person?""" | ||
| 156 | 156 | ||||
| 157 | def __init__(self): | 157 | def __init__(self): | ||
| 158 | """Initialize age for each person.""" | 158 | """Initialize age for each person.""" | ||
| 159 | self.age = 0 | 159 | self.age = 0 | ||
| 160 | 160 | ||||
| 161 | def __hash__(self): | 161 | def __hash__(self): | ||
| 162 | """Can you hash a person?""" | 162 | """Can you hash a person?""" | ||
| 163 | return hash(id(self)) | 163 | return hash(id(self)) | ||
| 164 | 164 | ||||
| 165 | 165 | ||||
| 166 | class Stork: | 166 | class Stork: | ||
| 167 | """A main worker in the baby-delivery service.""" | 167 | """A main worker in the baby-delivery service.""" | ||
| 168 | 168 | ||||
| 169 | _available_storks = [] | 169 | _available_storks = [] | ||
| 170 | 170 | ||||
| 171 | def __init__(self): | 171 | def __init__(self): | ||
| 172 | """Initialize carrying space for babies for the current stork.""" | 172 | """Initialize carrying space for babies for the current stork.""" | ||
| 173 | self.baby = [] | 173 | self.baby = [] | ||
| 174 | 174 | ||||
| 175 | def _procure_a_baby(self, genetic_information): | 175 | def _procure_a_baby(self, genetic_information): | ||
| 176 | """Where from? No idea.""" | 176 | """Where from? No idea.""" | ||
| 177 | # Part of an old implementation, left here only for the joke | 177 | # Part of an old implementation, left here only for the joke | ||
| 178 | # self.baby = [Baby('Baby', tuple(type(parent) for parent in parents), ({}))] # He-he | 178 | # self.baby = [Baby('Baby', tuple(type(parent) for parent in parents), ({}))] # He-he | ||
| 179 | self.baby = [object.__new__(*genetic_information)] | 179 | self.baby = [object.__new__(*genetic_information)] | ||
| 180 | self._____notify_CSI() | 180 | self._____notify_CSI() | ||
| 181 | 181 | ||||
| 182 | def _____notify_CSI(self): | 182 | def _____notify_CSI(self): | ||
| t | 183 | """Nothing to see here, move along,""" | t | 183 | """Nothing to see here, move along.""" |
| 184 | CSI.notify_about_new_baby(self.baby[0]) | 184 | CSI.notify_about_new_baby(self.baby[0]) | ||
| 185 | 185 | ||||
| 186 | def _deliver_baby(self): | 186 | def _deliver_baby(self): | ||
| 187 | """Hehe, *pop*.""" | 187 | """Hehe, *pop*.""" | ||
| 188 | return self.baby.pop() | 188 | return self.baby.pop() | ||
| 189 | 189 | ||||
| 190 | @classmethod | 190 | @classmethod | ||
| 191 | def deliver_baby(cls, genetic_information): | 191 | def deliver_baby(cls, genetic_information): | ||
| 192 | """Deliver a baby to the happy parents.""" | 192 | """Deliver a baby to the happy parents.""" | ||
| 193 | threading.Thread(target=cls._request_storks).start() | 193 | threading.Thread(target=cls._request_storks).start() | ||
| 194 | while not cls._available_storks: | 194 | while not cls._available_storks: | ||
| 195 | print("There are no storks available, please wait as your call is important to us!") | 195 | print("There are no storks available, please wait as your call is important to us!") | ||
| 196 | time.sleep(0.03) | 196 | time.sleep(0.03) | ||
| 197 | return cls._dispatch_stork(genetic_information) | 197 | return cls._dispatch_stork(genetic_information) | ||
| 198 | 198 | ||||
| 199 | @classmethod | 199 | @classmethod | ||
| 200 | def _request_storks(cls): | 200 | def _request_storks(cls): | ||
| 201 | """Request for adding storks to the stork pool.""" | 201 | """Request for adding storks to the stork pool.""" | ||
| 202 | time.sleep(0.09) | 202 | time.sleep(0.09) | ||
| 203 | storks = [cls() for _ in range(random.randint(1, 10))] | 203 | storks = [cls() for _ in range(random.randint(1, 10))] | ||
| 204 | cls._available_storks.extend(storks) | 204 | cls._available_storks.extend(storks) | ||
| 205 | print("Thank you for your patience. Storks are ready for dispatch!") | 205 | print("Thank you for your patience. Storks are ready for dispatch!") | ||
| 206 | 206 | ||||
| 207 | @classmethod | 207 | @classmethod | ||
| 208 | def _dispatch_stork(cls, genetic_information): | 208 | def _dispatch_stork(cls, genetic_information): | ||
| 209 | """Dispatch an available stork in the area.""" | 209 | """Dispatch an available stork in the area.""" | ||
| 210 | stork_index = random.randint(0, len(cls._available_storks) - 1) | 210 | stork_index = random.randint(0, len(cls._available_storks) - 1) | ||
| 211 | stork = cls._available_storks.pop(stork_index) | 211 | stork = cls._available_storks.pop(stork_index) | ||
| 212 | stork._procure_a_baby(genetic_information) | 212 | stork._procure_a_baby(genetic_information) | ||
| 213 | print("Stork dispatched, please wait for your delivery.") | 213 | print("Stork dispatched, please wait for your delivery.") | ||
| 214 | return stork._deliver_baby() | 214 | return stork._deliver_baby() |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import random | f | 1 | import random |
| 2 | import re | 2 | import re | ||
| 3 | import threading | 3 | import threading | ||
| 4 | import time | 4 | import time | ||
| 5 | from collections import defaultdict, Counter, OrderedDict | 5 | from collections import defaultdict, Counter, OrderedDict | ||
| 6 | from datetime import datetime | 6 | from datetime import datetime | ||
| 7 | 7 | ||||
| 8 | 8 | ||||
| 9 | class CSI: | 9 | class CSI: | ||
| 10 | """Central Santa Intelligence.""" | 10 | """Central Santa Intelligence.""" | ||
| 11 | 11 | ||||
| 12 | _instance = None | 12 | _instance = None | ||
| 13 | _naughty_list = defaultdict(OrderedDict) | 13 | _naughty_list = defaultdict(OrderedDict) | ||
| 14 | _individuals_under_observation = {} | 14 | _individuals_under_observation = {} | ||
| 15 | 15 | ||||
| 16 | def __new__(cls, *args, **kwargs): | 16 | def __new__(cls, *args, **kwargs): | ||
| 17 | """There can be only one CSI.""" | 17 | """There can be only one CSI.""" | ||
| 18 | if cls._instance is None: | 18 | if cls._instance is None: | ||
| 19 | cls._instance = super().__new__(cls, *args, **kwargs) | 19 | cls._instance = super().__new__(cls, *args, **kwargs) | ||
| 20 | return cls._instance | 20 | return cls._instance | ||
| 21 | 21 | ||||
| 22 | @classmethod | 22 | @classmethod | ||
| 23 | def notify_about_new_baby(cls, individual): | 23 | def notify_about_new_baby(cls, individual): | ||
| 24 | """Here's your package of earthworms. How are Kevin and the kids?""" | 24 | """Here's your package of earthworms. How are Kevin and the kids?""" | ||
| 25 | cls._individuals_under_observation[id(individual)] = individual | 25 | cls._individuals_under_observation[id(individual)] = individual | ||
| 26 | 26 | ||||
| 27 | def notify_about_transgression(method): | 27 | def notify_about_transgression(method): | ||
| 28 | """CSI sees EVERYTHING.""" | 28 | """CSI sees EVERYTHING.""" | ||
| 29 | def decorated(*args, **kwargs): | 29 | def decorated(*args, **kwargs): | ||
| 30 | try: | 30 | try: | ||
| 31 | result = method(individual, *args, **kwargs) | 31 | result = method(individual, *args, **kwargs) | ||
| 32 | except Exception as err: | 32 | except Exception as err: | ||
| 33 | time_of_naughtiness = datetime.now() | 33 | time_of_naughtiness = datetime.now() | ||
| 34 | print(f"Individual {individual} has caused a problem at {time_of_naughtiness} - {err}.") | 34 | print(f"Individual {individual} has caused a problem at {time_of_naughtiness} - {err}.") | ||
| 35 | CSI._naughty_list[individual][time_of_naughtiness] = err | 35 | CSI._naughty_list[individual][time_of_naughtiness] = err | ||
| 36 | raise | 36 | raise | ||
| 37 | return result | 37 | return result | ||
| 38 | return decorated | 38 | return decorated | ||
| 39 | 39 | ||||
| 40 | for attr_name, obj in type(individual).__dict__.items(): | 40 | for attr_name, obj in type(individual).__dict__.items(): | ||
| 41 | if callable(obj) and not attr_name.startswith('_'): | 41 | if callable(obj) and not attr_name.startswith('_'): | ||
| 42 | setattr(individual, attr_name, notify_about_transgression(obj)) | 42 | setattr(individual, attr_name, notify_about_transgression(obj)) | ||
| 43 | 43 | ||||
| 44 | @property | 44 | @property | ||
| 45 | def all_individuals(self): | 45 | def all_individuals(self): | ||
| 46 | return self._individuals_under_observation.values() | 46 | return self._individuals_under_observation.values() | ||
| 47 | 47 | ||||
| 48 | def identify_sender(self, text): | 48 | def identify_sender(self, text): | ||
| 49 | """Santa leaves espionage to the CSI.""" | 49 | """Santa leaves espionage to the CSI.""" | ||
| 50 | sender_id = int(match.group().strip() if (match := re.search(r'^\s*\d+\s*$', text, re.M)) else None) | 50 | sender_id = int(match.group().strip() if (match := re.search(r'^\s*\d+\s*$', text, re.M)) else None) | ||
| 51 | return self._individuals_under_observation[sender_id] | 51 | return self._individuals_under_observation[sender_id] | ||
| 52 | 52 | ||||
| 53 | def is_naughty(self, individual): | 53 | def is_naughty(self, individual): | ||
| 54 | """Assess if the individual has erred this year.""" | 54 | """Assess if the individual has erred this year.""" | ||
| 55 | return individual in self._naughty_list | 55 | return individual in self._naughty_list | ||
| 56 | 56 | ||||
| 57 | def prepare_for_next_christmass(self): | 57 | def prepare_for_next_christmass(self): | ||
| 58 | """Update the ages of people and give everyone another chance for the new year.""" | 58 | """Update the ages of people and give everyone another chance for the new year.""" | ||
| 59 | self._naughty_list = defaultdict(OrderedDict) | 59 | self._naughty_list = defaultdict(OrderedDict) | ||
| 60 | 60 | ||||
| 61 | 61 | ||||
| 62 | class Santa: | 62 | class Santa: | ||
| 63 | """Saint Nicholas... Or however he's called in your culture.""" | 63 | """Saint Nicholas... Or however he's called in your culture.""" | ||
| 64 | 64 | ||||
| 65 | _csi = CSI() | 65 | _csi = CSI() | ||
| 66 | _wishes = OrderedDict() | 66 | _wishes = OrderedDict() | ||
| 67 | _instance = None | 67 | _instance = None | ||
| 68 | _santas_private_list = {} | 68 | _santas_private_list = {} | ||
| 69 | 69 | ||||
| 70 | def __new__(cls, *args, **kwargs): | 70 | def __new__(cls, *args, **kwargs): | ||
| 71 | """There can be only one Santa!""" | 71 | """There can be only one Santa!""" | ||
| 72 | if cls._instance is None: | 72 | if cls._instance is None: | ||
| 73 | cls._instance = super().__new__(cls, *args, **kwargs) | 73 | cls._instance = super().__new__(cls, *args, **kwargs) | ||
| 74 | return cls._instance | 74 | return cls._instance | ||
| 75 | 75 | ||||
| 76 | def __call__(self, kid, request): | 76 | def __call__(self, kid, request): | ||
| 77 | """Call santa with a gift request.""" | 77 | """Call santa with a gift request.""" | ||
| 78 | self._wishes[kid] = self._extract_gift(request) | 78 | self._wishes[kid] = self._extract_gift(request) | ||
| 79 | 79 | ||||
| 80 | def __matmul__(self, letter): | 80 | def __matmul__(self, letter): | ||
| 81 | """Write a letter to Santa.""" | 81 | """Write a letter to Santa.""" | ||
| 82 | kid = self._csi.identify_sender(letter) | 82 | kid = self._csi.identify_sender(letter) | ||
| 83 | self._wishes[kid] = self._extract_gift(letter) | 83 | self._wishes[kid] = self._extract_gift(letter) | ||
| 84 | 84 | ||||
| 85 | def __iter__(self): | 85 | def __iter__(self): | ||
| n | 86 | """Santa """ | n | 86 | """Santa is iterable, if you didn't know.""" |
| 87 | return iter(self._wishes.values()) | 87 | return iter(self._wishes.values()) | ||
| 88 | 88 | ||||
| 89 | def _extract_gift(self, text): | 89 | def _extract_gift(self, text): | ||
| 90 | """Santa takes notes of all gifts.""" | 90 | """Santa takes notes of all gifts.""" | ||
| 91 | return match.group() if (match := re.search(r'(?<=[\'"])[a-zA-Z\d\s]+?(?=[\'"])', text)) else None | 91 | return match.group() if (match := re.search(r'(?<=[\'"])[a-zA-Z\d\s]+?(?=[\'"])', text)) else None | ||
| 92 | 92 | ||||
| 93 | def xmas(self): | 93 | def xmas(self): | ||
| 94 | """Deliver gifts.""" | 94 | """Deliver gifts.""" | ||
| 95 | most_wanted = common[0][0] if (common := Counter(self._wishes.values()).most_common()) else None | 95 | most_wanted = common[0][0] if (common := Counter(self._wishes.values()).most_common()) else None | ||
| 96 | # Make sure to give presents to the ones who called or sent letters first | 96 | # Make sure to give presents to the ones who called or sent letters first | ||
| 97 | kids_with_wishes = list(self._wishes.keys()) | 97 | kids_with_wishes = list(self._wishes.keys()) | ||
| 98 | kids_without_wishes = list(set(self._csi.all_individuals) - set(kids_with_wishes)) | 98 | kids_without_wishes = list(set(self._csi.all_individuals) - set(kids_with_wishes)) | ||
| 99 | for kid in kids_with_wishes + kids_without_wishes: | 99 | for kid in kids_with_wishes + kids_without_wishes: | ||
| 100 | if kid.age >= 18 and self._csi.is_naughty(kid): | 100 | if kid.age >= 18 and self._csi.is_naughty(kid): | ||
| 101 | self._santas_private_list.add(kid) | 101 | self._santas_private_list.add(kid) | ||
| 102 | continue | 102 | continue | ||
| 103 | # If there weren't any wishes, Santa doesn't care anymore and he's a bit sad | 103 | # If there weren't any wishes, Santa doesn't care anymore and he's a bit sad | ||
| 104 | if kids_with_wishes and kid.age < 5: | 104 | if kids_with_wishes and kid.age < 5: | ||
| 105 | if self._csi.is_naughty(kid): | 105 | if self._csi.is_naughty(kid): | ||
| 106 | present = 'coal' | 106 | present = 'coal' | ||
| 107 | else: | 107 | else: | ||
| 108 | present = self._wishes.get(kid, most_wanted) | 108 | present = self._wishes.get(kid, most_wanted) | ||
| 109 | kid(present) | 109 | kid(present) | ||
| 110 | else: | 110 | else: | ||
| 111 | kid(None) # A Christmas is a Christmas even without the presents | 111 | kid(None) # A Christmas is a Christmas even without the presents | ||
| 112 | self._prepare_for_next_christmass() | 112 | self._prepare_for_next_christmass() | ||
| 113 | 113 | ||||
| 114 | def _prepare_for_next_christmass(self): | 114 | def _prepare_for_next_christmass(self): | ||
| 115 | """Prepare for next Christmas by giving everyone the benefit of the doubt.""" | 115 | """Prepare for next Christmas by giving everyone the benefit of the doubt.""" | ||
| 116 | self._csi.prepare_for_next_christmass() | 116 | self._csi.prepare_for_next_christmass() | ||
| 117 | self._wishes = OrderedDict() | 117 | self._wishes = OrderedDict() | ||
| 118 | 118 | ||||
| 119 | 119 | ||||
| 120 | class Kid(type): | 120 | class Kid(type): | ||
| 121 | 121 | ||||
| 122 | @staticmethod | 122 | @staticmethod | ||
| 123 | def _better_init(original_init): | 123 | def _better_init(original_init): | ||
| 124 | """Because sometimes people need a push in the right direction.""" | 124 | """Because sometimes people need a push in the right direction.""" | ||
| 125 | def decorated(self, *args, **kwargs): | 125 | def decorated(self, *args, **kwargs): | ||
| 126 | original_init(self, *args, **kwargs) | 126 | original_init(self, *args, **kwargs) | ||
| 127 | Person.__init__(self) | 127 | Person.__init__(self) | ||
| 128 | return decorated | 128 | return decorated | ||
| 129 | 129 | ||||
| 130 | @staticmethod | 130 | @staticmethod | ||
| 131 | def _better_new(*genetic_information): | 131 | def _better_new(*genetic_information): | ||
| 132 | """Because this is how babies are made, canonically speaking.""" | 132 | """Because this is how babies are made, canonically speaking.""" | ||
| 133 | return Stork.deliver_baby(genetic_information) | 133 | return Stork.deliver_baby(genetic_information) | ||
| 134 | 134 | ||||
| 135 | @staticmethod | 135 | @staticmethod | ||
| 136 | def _better_call(original_call): # Saul | 136 | def _better_call(original_call): # Saul | ||
| 137 | """Add an increase of age to the original call.""" | 137 | """Add an increase of age to the original call.""" | ||
| 138 | def decorated(self, *args, **kwargs): | 138 | def decorated(self, *args, **kwargs): | ||
| 139 | result = original_call(self, *args, **kwargs) | 139 | result = original_call(self, *args, **kwargs) | ||
| 140 | self.age += 1 | 140 | self.age += 1 | ||
| 141 | return result | 141 | return result | ||
| 142 | return decorated | 142 | return decorated | ||
| 143 | 143 | ||||
| 144 | def __new__(cls, name, bases, attr_dict): | 144 | def __new__(cls, name, bases, attr_dict): | ||
| 145 | """Create a type of kid.""" | 145 | """Create a type of kid.""" | ||
| 146 | if '__call__' not in attr_dict: | 146 | if '__call__' not in attr_dict: | ||
| 147 | raise NotImplementedError | 147 | raise NotImplementedError | ||
| 148 | attr_dict['__init__'] = cls._better_init(attr_dict.get('__init__', lambda _: None)) | 148 | attr_dict['__init__'] = cls._better_init(attr_dict.get('__init__', lambda _: None)) | ||
| 149 | attr_dict['__new__'] = cls._better_new | 149 | attr_dict['__new__'] = cls._better_new | ||
| 150 | attr_dict['__call__'] = cls._better_call(attr_dict['__call__']) | 150 | attr_dict['__call__'] = cls._better_call(attr_dict['__call__']) | ||
| 151 | return super().__new__(cls, name, bases + (Person,), attr_dict) | 151 | return super().__new__(cls, name, bases + (Person,), attr_dict) | ||
| 152 | 152 | ||||
| 153 | 153 | ||||
| 154 | class Person: | 154 | class Person: | ||
| 155 | """What is a person?""" | 155 | """What is a person?""" | ||
| 156 | 156 | ||||
| 157 | def __init__(self): | 157 | def __init__(self): | ||
| n | 158 | """Initialize default attributes for each person. | n | 158 | """Initialize age for each person.""" |
| 159 | |||||
| 160 | Although don't we all start life in love and then slowly | ||||
| 161 | fall out of love? | ||||
| 162 | """ | ||||
| 163 | self.age = 0 | 159 | self.age = 0 | ||
| t | 164 | self.in_love = False | t | ||
| 165 | 160 | ||||
| 166 | def __hash__(self): | 161 | def __hash__(self): | ||
| 167 | """Can you hash a person?""" | 162 | """Can you hash a person?""" | ||
| 168 | return hash(id(self)) | 163 | return hash(id(self)) | ||
| 169 | 164 | ||||
| 170 | 165 | ||||
| 171 | class Stork: | 166 | class Stork: | ||
| 172 | """A main worker in the baby-delivery service.""" | 167 | """A main worker in the baby-delivery service.""" | ||
| 173 | 168 | ||||
| 174 | _available_storks = [] | 169 | _available_storks = [] | ||
| 175 | 170 | ||||
| 176 | def __init__(self): | 171 | def __init__(self): | ||
| 177 | """Initialize carrying space for babies for the current stork.""" | 172 | """Initialize carrying space for babies for the current stork.""" | ||
| 178 | self.baby = [] | 173 | self.baby = [] | ||
| 179 | 174 | ||||
| 180 | def _procure_a_baby(self, genetic_information): | 175 | def _procure_a_baby(self, genetic_information): | ||
| 181 | """Where from? No idea.""" | 176 | """Where from? No idea.""" | ||
| 182 | # Part of an old implementation, left here only for the joke | 177 | # Part of an old implementation, left here only for the joke | ||
| 183 | # self.baby = [Baby('Baby', tuple(type(parent) for parent in parents), ({}))] # He-he | 178 | # self.baby = [Baby('Baby', tuple(type(parent) for parent in parents), ({}))] # He-he | ||
| 184 | self.baby = [object.__new__(*genetic_information)] | 179 | self.baby = [object.__new__(*genetic_information)] | ||
| 185 | self._____notify_CSI() | 180 | self._____notify_CSI() | ||
| 186 | 181 | ||||
| 187 | def _____notify_CSI(self): | 182 | def _____notify_CSI(self): | ||
| 188 | """Nothing to see here, move along,""" | 183 | """Nothing to see here, move along,""" | ||
| 189 | CSI.notify_about_new_baby(self.baby[0]) | 184 | CSI.notify_about_new_baby(self.baby[0]) | ||
| 190 | 185 | ||||
| 191 | def _deliver_baby(self): | 186 | def _deliver_baby(self): | ||
| 192 | """Hehe, *pop*.""" | 187 | """Hehe, *pop*.""" | ||
| 193 | return self.baby.pop() | 188 | return self.baby.pop() | ||
| 194 | 189 | ||||
| 195 | @classmethod | 190 | @classmethod | ||
| 196 | def deliver_baby(cls, genetic_information): | 191 | def deliver_baby(cls, genetic_information): | ||
| 197 | """Deliver a baby to the happy parents.""" | 192 | """Deliver a baby to the happy parents.""" | ||
| 198 | threading.Thread(target=cls._request_storks).start() | 193 | threading.Thread(target=cls._request_storks).start() | ||
| 199 | while not cls._available_storks: | 194 | while not cls._available_storks: | ||
| 200 | print("There are no storks available, please wait as your call is important to us!") | 195 | print("There are no storks available, please wait as your call is important to us!") | ||
| 201 | time.sleep(0.03) | 196 | time.sleep(0.03) | ||
| 202 | return cls._dispatch_stork(genetic_information) | 197 | return cls._dispatch_stork(genetic_information) | ||
| 203 | 198 | ||||
| 204 | @classmethod | 199 | @classmethod | ||
| 205 | def _request_storks(cls): | 200 | def _request_storks(cls): | ||
| 206 | """Request for adding storks to the stork pool.""" | 201 | """Request for adding storks to the stork pool.""" | ||
| 207 | time.sleep(0.09) | 202 | time.sleep(0.09) | ||
| 208 | storks = [cls() for _ in range(random.randint(1, 10))] | 203 | storks = [cls() for _ in range(random.randint(1, 10))] | ||
| 209 | cls._available_storks.extend(storks) | 204 | cls._available_storks.extend(storks) | ||
| 210 | print("Thank you for your patience. Storks are ready for dispatch!") | 205 | print("Thank you for your patience. Storks are ready for dispatch!") | ||
| 211 | 206 | ||||
| 212 | @classmethod | 207 | @classmethod | ||
| 213 | def _dispatch_stork(cls, genetic_information): | 208 | def _dispatch_stork(cls, genetic_information): | ||
| 214 | """Dispatch an available stork in the area.""" | 209 | """Dispatch an available stork in the area.""" | ||
| 215 | stork_index = random.randint(0, len(cls._available_storks) - 1) | 210 | stork_index = random.randint(0, len(cls._available_storks) - 1) | ||
| 216 | stork = cls._available_storks.pop(stork_index) | 211 | stork = cls._available_storks.pop(stork_index) | ||
| 217 | stork._procure_a_baby(genetic_information) | 212 | stork._procure_a_baby(genetic_information) | ||
| 218 | print("Stork dispatched, please wait for your delivery.") | 213 | print("Stork dispatched, please wait for your delivery.") | ||
| 219 | return stork._deliver_baby() | 214 | return stork._deliver_baby() |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
19.12.2024 14:40