1import re
2from collections import defaultdict
3import random
4
5class Santa:
6 _instance = None
7 _children = set()
8
9 def __new__(cls, *args, **kwargs):
10 if not cls._instance:
11 cls._instance = super(Santa, cls).__new__(cls, *args, **kwargs)
12 cls._instance.gifts = []
13 cls._instance.requests = {}
14 cls._instance.xmas_count = 0
15 cls._instance.naughty = defaultdict(bool)
16 return cls._instance
17
18 def __call__(self, child, wish):
19 gift = self.extract_gift(wish)
20 if gift:
21 self.requests[child] = gift
22
23 def __matmul__(self, letter):
24 gift = self.extract_gift(letter)
25 signature = self.extract_signature(letter)
26 if gift and signature:
27 child = self.get_child_by_id(int(signature))
28 if child:
29 self.requests[child] = gift
30
31 @staticmethod
32 def extract_gift(text):
33 match = re.search(r'"([A-Za-z0-9 ]+)"|\'([A-Za-z0-9 ]+)\'', text)
34 if match:
35 return match.group(1) or match.group(2)
36 return None
37
38 @staticmethod
39 def extract_signature(text):
40 match = re.search(r'^\s*([0-9]+)\s*$', text, re.MULTILINE)
41 if match:
42 return match.group(1)
43 return None
44
45 @classmethod
46 def register_child(cls, child):
47 cls._children.add(child)
48
49 @classmethod
50 def get_child_by_id(cls, child_id):
51 for child in cls._children:
52 if id(child) == child_id:
53 return child
54 return None
55
56 def __iter__(self):
57 return iter(self.gifts)
58
59 def xmas(self):
60 if not self.requests:
61 return
62
63 gift_count = defaultdict(int)
64 for gift in self.requests.values():
65 gift_count[gift] += 1
66
67 most_requested = max(gift_count.values(), default=0)
68 popular_gifts = [gift for gift, count in gift_count.items() if count == most_requested]
69 default_gift = random.choice(popular_gifts) if popular_gifts else "coal"
70
71 for child in list(self._children):
72 if child.age > 5:
73 continue
74
75 if self.naughty[child]:
76 child("coal")
77 continue
78
79 gift = self.requests.get(child, default_gift)
80 child(gift)
81
82 self.gifts = []
83 self.requests = {}
84 self.xmas_count += 1
85
86
87class Child:
88 def __init__(self, name):
89 self.name = name
90 Santa.register_child(self)
91 self.method_called = False
92
93 def __str__(self):
94 return self.name
95
96 @property
97 def age(self):
98 return Santa._instance.xmas_count
99
100 def some_method(self):
101 self.method_called = True
EEEEEEEEEEEEEEEEEEEE
======================================================================
ERROR: test_class_from_kid (test.TestKid.test_class_from_kid)
Test creating new class from Kid.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 13, in test_class_from_kid
cls = solution.Kid('name', (), {'__call__': print})
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_class_from_kid_without_call_dunder (test.TestKid.test_class_from_kid_without_call_dunder)
Test creating new class from Kid.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 19, in test_class_from_kid_without_call_dunder
solution.Kid('name', (), {})
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_call (test.TestSanta.test_call)
Test sending message via calling.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_call_and_mail_same_kid (test.TestSanta.test_call_and_mail_same_kid)
Test that calls and mails work for the same kid.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_iterable (test.TestSanta.test_iterable)
Ensure Santa can be iterated multiple times including overwriting presents.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_mail (test.TestSanta.test_mail)
Test sending message via email.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_present_matching (test.TestSanta.test_present_matching)
Test matching signature in the letter.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: 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 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: 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 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_singleton (test.TestSanta.test_singleton)
Ensure Santa is a singleton.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass (test.TestSanta.test_xmass)
Test a simple Christmas case.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_kid_with_multiple_wishes (test.TestSanta.test_xmass_kid_with_multiple_wishes)
Test a Christmas with a kid who sends multiple wishes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_kid_without_a_wish (test.TestSanta.test_xmass_kid_without_a_wish)
Test a Christmas with a kids that hasn't sent a wish.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_naughty (test.TestSanta.test_xmass_naughty)
Test a Christmas with naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_no_wishes (test.TestSanta.test_xmass_no_wishes)
Test a Christmas with no wishes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_no_wishes_but_naughty_kids (test.TestSanta.test_xmass_no_wishes_but_naughty_kids)
Test a Christmas with no wishes, but naughty kids present.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_private_with_error (test.TestSanta.test_xmass_private_with_error)
Test a Christmas with not-so-naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_public_with_no_error (test.TestSanta.test_xmass_public_with_no_error)
Test a Christmas with not-so-naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_years_5_and_over (test.TestSanta.test_xmass_years_5_and_over)
Test with passing years with kid aged 5 and over.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
======================================================================
ERROR: test_xmass_years_under_5 (test.TestSanta.test_xmass_years_under_5)
Test with passing years with a kid under 5 years old.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 35, in setUp
self.KidClass1 = solution.Kid('KidClass1', (), deepcopy(self.KID_DICT))
^^^^^^^^^^^^
AttributeError: module 'solution' has no attribute 'Kid'
----------------------------------------------------------------------
Ran 20 tests in 0.003s
FAILED (errors=20)
19.12.2024 16:39
19.12.2024 16:40
19.12.2024 16:41