1import re
2from collections import OrderedDict
3
4class Santa:
5 instance = None
6 AGE_LIMIT = 5
7 BAD_KID_GIFT = 'coal'
8 presents = OrderedDict()
9 childrens = {}
10 childrens_years = {}
11
12 def __new__(cls):
13 if not cls.instance:
14 cls.instance = super().__new__(cls)
15 return cls.instance
16
17 def __iter__(self):
18 for kid_id in self.childrens:
19 if self.presents.get(kid_id):
20 yield self.presents.get(kid_id)
21
22 def add_child(self, child):
23 child_id = id(child)
24 self.childrens[child_id] = child
25 self.childrens_years[child_id] = 0
26
27 def __call__(self, child, letter):
28 self.add_present(id(child), letter)
29
30 def __matmul__(self, letter):
31 if not isinstance(letter, str):
32 raise TypeError
33 id_pattern = r'^\s*\d+\s*$'
34 child_id = re.search(id_pattern, letter, re.MULTILINE)
35 if child_id:
36 self.add_present(int(child_id.group()), letter)
37
38 def add_present(self, child_id, letter):
39 wish_pattern = r'"([A-Za-z0-9 ]+)"|\'([A-Za-z0-9 ]+)\''
40 wish = re.search(wish_pattern, letter)
41 if wish:
42 wish_item = wish.group()[1:-1]
43 self.presents[child_id] = wish_item
44
45 def xmas(self):
46 most_wanted_present = self.get_most_wanted()
47 if most_wanted_present == None:
48 for kid_id, kid in self.childrens.items():
49 self.childrens_years[kid_id] += 1
50 else:
51 for kid_id, kid in self.childrens.items():
52 self.childrens_years[kid_id] += 1
53 if self.childrens_years[kid_id] > self.AGE_LIMIT:
54 continue
55 if self.presents.get(kid_id):
56 if self.is_naughty(kid):
57 kid(self.BAD_KID_GIFT)
58 else:
59 kid(self.presents[kid_id])
60 del self.presents[kid_id]
61 else:
62 if self.is_naughty(kid):
63 kid(self.BAD_KID_GIFT)
64 else:
65 kid(most_wanted_present)
66
67 def is_naughty(self, child):
68 return False
69
70 def get_most_wanted(self):
71 all_presents = [present for present in self.presents.values()]
72 return max(all_presents, key=all_presents.count, default=None)
73
74
75class Kid(type):
76
77 def __new__(cls, name, bases, attr_dict):
78 if "__call__" not in attr_dict:
79 raise NotImplementedError("Kid class should implement __call__ method.")
80 return super().__new__(cls, name, bases, attr_dict)
81
82 def __call__(cls, *args, **kwargs):
83 instance = super().__call__(*args, **kwargs)
84 santa = Santa()
85 santa.add_child(instance)
86 return instance
.......F.....F......
======================================================================
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_xmass_naughty (test.TestSanta.test_xmass_naughty)
Test a Christmas with naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 227, in test_xmass_naughty
self.assertEqual(kid1.SECRET_PRESENT, 'coal')
AssertionError: 'sirenie' != 'coal'
- sirenie
+ coal
----------------------------------------------------------------------
Ran 20 tests in 0.022s
FAILED (failures=2)
f | 1 | import re | f | 1 | import re |
n | n | 2 | from collections import OrderedDict | ||
2 | 3 | ||||
3 | class Santa: | 4 | class Santa: | ||
4 | instance = None | 5 | instance = None | ||
n | 5 | presents = {} | n | 6 | AGE_LIMIT = 5 |
7 | BAD_KID_GIFT = 'coal' | ||||
8 | presents = OrderedDict() | ||||
6 | childrens = {} | 9 | childrens = {} | ||
n | 7 | wishes_order = [] | n | 10 | childrens_years = {} |
8 | 11 | ||||
9 | def __new__(cls): | 12 | def __new__(cls): | ||
10 | if not cls.instance: | 13 | if not cls.instance: | ||
11 | cls.instance = super().__new__(cls) | 14 | cls.instance = super().__new__(cls) | ||
12 | return cls.instance | 15 | return cls.instance | ||
13 | 16 | ||||
14 | def __iter__(self): | 17 | def __iter__(self): | ||
n | 15 | for kid_id in self.wishes_order: | n | 18 | for kid_id in self.childrens: |
16 | if self.presents.get(kid_id): | 19 | if self.presents.get(kid_id): | ||
n | 17 | yield self.presents.get(kid_id)[0] | n | 20 | yield self.presents.get(kid_id) |
18 | 21 | ||||
19 | def add_child(self, child): | 22 | def add_child(self, child): | ||
20 | child_id = id(child) | 23 | child_id = id(child) | ||
n | 21 | self.childrens[child_id] = child | n | 24 | self.childrens[child_id] = child |
25 | self.childrens_years[child_id] = 0 | ||||
22 | 26 | ||||
23 | def __call__(self, child, letter): | 27 | def __call__(self, child, letter): | ||
n | 24 | if (type(child.__class__) is Kid): | n | ||
25 | self.add_present(id(child), letter) | 28 | self.add_present(id(child), letter) | ||
26 | 29 | ||||
27 | def __matmul__(self, letter): | 30 | def __matmul__(self, letter): | ||
28 | if not isinstance(letter, str): | 31 | if not isinstance(letter, str): | ||
29 | raise TypeError | 32 | raise TypeError | ||
30 | id_pattern = r'^\s*\d+\s*$' | 33 | id_pattern = r'^\s*\d+\s*$' | ||
31 | child_id = re.search(id_pattern, letter, re.MULTILINE) | 34 | child_id = re.search(id_pattern, letter, re.MULTILINE) | ||
32 | if child_id: | 35 | if child_id: | ||
33 | self.add_present(int(child_id.group()), letter) | 36 | self.add_present(int(child_id.group()), letter) | ||
34 | 37 | ||||
35 | def add_present(self, child_id, letter): | 38 | def add_present(self, child_id, letter): | ||
36 | wish_pattern = r'"([A-Za-z0-9 ]+)"|\'([A-Za-z0-9 ]+)\'' | 39 | wish_pattern = r'"([A-Za-z0-9 ]+)"|\'([A-Za-z0-9 ]+)\'' | ||
37 | wish = re.search(wish_pattern, letter) | 40 | wish = re.search(wish_pattern, letter) | ||
38 | if wish: | 41 | if wish: | ||
39 | wish_item = wish.group()[1:-1] | 42 | wish_item = wish.group()[1:-1] | ||
n | 40 | if child_id in self.presents: | n | ||
41 | self.presents[child_id][0] = wish_item | 43 | self.presents[child_id] = wish_item | ||
42 | else: | ||||
43 | self.presents[child_id] = [wish_item, 0] | ||||
44 | self.wishes_order.append(child_id) | ||||
45 | 44 | ||||
46 | def xmas(self): | 45 | def xmas(self): | ||
47 | most_wanted_present = self.get_most_wanted() | 46 | most_wanted_present = self.get_most_wanted() | ||
48 | if most_wanted_present == None: | 47 | if most_wanted_present == None: | ||
49 | for kid_id, kid in self.childrens.items(): | 48 | for kid_id, kid in self.childrens.items(): | ||
n | 50 | present_years_pair = self.presents.get(kid_id) | n | ||
51 | if present_years_pair: | ||||
52 | self.presents[kid_id][1] += 1 | 49 | self.childrens_years[kid_id] += 1 | ||
53 | else: | ||||
54 | self.presents[kid_id] = [None, 1] | ||||
55 | else: | 50 | else: | ||
56 | for kid_id, kid in self.childrens.items(): | 51 | for kid_id, kid in self.childrens.items(): | ||
n | 57 | present_years_pair = self.presents.get(kid_id) | n | 52 | self.childrens_years[kid_id] += 1 |
58 | if present_years_pair: | 53 | if self.childrens_years[kid_id] > self.AGE_LIMIT: | ||
59 | if present_years_pair[1] >= 5: | ||||
60 | continue | 54 | continue | ||
61 | elif present_years_pair[0]: | 55 | if self.presents.get(kid_id): | ||
62 | self.presents[kid_id][1] += 1 | ||||
63 | if self.is_naughty(kid): | 56 | if self.is_naughty(kid): | ||
64 | kid('coal') | 57 | kid(self.BAD_KID_GIFT) | ||
65 | else: | ||||
66 | kid(present_years_pair[0]) | ||||
67 | self.presents[kid_id][0] = None | ||||
68 | else: | 58 | else: | ||
n | n | 59 | kid(self.presents[kid_id]) | ||
69 | self.presents[kid_id][1] += 1 | 60 | del self.presents[kid_id] | ||
70 | if self.is_naughty(kid): | ||||
71 | kid('coal') | ||||
72 | else: | ||||
73 | kid(most_wanted_present) | ||||
74 | else: | 61 | else: | ||
n | 75 | self.presents[kid_id] = [None, 1] | n | ||
76 | if self.is_naughty(kid): | 62 | if self.is_naughty(kid): | ||
n | 77 | kid('coal') | n | 63 | kid(self.BAD_KID_GIFT) |
78 | else: | 64 | else: | ||
79 | kid(most_wanted_present) | 65 | kid(most_wanted_present) | ||
80 | 66 | ||||
81 | def is_naughty(self, child): | 67 | def is_naughty(self, child): | ||
82 | return False | 68 | return False | ||
n | 83 | n | 69 | ||
84 | def get_most_wanted(self): | 70 | def get_most_wanted(self): | ||
n | 85 | presents_count = {} | n | 71 | all_presents = [present for present in self.presents.values()] |
86 | for kid_id in self.childrens: | 72 | return max(all_presents, key=all_presents.count, default=None) | ||
87 | present = self.presents.get(kid_id) | 73 | |||
88 | if present: | ||||
89 | if present[0] not in presents_count: | ||||
90 | presents_count[present[0]] = 0 | ||||
91 | presents_count[present[0]] += 1 | ||||
92 | most_wanted_count = 0 | ||||
93 | item = None | ||||
94 | for key, value in presents_count.items(): | ||||
95 | if value > most_wanted_count and key: | ||||
96 | most_wanted_count = value | ||||
97 | item = key | ||||
98 | return item | ||||
99 | |||||
100 | 74 | ||||
101 | class Kid(type): | 75 | class Kid(type): | ||
102 | 76 | ||||
103 | def __new__(cls, name, bases, attr_dict): | 77 | def __new__(cls, name, bases, attr_dict): | ||
n | 104 | if not attr_dict.get("__call__"): | n | 78 | if "__call__" not in attr_dict: |
105 | raise NotImplementedError("kid class should implement call method") | 79 | raise NotImplementedError("Kid class should implement __call__ method.") | ||
106 | return super().__new__(cls, name, bases, attr_dict) | 80 | return super().__new__(cls, name, bases, attr_dict) | ||
t | 107 | t | 81 | ||
108 | def __call__(cls, *args, **kwargs): | 82 | def __call__(cls, *args, **kwargs): | ||
109 | instance = super().__call__(*args, **kwargs) | 83 | instance = super().__call__(*args, **kwargs) | ||
110 | santa = Santa() | 84 | santa = Santa() | ||
111 | santa.add_child(instance) | 85 | santa.add_child(instance) | ||
112 | return instance | 86 | return instance |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|