1import re
2from collections import OrderedDict
3import random
4from unittest.mock import patch, call
5
6class SingletonMeta(type):
7 """A metaclass for realizing the Singleton design pattern."""
8
9 #attribute to save the unique instance in
10 _instance = None
11
12 def __call__(cls, *args, **kwargs):
13 """Control the creation of an instance of a class."""
14 if not cls._instance:
15 cls._instance = super().__call__(*args, **kwargs)
16 return cls._instance
17
18class Santa(metaclass=SingletonMeta):
19 """A class representing Santa."""
20
21 _kids = {}
22 _wishes = OrderedDict()
23
24 def __call__(self, kid, phone_call):
25 """Handle a wish request made by a kid made by a phone call."""
26 wish = self.get_wish_of(phone_call)
27 self._wishes[id(kid)] = wish
28
29 def __matmul__(self, letter):
30 """Handle a wish request made by a Kid sent as a letter."""
31 wish = self.get_wish_of(letter)
32 signature = int(re.search(r'(\b\d+\b)', letter).group(0))
33 self._wishes[signature] = wish
34
35 def get_wish_of(self, source):
36 """Match the wish in source."""
37 wish_match = re.search(r"(['\"])([\w ]+)\1", source, re.MULTILINE | re.DOTALL)
38 return wish_match.group(1)
39
40 @classmethod
41 def add_new_kid(cls, kid):
42 """Save kids in order to be able to call them."""
43 cls._kids[id(kid)] = kid
44
45 def __iter__(self):
46 """Return an iterator for Santa's presents."""
47 self._all_presents = list(self._wishes.values())
48 self._index = 0
49 return self
50
51 def __next__(self):
52 """Return the next present in the list."""
53 if self._index < len(self._all_presents):
54 result = self._all_presents[self._index]
55 self._index += 1
56 return result
57 raise StopIteration
58
59 def _get_most_common_gift(self):
60 """Find the most common gift."""
61 gifts = list(self._wishes.values())
62 gift_counts = {gift: gifts.count(gift) for gift in set(gifts)}
63
64 max_count = max(gift_counts.values())
65 most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count]
66
67 return random.choice(most_frequent_gifts)
68
69 def to_next_christmas(self):
70 """Age up all kids and clear gifts for next Christmas."""
71 self._wishes = OrderedDict()
72 for kid in self._kids.values():
73 kid.age_up()
74 kid.set_is_good()
75
76 def _handle_kid(self, id, instance):
77 """Handle the present for a kid."""
78 if instance.age >= 5:
79 return
80
81 if not instance.is_good:
82 instance('coal')
83 elif id in self._wishes:
84 instance(self._wishes[id])
85 else:
86 instance(self._get_most_common_gift())
87
88 def xmas(self):
89 """Distribute presents according to the rules."""
90 if not self._wishes:
91 self.to_next_christmas()
92 return
93
94 for id, instance in self._kids.items():
95 self._handle_kid(id, instance)
96
97 self.to_next_christmas()
98
99class Kid(type):
100 """Metaclass that ensures every new kid is registered in Santa and has required methods."""
101
102 def __new__(cls, name, bases, attributes):
103 if '__call__' not in attributes:
104 raise NotImplementedError("О, неразумни юроде!")
105
106 new_class = super().__new__(cls, name, bases, attributes)
107
108 interface = cls.create_kid_methods()
109 new_class.__init__ = interface[0]
110 new_class.age_up = interface[1]
111 new_class.set_is_good = interface[2]
112 return new_class
113
114 def __init__(cls, name, bases, attributes):
115 """Wrap class methods to flag the kid is naughty if exception is thrown."""
116 for method_name, method in cls.__dict__.items():
117 if callable(method) and not method_name.startswith('_'):
118 setattr(cls, method_name, cls.wrapped_method(method))
119
120 @staticmethod
121 def create_kid_methods():
122 """Generate __init__, age_up, set_is_good."""
123 def __init__(self, *args, **kwargs):
124 self.age = 0
125 self.is_good = True
126 super().__init__(*args, **kwargs)
127
128 def age_up(self):
129 self.age += 1
130
131 def set_is_good(self, is_good=True):
132 self.is_good = is_good
133
134 return __init__, age_up, set_is_good
135
136 @staticmethod
137 def wrapped_method(method):
138 """Search for raised exception in public methods."""
139 def decoratored_method(self, *args, **kwargs):
140 try:
141 return method(self, *args, **kwargs)
142 except Exception as err:
143 self.set_is_good(False)
144 raise err
145 return decoratored_method
146
147 def __call__(cls, *args, **kwargs):
148 """Add kid in the wishlist when a kid is called."""
149 instance = super().__call__(*args, **kwargs)
150 Santa.add_new_kid(instance)
151 return instance
..EEEEEEE.EEEEEEEEEE
======================================================================
ERROR: test_call (test.TestSanta.test_call)
Test sending message via calling.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 52, in test_call
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 68, in test_call_and_mail_same_kid
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 124, in test_iterable
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
ERROR: test_mail (test.TestSanta.test_mail)
Test sending message via email.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 60, in test_mail
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 75, in test_present_matching
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 252, in test_santa_gift_order
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 96, in test_signature_matching
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
ERROR: test_xmass (test.TestSanta.test_xmass)
Test a simple Christmas case.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 134, in test_xmass
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 182, in test_xmass_kid_with_multiple_wishes
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 167, in test_xmass_kid_without_a_wish
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 217, in test_xmass_naughty
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 147, in test_xmass_no_wishes
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 157, in test_xmass_no_wishes_but_naughty_kids
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 233, in test_xmass_private_with_error
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 244, in test_xmass_public_with_no_error
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 205, in test_xmass_years_5_and_over
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
======================================================================
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 191, in test_xmass_years_under_5
kid1 = self.KidClass1()
^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 149, in __call__
instance = super().__call__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 126, in __init__
super().__init__(*args, **kwargs)
^^^^^^^^^^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
----------------------------------------------------------------------
Ran 20 tests in 0.041s
FAILED (errors=17)
Илиан Запрянов
19.12.2024 18:52💀
|
Виктор Бечев
19.12.2024 13:59Аз искам да те питам нещо, без да ми е съвестно, че съм помогнал прекалено. Просто не обичам да виждам труд, който да отиде "на вятъра" заради нещо глупаво...
Пусна ли примерния код?
|
f | 1 | import re | f | 1 | import re |
2 | from collections import OrderedDict | 2 | from collections import OrderedDict | ||
3 | import random | 3 | import random | ||
4 | from unittest.mock import patch, call | 4 | from unittest.mock import patch, call | ||
5 | 5 | ||||
6 | class SingletonMeta(type): | 6 | class SingletonMeta(type): | ||
7 | """A metaclass for realizing the Singleton design pattern.""" | 7 | """A metaclass for realizing the Singleton design pattern.""" | ||
8 | 8 | ||||
9 | #attribute to save the unique instance in | 9 | #attribute to save the unique instance in | ||
10 | _instance = None | 10 | _instance = None | ||
11 | 11 | ||||
12 | def __call__(cls, *args, **kwargs): | 12 | def __call__(cls, *args, **kwargs): | ||
13 | """Control the creation of an instance of a class.""" | 13 | """Control the creation of an instance of a class.""" | ||
14 | if not cls._instance: | 14 | if not cls._instance: | ||
15 | cls._instance = super().__call__(*args, **kwargs) | 15 | cls._instance = super().__call__(*args, **kwargs) | ||
16 | return cls._instance | 16 | return cls._instance | ||
17 | 17 | ||||
18 | class Santa(metaclass=SingletonMeta): | 18 | class Santa(metaclass=SingletonMeta): | ||
19 | """A class representing Santa.""" | 19 | """A class representing Santa.""" | ||
20 | 20 | ||||
21 | _kids = {} | 21 | _kids = {} | ||
22 | _wishes = OrderedDict() | 22 | _wishes = OrderedDict() | ||
23 | 23 | ||||
24 | def __call__(self, kid, phone_call): | 24 | def __call__(self, kid, phone_call): | ||
25 | """Handle a wish request made by a kid made by a phone call.""" | 25 | """Handle a wish request made by a kid made by a phone call.""" | ||
26 | wish = self.get_wish_of(phone_call) | 26 | wish = self.get_wish_of(phone_call) | ||
27 | self._wishes[id(kid)] = wish | 27 | self._wishes[id(kid)] = wish | ||
28 | 28 | ||||
29 | def __matmul__(self, letter): | 29 | def __matmul__(self, letter): | ||
30 | """Handle a wish request made by a Kid sent as a letter.""" | 30 | """Handle a wish request made by a Kid sent as a letter.""" | ||
31 | wish = self.get_wish_of(letter) | 31 | wish = self.get_wish_of(letter) | ||
32 | signature = int(re.search(r'(\b\d+\b)', letter).group(0)) | 32 | signature = int(re.search(r'(\b\d+\b)', letter).group(0)) | ||
33 | self._wishes[signature] = wish | 33 | self._wishes[signature] = wish | ||
34 | 34 | ||||
35 | def get_wish_of(self, source): | 35 | def get_wish_of(self, source): | ||
36 | """Match the wish in source.""" | 36 | """Match the wish in source.""" | ||
37 | wish_match = re.search(r"(['\"])([\w ]+)\1", source, re.MULTILINE | re.DOTALL) | 37 | wish_match = re.search(r"(['\"])([\w ]+)\1", source, re.MULTILINE | re.DOTALL) | ||
38 | return wish_match.group(1) | 38 | return wish_match.group(1) | ||
39 | 39 | ||||
40 | @classmethod | 40 | @classmethod | ||
41 | def add_new_kid(cls, kid): | 41 | def add_new_kid(cls, kid): | ||
42 | """Save kids in order to be able to call them.""" | 42 | """Save kids in order to be able to call them.""" | ||
43 | cls._kids[id(kid)] = kid | 43 | cls._kids[id(kid)] = kid | ||
44 | 44 | ||||
45 | def __iter__(self): | 45 | def __iter__(self): | ||
46 | """Return an iterator for Santa's presents.""" | 46 | """Return an iterator for Santa's presents.""" | ||
47 | self._all_presents = list(self._wishes.values()) | 47 | self._all_presents = list(self._wishes.values()) | ||
48 | self._index = 0 | 48 | self._index = 0 | ||
49 | return self | 49 | return self | ||
50 | 50 | ||||
51 | def __next__(self): | 51 | def __next__(self): | ||
52 | """Return the next present in the list.""" | 52 | """Return the next present in the list.""" | ||
53 | if self._index < len(self._all_presents): | 53 | if self._index < len(self._all_presents): | ||
54 | result = self._all_presents[self._index] | 54 | result = self._all_presents[self._index] | ||
55 | self._index += 1 | 55 | self._index += 1 | ||
56 | return result | 56 | return result | ||
57 | raise StopIteration | 57 | raise StopIteration | ||
58 | 58 | ||||
59 | def _get_most_common_gift(self): | 59 | def _get_most_common_gift(self): | ||
60 | """Find the most common gift.""" | 60 | """Find the most common gift.""" | ||
61 | gifts = list(self._wishes.values()) | 61 | gifts = list(self._wishes.values()) | ||
62 | gift_counts = {gift: gifts.count(gift) for gift in set(gifts)} | 62 | gift_counts = {gift: gifts.count(gift) for gift in set(gifts)} | ||
63 | 63 | ||||
64 | max_count = max(gift_counts.values()) | 64 | max_count = max(gift_counts.values()) | ||
65 | most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count] | 65 | most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count] | ||
66 | 66 | ||||
67 | return random.choice(most_frequent_gifts) | 67 | return random.choice(most_frequent_gifts) | ||
68 | 68 | ||||
69 | def to_next_christmas(self): | 69 | def to_next_christmas(self): | ||
70 | """Age up all kids and clear gifts for next Christmas.""" | 70 | """Age up all kids and clear gifts for next Christmas.""" | ||
71 | self._wishes = OrderedDict() | 71 | self._wishes = OrderedDict() | ||
72 | for kid in self._kids.values(): | 72 | for kid in self._kids.values(): | ||
73 | kid.age_up() | 73 | kid.age_up() | ||
74 | kid.set_is_good() | 74 | kid.set_is_good() | ||
75 | 75 | ||||
76 | def _handle_kid(self, id, instance): | 76 | def _handle_kid(self, id, instance): | ||
77 | """Handle the present for a kid.""" | 77 | """Handle the present for a kid.""" | ||
78 | if instance.age >= 5: | 78 | if instance.age >= 5: | ||
79 | return | 79 | return | ||
80 | 80 | ||||
81 | if not instance.is_good: | 81 | if not instance.is_good: | ||
82 | instance('coal') | 82 | instance('coal') | ||
83 | elif id in self._wishes: | 83 | elif id in self._wishes: | ||
84 | instance(self._wishes[id]) | 84 | instance(self._wishes[id]) | ||
85 | else: | 85 | else: | ||
86 | instance(self._get_most_common_gift()) | 86 | instance(self._get_most_common_gift()) | ||
87 | 87 | ||||
88 | def xmas(self): | 88 | def xmas(self): | ||
89 | """Distribute presents according to the rules.""" | 89 | """Distribute presents according to the rules.""" | ||
90 | if not self._wishes: | 90 | if not self._wishes: | ||
91 | self.to_next_christmas() | 91 | self.to_next_christmas() | ||
92 | return | 92 | return | ||
93 | 93 | ||||
94 | for id, instance in self._kids.items(): | 94 | for id, instance in self._kids.items(): | ||
95 | self._handle_kid(id, instance) | 95 | self._handle_kid(id, instance) | ||
96 | 96 | ||||
97 | self.to_next_christmas() | 97 | self.to_next_christmas() | ||
98 | 98 | ||||
99 | class Kid(type): | 99 | class Kid(type): | ||
100 | """Metaclass that ensures every new kid is registered in Santa and has required methods.""" | 100 | """Metaclass that ensures every new kid is registered in Santa and has required methods.""" | ||
101 | 101 | ||||
102 | def __new__(cls, name, bases, attributes): | 102 | def __new__(cls, name, bases, attributes): | ||
103 | if '__call__' not in attributes: | 103 | if '__call__' not in attributes: | ||
104 | raise NotImplementedError("О, неразумни юроде!") | 104 | raise NotImplementedError("О, неразумни юроде!") | ||
105 | 105 | ||||
106 | new_class = super().__new__(cls, name, bases, attributes) | 106 | new_class = super().__new__(cls, name, bases, attributes) | ||
107 | 107 | ||||
108 | interface = cls.create_kid_methods() | 108 | interface = cls.create_kid_methods() | ||
109 | new_class.__init__ = interface[0] | 109 | new_class.__init__ = interface[0] | ||
110 | new_class.age_up = interface[1] | 110 | new_class.age_up = interface[1] | ||
111 | new_class.set_is_good = interface[2] | 111 | new_class.set_is_good = interface[2] | ||
112 | return new_class | 112 | return new_class | ||
113 | 113 | ||||
114 | def __init__(cls, name, bases, attributes): | 114 | def __init__(cls, name, bases, attributes): | ||
t | 115 | """Validate is kid good when initialized.""" | t | 115 | """Wrap class methods to flag the kid is naughty if exception is thrown.""" |
116 | for method_name, method in cls.__dict__.items(): | 116 | for method_name, method in cls.__dict__.items(): | ||
117 | if callable(method) and not method_name.startswith('_'): | 117 | if callable(method) and not method_name.startswith('_'): | ||
118 | setattr(cls, method_name, cls.wrapped_method(method)) | 118 | setattr(cls, method_name, cls.wrapped_method(method)) | ||
119 | 119 | ||||
120 | @staticmethod | 120 | @staticmethod | ||
121 | def create_kid_methods(): | 121 | def create_kid_methods(): | ||
122 | """Generate __init__, age_up, set_is_good.""" | 122 | """Generate __init__, age_up, set_is_good.""" | ||
123 | def __init__(self, *args, **kwargs): | 123 | def __init__(self, *args, **kwargs): | ||
124 | self.age = 0 | 124 | self.age = 0 | ||
125 | self.is_good = True | 125 | self.is_good = True | ||
126 | super().__init__(*args, **kwargs) | 126 | super().__init__(*args, **kwargs) | ||
127 | 127 | ||||
128 | def age_up(self): | 128 | def age_up(self): | ||
129 | self.age += 1 | 129 | self.age += 1 | ||
130 | 130 | ||||
131 | def set_is_good(self, is_good=True): | 131 | def set_is_good(self, is_good=True): | ||
132 | self.is_good = is_good | 132 | self.is_good = is_good | ||
133 | 133 | ||||
134 | return __init__, age_up, set_is_good | 134 | return __init__, age_up, set_is_good | ||
135 | 135 | ||||
136 | @staticmethod | 136 | @staticmethod | ||
137 | def wrapped_method(method): | 137 | def wrapped_method(method): | ||
138 | """Search for raised exception in public methods.""" | 138 | """Search for raised exception in public methods.""" | ||
139 | def decoratored_method(self, *args, **kwargs): | 139 | def decoratored_method(self, *args, **kwargs): | ||
140 | try: | 140 | try: | ||
141 | return method(self, *args, **kwargs) | 141 | return method(self, *args, **kwargs) | ||
142 | except Exception as err: | 142 | except Exception as err: | ||
143 | self.set_is_good(False) | 143 | self.set_is_good(False) | ||
144 | raise err | 144 | raise err | ||
145 | return decoratored_method | 145 | return decoratored_method | ||
146 | 146 | ||||
147 | def __call__(cls, *args, **kwargs): | 147 | def __call__(cls, *args, **kwargs): | ||
148 | """Add kid in the wishlist when a kid is called.""" | 148 | """Add kid in the wishlist when a kid is called.""" | ||
149 | instance = super().__call__(*args, **kwargs) | 149 | instance = super().__call__(*args, **kwargs) | ||
150 | Santa.add_new_kid(instance) | 150 | Santa.add_new_kid(instance) | ||
151 | return instance | 151 | return instance |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
t | 1 | import re | t | 1 | import re |
2 | from collections import OrderedDict | 2 | from collections import OrderedDict | ||
3 | import random | 3 | import random | ||
4 | from unittest.mock import patch, call | 4 | from unittest.mock import patch, call | ||
5 | 5 | ||||
6 | class SingletonMeta(type): | 6 | class SingletonMeta(type): | ||
7 | """A metaclass for realizing the Singleton design pattern.""" | 7 | """A metaclass for realizing the Singleton design pattern.""" | ||
8 | 8 | ||||
9 | #attribute to save the unique instance in | 9 | #attribute to save the unique instance in | ||
10 | _instance = None | 10 | _instance = None | ||
11 | 11 | ||||
12 | def __call__(cls, *args, **kwargs): | 12 | def __call__(cls, *args, **kwargs): | ||
13 | """Control the creation of an instance of a class.""" | 13 | """Control the creation of an instance of a class.""" | ||
14 | if not cls._instance: | 14 | if not cls._instance: | ||
15 | cls._instance = super().__call__(*args, **kwargs) | 15 | cls._instance = super().__call__(*args, **kwargs) | ||
16 | return cls._instance | 16 | return cls._instance | ||
17 | 17 | ||||
18 | class Santa(metaclass=SingletonMeta): | 18 | class Santa(metaclass=SingletonMeta): | ||
19 | """A class representing Santa.""" | 19 | """A class representing Santa.""" | ||
20 | 20 | ||||
21 | _kids = {} | 21 | _kids = {} | ||
22 | _wishes = OrderedDict() | 22 | _wishes = OrderedDict() | ||
23 | 23 | ||||
24 | def __call__(self, kid, phone_call): | 24 | def __call__(self, kid, phone_call): | ||
25 | """Handle a wish request made by a kid made by a phone call.""" | 25 | """Handle a wish request made by a kid made by a phone call.""" | ||
26 | wish = self.get_wish_of(phone_call) | 26 | wish = self.get_wish_of(phone_call) | ||
27 | self._wishes[id(kid)] = wish | 27 | self._wishes[id(kid)] = wish | ||
28 | 28 | ||||
29 | def __matmul__(self, letter): | 29 | def __matmul__(self, letter): | ||
30 | """Handle a wish request made by a Kid sent as a letter.""" | 30 | """Handle a wish request made by a Kid sent as a letter.""" | ||
31 | wish = self.get_wish_of(letter) | 31 | wish = self.get_wish_of(letter) | ||
32 | signature = int(re.search(r'(\b\d+\b)', letter).group(0)) | 32 | signature = int(re.search(r'(\b\d+\b)', letter).group(0)) | ||
33 | self._wishes[signature] = wish | 33 | self._wishes[signature] = wish | ||
34 | 34 | ||||
35 | def get_wish_of(self, source): | 35 | def get_wish_of(self, source): | ||
36 | """Match the wish in source.""" | 36 | """Match the wish in source.""" | ||
37 | wish_match = re.search(r"(['\"])([\w ]+)\1", source, re.MULTILINE | re.DOTALL) | 37 | wish_match = re.search(r"(['\"])([\w ]+)\1", source, re.MULTILINE | re.DOTALL) | ||
38 | return wish_match.group(1) | 38 | return wish_match.group(1) | ||
39 | 39 | ||||
40 | @classmethod | 40 | @classmethod | ||
41 | def add_new_kid(cls, kid): | 41 | def add_new_kid(cls, kid): | ||
42 | """Save kids in order to be able to call them.""" | 42 | """Save kids in order to be able to call them.""" | ||
43 | cls._kids[id(kid)] = kid | 43 | cls._kids[id(kid)] = kid | ||
44 | 44 | ||||
45 | def __iter__(self): | 45 | def __iter__(self): | ||
46 | """Return an iterator for Santa's presents.""" | 46 | """Return an iterator for Santa's presents.""" | ||
47 | self._all_presents = list(self._wishes.values()) | 47 | self._all_presents = list(self._wishes.values()) | ||
48 | self._index = 0 | 48 | self._index = 0 | ||
49 | return self | 49 | return self | ||
50 | 50 | ||||
51 | def __next__(self): | 51 | def __next__(self): | ||
52 | """Return the next present in the list.""" | 52 | """Return the next present in the list.""" | ||
53 | if self._index < len(self._all_presents): | 53 | if self._index < len(self._all_presents): | ||
54 | result = self._all_presents[self._index] | 54 | result = self._all_presents[self._index] | ||
55 | self._index += 1 | 55 | self._index += 1 | ||
56 | return result | 56 | return result | ||
57 | raise StopIteration | 57 | raise StopIteration | ||
58 | 58 | ||||
59 | def _get_most_common_gift(self): | 59 | def _get_most_common_gift(self): | ||
60 | """Find the most common gift.""" | 60 | """Find the most common gift.""" | ||
61 | gifts = list(self._wishes.values()) | 61 | gifts = list(self._wishes.values()) | ||
62 | gift_counts = {gift: gifts.count(gift) for gift in set(gifts)} | 62 | gift_counts = {gift: gifts.count(gift) for gift in set(gifts)} | ||
63 | 63 | ||||
64 | max_count = max(gift_counts.values()) | 64 | max_count = max(gift_counts.values()) | ||
65 | most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count] | 65 | most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count] | ||
66 | 66 | ||||
67 | return random.choice(most_frequent_gifts) | 67 | return random.choice(most_frequent_gifts) | ||
68 | 68 | ||||
69 | def to_next_christmas(self): | 69 | def to_next_christmas(self): | ||
70 | """Age up all kids and clear gifts for next Christmas.""" | 70 | """Age up all kids and clear gifts for next Christmas.""" | ||
71 | self._wishes = OrderedDict() | 71 | self._wishes = OrderedDict() | ||
72 | for kid in self._kids.values(): | 72 | for kid in self._kids.values(): | ||
73 | kid.age_up() | 73 | kid.age_up() | ||
74 | kid.set_is_good() | 74 | kid.set_is_good() | ||
75 | 75 | ||||
76 | def _handle_kid(self, id, instance): | 76 | def _handle_kid(self, id, instance): | ||
77 | """Handle the present for a kid.""" | 77 | """Handle the present for a kid.""" | ||
78 | if instance.age >= 5: | 78 | if instance.age >= 5: | ||
79 | return | 79 | return | ||
80 | 80 | ||||
81 | if not instance.is_good: | 81 | if not instance.is_good: | ||
82 | instance('coal') | 82 | instance('coal') | ||
83 | elif id in self._wishes: | 83 | elif id in self._wishes: | ||
84 | instance(self._wishes[id]) | 84 | instance(self._wishes[id]) | ||
85 | else: | 85 | else: | ||
86 | instance(self._get_most_common_gift()) | 86 | instance(self._get_most_common_gift()) | ||
87 | 87 | ||||
88 | def xmas(self): | 88 | def xmas(self): | ||
89 | """Distribute presents according to the rules.""" | 89 | """Distribute presents according to the rules.""" | ||
90 | if not self._wishes: | 90 | if not self._wishes: | ||
91 | self.to_next_christmas() | 91 | self.to_next_christmas() | ||
92 | return | 92 | return | ||
93 | 93 | ||||
94 | for id, instance in self._kids.items(): | 94 | for id, instance in self._kids.items(): | ||
95 | self._handle_kid(id, instance) | 95 | self._handle_kid(id, instance) | ||
96 | 96 | ||||
97 | self.to_next_christmas() | 97 | self.to_next_christmas() | ||
98 | 98 | ||||
99 | class Kid(type): | 99 | class Kid(type): | ||
100 | """Metaclass that ensures every new kid is registered in Santa and has required methods.""" | 100 | """Metaclass that ensures every new kid is registered in Santa and has required methods.""" | ||
101 | 101 | ||||
102 | def __new__(cls, name, bases, attributes): | 102 | def __new__(cls, name, bases, attributes): | ||
103 | if '__call__' not in attributes: | 103 | if '__call__' not in attributes: | ||
104 | raise NotImplementedError("О, неразумни юроде!") | 104 | raise NotImplementedError("О, неразумни юроде!") | ||
105 | 105 | ||||
106 | new_class = super().__new__(cls, name, bases, attributes) | 106 | new_class = super().__new__(cls, name, bases, attributes) | ||
107 | 107 | ||||
108 | interface = cls.create_kid_methods() | 108 | interface = cls.create_kid_methods() | ||
109 | new_class.__init__ = interface[0] | 109 | new_class.__init__ = interface[0] | ||
110 | new_class.age_up = interface[1] | 110 | new_class.age_up = interface[1] | ||
111 | new_class.set_is_good = interface[2] | 111 | new_class.set_is_good = interface[2] | ||
112 | return new_class | 112 | return new_class | ||
113 | 113 | ||||
114 | def __init__(cls, name, bases, attributes): | 114 | def __init__(cls, name, bases, attributes): | ||
115 | """Validate is kid good when initialized.""" | 115 | """Validate is kid good when initialized.""" | ||
116 | for method_name, method in cls.__dict__.items(): | 116 | for method_name, method in cls.__dict__.items(): | ||
117 | if callable(method) and not method_name.startswith('_'): | 117 | if callable(method) and not method_name.startswith('_'): | ||
118 | setattr(cls, method_name, cls.wrapped_method(method)) | 118 | setattr(cls, method_name, cls.wrapped_method(method)) | ||
119 | 119 | ||||
120 | @staticmethod | 120 | @staticmethod | ||
121 | def create_kid_methods(): | 121 | def create_kid_methods(): | ||
122 | """Generate __init__, age_up, set_is_good.""" | 122 | """Generate __init__, age_up, set_is_good.""" | ||
123 | def __init__(self, *args, **kwargs): | 123 | def __init__(self, *args, **kwargs): | ||
124 | self.age = 0 | 124 | self.age = 0 | ||
125 | self.is_good = True | 125 | self.is_good = True | ||
126 | super().__init__(*args, **kwargs) | 126 | super().__init__(*args, **kwargs) | ||
127 | 127 | ||||
128 | def age_up(self): | 128 | def age_up(self): | ||
129 | self.age += 1 | 129 | self.age += 1 | ||
130 | 130 | ||||
131 | def set_is_good(self, is_good=True): | 131 | def set_is_good(self, is_good=True): | ||
132 | self.is_good = is_good | 132 | self.is_good = is_good | ||
133 | 133 | ||||
134 | return __init__, age_up, set_is_good | 134 | return __init__, age_up, set_is_good | ||
135 | 135 | ||||
136 | @staticmethod | 136 | @staticmethod | ||
137 | def wrapped_method(method): | 137 | def wrapped_method(method): | ||
138 | """Search for raised exception in public methods.""" | 138 | """Search for raised exception in public methods.""" | ||
139 | def decoratored_method(self, *args, **kwargs): | 139 | def decoratored_method(self, *args, **kwargs): | ||
140 | try: | 140 | try: | ||
141 | return method(self, *args, **kwargs) | 141 | return method(self, *args, **kwargs) | ||
142 | except Exception as err: | 142 | except Exception as err: | ||
143 | self.set_is_good(False) | 143 | self.set_is_good(False) | ||
144 | raise err | 144 | raise err | ||
145 | return decoratored_method | 145 | return decoratored_method | ||
146 | 146 | ||||
147 | def __call__(cls, *args, **kwargs): | 147 | def __call__(cls, *args, **kwargs): | ||
148 | """Add kid in the wishlist when a kid is called.""" | 148 | """Add kid in the wishlist when a kid is called.""" | ||
149 | instance = super().__call__(*args, **kwargs) | 149 | instance = super().__call__(*args, **kwargs) | ||
150 | Santa.add_new_kid(instance) | 150 | Santa.add_new_kid(instance) | ||
151 | return instance | 151 | return instance |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import re | f | 1 | import re |
2 | from collections import OrderedDict | 2 | from collections import OrderedDict | ||
3 | import random | 3 | import random | ||
4 | from unittest.mock import patch, call | 4 | from unittest.mock import patch, call | ||
5 | 5 | ||||
6 | class SingletonMeta(type): | 6 | class SingletonMeta(type): | ||
7 | """A metaclass for realizing the Singleton design pattern.""" | 7 | """A metaclass for realizing the Singleton design pattern.""" | ||
8 | 8 | ||||
9 | #attribute to save the unique instance in | 9 | #attribute to save the unique instance in | ||
10 | _instance = None | 10 | _instance = None | ||
11 | 11 | ||||
12 | def __call__(cls, *args, **kwargs): | 12 | def __call__(cls, *args, **kwargs): | ||
13 | """Control the creation of an instance of a class.""" | 13 | """Control the creation of an instance of a class.""" | ||
14 | if not cls._instance: | 14 | if not cls._instance: | ||
15 | cls._instance = super().__call__(*args, **kwargs) | 15 | cls._instance = super().__call__(*args, **kwargs) | ||
16 | return cls._instance | 16 | return cls._instance | ||
17 | 17 | ||||
18 | class Santa(metaclass=SingletonMeta): | 18 | class Santa(metaclass=SingletonMeta): | ||
19 | """A class representing Santa.""" | 19 | """A class representing Santa.""" | ||
20 | 20 | ||||
21 | _kids = {} | 21 | _kids = {} | ||
22 | _wishes = OrderedDict() | 22 | _wishes = OrderedDict() | ||
23 | 23 | ||||
24 | def __call__(self, kid, phone_call): | 24 | def __call__(self, kid, phone_call): | ||
25 | """Handle a wish request made by a kid made by a phone call.""" | 25 | """Handle a wish request made by a kid made by a phone call.""" | ||
26 | wish = self.get_wish_of(phone_call) | 26 | wish = self.get_wish_of(phone_call) | ||
27 | self._wishes[id(kid)] = wish | 27 | self._wishes[id(kid)] = wish | ||
28 | 28 | ||||
29 | def __matmul__(self, letter): | 29 | def __matmul__(self, letter): | ||
30 | """Handle a wish request made by a Kid sent as a letter.""" | 30 | """Handle a wish request made by a Kid sent as a letter.""" | ||
31 | wish = self.get_wish_of(letter) | 31 | wish = self.get_wish_of(letter) | ||
32 | signature = int(re.search(r'(\b\d+\b)', letter).group(0)) | 32 | signature = int(re.search(r'(\b\d+\b)', letter).group(0)) | ||
33 | self._wishes[signature] = wish | 33 | self._wishes[signature] = wish | ||
34 | 34 | ||||
35 | def get_wish_of(self, source): | 35 | def get_wish_of(self, source): | ||
36 | """Match the wish in source.""" | 36 | """Match the wish in source.""" | ||
n | 37 | wish_match = re.search(r"['\"]([A-Za-z0-9 ]+)['\"]", source, re.MULTILINE | re.DOTALL) | n | 37 | wish_match = re.search(r"(['\"])([\w ]+)\1", source, re.MULTILINE | re.DOTALL) |
38 | return wish_match.group(1) | 38 | return wish_match.group(1) | ||
39 | 39 | ||||
40 | @classmethod | 40 | @classmethod | ||
41 | def add_new_kid(cls, kid): | 41 | def add_new_kid(cls, kid): | ||
42 | """Save kids in order to be able to call them.""" | 42 | """Save kids in order to be able to call them.""" | ||
43 | cls._kids[id(kid)] = kid | 43 | cls._kids[id(kid)] = kid | ||
44 | 44 | ||||
45 | def __iter__(self): | 45 | def __iter__(self): | ||
46 | """Return an iterator for Santa's presents.""" | 46 | """Return an iterator for Santa's presents.""" | ||
47 | self._all_presents = list(self._wishes.values()) | 47 | self._all_presents = list(self._wishes.values()) | ||
48 | self._index = 0 | 48 | self._index = 0 | ||
49 | return self | 49 | return self | ||
50 | 50 | ||||
51 | def __next__(self): | 51 | def __next__(self): | ||
52 | """Return the next present in the list.""" | 52 | """Return the next present in the list.""" | ||
53 | if self._index < len(self._all_presents): | 53 | if self._index < len(self._all_presents): | ||
54 | result = self._all_presents[self._index] | 54 | result = self._all_presents[self._index] | ||
55 | self._index += 1 | 55 | self._index += 1 | ||
56 | return result | 56 | return result | ||
57 | raise StopIteration | 57 | raise StopIteration | ||
58 | 58 | ||||
59 | def _get_most_common_gift(self): | 59 | def _get_most_common_gift(self): | ||
60 | """Find the most common gift.""" | 60 | """Find the most common gift.""" | ||
61 | gifts = list(self._wishes.values()) | 61 | gifts = list(self._wishes.values()) | ||
62 | gift_counts = {gift: gifts.count(gift) for gift in set(gifts)} | 62 | gift_counts = {gift: gifts.count(gift) for gift in set(gifts)} | ||
63 | 63 | ||||
64 | max_count = max(gift_counts.values()) | 64 | max_count = max(gift_counts.values()) | ||
65 | most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count] | 65 | most_frequent_gifts = [gift for gift, count in gift_counts.items() if count == max_count] | ||
66 | 66 | ||||
67 | return random.choice(most_frequent_gifts) | 67 | return random.choice(most_frequent_gifts) | ||
68 | 68 | ||||
69 | def to_next_christmas(self): | 69 | def to_next_christmas(self): | ||
70 | """Age up all kids and clear gifts for next Christmas.""" | 70 | """Age up all kids and clear gifts for next Christmas.""" | ||
71 | self._wishes = OrderedDict() | 71 | self._wishes = OrderedDict() | ||
72 | for kid in self._kids.values(): | 72 | for kid in self._kids.values(): | ||
73 | kid.age_up() | 73 | kid.age_up() | ||
74 | kid.set_is_good() | 74 | kid.set_is_good() | ||
75 | 75 | ||||
76 | def _handle_kid(self, id, instance): | 76 | def _handle_kid(self, id, instance): | ||
77 | """Handle the present for a kid.""" | 77 | """Handle the present for a kid.""" | ||
78 | if instance.age >= 5: | 78 | if instance.age >= 5: | ||
79 | return | 79 | return | ||
80 | 80 | ||||
81 | if not instance.is_good: | 81 | if not instance.is_good: | ||
82 | instance('coal') | 82 | instance('coal') | ||
83 | elif id in self._wishes: | 83 | elif id in self._wishes: | ||
84 | instance(self._wishes[id]) | 84 | instance(self._wishes[id]) | ||
85 | else: | 85 | else: | ||
86 | instance(self._get_most_common_gift()) | 86 | instance(self._get_most_common_gift()) | ||
87 | 87 | ||||
88 | def xmas(self): | 88 | def xmas(self): | ||
89 | """Distribute presents according to the rules.""" | 89 | """Distribute presents according to the rules.""" | ||
90 | if not self._wishes: | 90 | if not self._wishes: | ||
91 | self.to_next_christmas() | 91 | self.to_next_christmas() | ||
92 | return | 92 | return | ||
93 | 93 | ||||
94 | for id, instance in self._kids.items(): | 94 | for id, instance in self._kids.items(): | ||
95 | self._handle_kid(id, instance) | 95 | self._handle_kid(id, instance) | ||
96 | 96 | ||||
97 | self.to_next_christmas() | 97 | self.to_next_christmas() | ||
98 | 98 | ||||
99 | class Kid(type): | 99 | class Kid(type): | ||
100 | """Metaclass that ensures every new kid is registered in Santa and has required methods.""" | 100 | """Metaclass that ensures every new kid is registered in Santa and has required methods.""" | ||
101 | 101 | ||||
102 | def __new__(cls, name, bases, attributes): | 102 | def __new__(cls, name, bases, attributes): | ||
103 | if '__call__' not in attributes: | 103 | if '__call__' not in attributes: | ||
104 | raise NotImplementedError("О, неразумни юроде!") | 104 | raise NotImplementedError("О, неразумни юроде!") | ||
105 | 105 | ||||
106 | new_class = super().__new__(cls, name, bases, attributes) | 106 | new_class = super().__new__(cls, name, bases, attributes) | ||
107 | 107 | ||||
108 | interface = cls.create_kid_methods() | 108 | interface = cls.create_kid_methods() | ||
109 | new_class.__init__ = interface[0] | 109 | new_class.__init__ = interface[0] | ||
110 | new_class.age_up = interface[1] | 110 | new_class.age_up = interface[1] | ||
111 | new_class.set_is_good = interface[2] | 111 | new_class.set_is_good = interface[2] | ||
112 | return new_class | 112 | return new_class | ||
113 | 113 | ||||
114 | def __init__(cls, name, bases, attributes): | 114 | def __init__(cls, name, bases, attributes): | ||
115 | """Validate is kid good when initialized.""" | 115 | """Validate is kid good when initialized.""" | ||
116 | for method_name, method in cls.__dict__.items(): | 116 | for method_name, method in cls.__dict__.items(): | ||
117 | if callable(method) and not method_name.startswith('_'): | 117 | if callable(method) and not method_name.startswith('_'): | ||
118 | setattr(cls, method_name, cls.wrapped_method(method)) | 118 | setattr(cls, method_name, cls.wrapped_method(method)) | ||
119 | 119 | ||||
120 | @staticmethod | 120 | @staticmethod | ||
121 | def create_kid_methods(): | 121 | def create_kid_methods(): | ||
122 | """Generate __init__, age_up, set_is_good.""" | 122 | """Generate __init__, age_up, set_is_good.""" | ||
123 | def __init__(self, *args, **kwargs): | 123 | def __init__(self, *args, **kwargs): | ||
124 | self.age = 0 | 124 | self.age = 0 | ||
125 | self.is_good = True | 125 | self.is_good = True | ||
t | 126 | super(self.__class__, self).__init__(*args, **kwargs) | t | 126 | super().__init__(*args, **kwargs) |
127 | 127 | ||||
128 | def age_up(self): | 128 | def age_up(self): | ||
129 | self.age += 1 | 129 | self.age += 1 | ||
130 | 130 | ||||
131 | def set_is_good(self, is_good=True): | 131 | def set_is_good(self, is_good=True): | ||
132 | self.is_good = is_good | 132 | self.is_good = is_good | ||
133 | 133 | ||||
134 | return __init__, age_up, set_is_good | 134 | return __init__, age_up, set_is_good | ||
135 | 135 | ||||
136 | @staticmethod | 136 | @staticmethod | ||
137 | def wrapped_method(method): | 137 | def wrapped_method(method): | ||
138 | """Search for raised exception in public methods.""" | 138 | """Search for raised exception in public methods.""" | ||
139 | def decoratored_method(self, *args, **kwargs): | 139 | def decoratored_method(self, *args, **kwargs): | ||
140 | try: | 140 | try: | ||
141 | return method(self, *args, **kwargs) | 141 | return method(self, *args, **kwargs) | ||
142 | except Exception as err: | 142 | except Exception as err: | ||
143 | self.set_is_good(False) | 143 | self.set_is_good(False) | ||
144 | raise err | 144 | raise err | ||
145 | return decoratored_method | 145 | return decoratored_method | ||
146 | 146 | ||||
147 | def __call__(cls, *args, **kwargs): | 147 | def __call__(cls, *args, **kwargs): | ||
148 | """Add kid in the wishlist when a kid is called.""" | 148 | """Add kid in the wishlist when a kid is called.""" | ||
149 | instance = super().__call__(*args, **kwargs) | 149 | instance = super().__call__(*args, **kwargs) | ||
150 | Santa.add_new_kid(instance) | 150 | Santa.add_new_kid(instance) | ||
151 | return instance | 151 | return instance |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
19.12.2024 11:37
19.12.2024 11:37
19.12.2024 11:40
19.12.2024 11:41
19.12.2024 11:42
19.12.2024 11:50