Домашни > Подаръци ще има за всички от сърце > Решения > Решението на Илиана Миладинова

Резултати
10 точки от тестове
1 точки от учител

11 точки общо

19 успешни теста
1 неуспешни теста
Код (Поправка на нещата от обратната връзка)

  1import re
  2
  3
  4class Singleton(type):
  5    _instances = {}
  6
  7    def __call__(cls, *args, **kwargs):
  8        if cls not in cls._instances:
  9            cls._instances[cls] = super().__call__(*args, **kwargs)
 10        return cls._instances[cls]
 11    
 12
 13class Santa(metaclass=Singleton):
 14    _MAX_AGE = 5
 15
 16    def __init__(self):
 17        self._wishes = {}
 18
 19    def _get_wish(self, text):
 20        """Get the wish from the letter/call"""
 21        
 22        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'
 23        wish = re.search(pattern, text)
 24        if wish:
 25            return wish.group(1)
 26
 27    def __call__(self, kid, text):
 28        wish = self._get_wish(text)
 29        if wish:
 30           self._wishes[id(kid)] = wish  
 31                
 32    def _get_signature(self, text):
 33        """Get the signature of the kid from the letter"""
 34
 35        pattern = r'\b\d+\b(?=\s*$)'
 36        signature = re.search(pattern, text)
 37        if signature:
 38            return signature.group().strip()
 39    
 40    def __matmul__(self, text):
 41        signature = self._get_signature(text)
 42        wish = self._get_wish(text)
 43        if signature and wish:
 44           self._wishes[int(signature)] = wish  
 45
 46    def __iter__(self):
 47        for val in self._wishes.values():
 48            yield val
 49    
 50    @property
 51    def _get_most_wanted_gift(self):
 52        """Get the most wanted gift"""
 53
 54        wishes = list(self._wishes.values())
 55        return max(wishes, key=wishes.count)
 56    
 57    def _clear_xmas(self):
 58        """Clear the wishes and _naughty_kids"""
 59
 60        self._wishes.clear()
 61        Kid._naughty_kids.clear()
 62
 63    def xmas(self):
 64        Kid._increment_ages()
 65
 66        if not self._wishes:
 67            return
 68        
 69        most_wanted_gift = self._get_most_wanted_gift
 70        for identity, kid in Kid._kids_instances.items():
 71            if Kid._kids_ages[identity] <= self._MAX_AGE:
 72                if kid in Kid._naughty_kids:
 73                    kid('coal')
 74                else:
 75                    if identity in self._wishes:
 76                        wish = self._wishes[identity]
 77                    else:
 78                        wish = most_wanted_gift
 79                    kid(wish)
 80
 81        self._clear_xmas()
 82        
 83
 84class Kid(type):
 85    _kids_ages = {}
 86    _kids_instances = {}
 87    _naughty_kids = set()
 88    
 89    @classmethod
 90    def _check_naughty(cls, method):
 91        def wrapper(self, *args, **kwargs):
 92            """Add the instance to _naughty_kids if an exception is raised in method"""
 93
 94            try:
 95                return method(self, *args, **kwargs)
 96            except Exception:
 97                cls._naughty_kids.add(self)
 98                raise
 99        return wrapper
100
101    def __new__(cls, name, bases, dct):
102        if '__call__' not in dct:
103            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')
104        
105        for attribute_name, attribute_val in dct.items():
106            if callable(attribute_val):
107                if not attribute_name.startswith('_'):
108                    dct[attribute_name] = cls._check_naughty(attribute_val)
109
110        return super().__new__(cls, name, bases, dct)
111    
112    def __call__(cls, *args, **kwargs):      
113        new_kid = super().__call__(*args, **kwargs)
114        identity = id(new_kid)
115        cls._kids_ages[identity] = 0
116        cls._kids_instances[identity] = new_kid
117        return new_kid
118        
119    @classmethod
120    def _increment_ages(cls):
121        """Increment the age of each kid by one year"""
122
123        for identity, age in cls._kids_ages.items():
124            cls._kids_ages[identity] += 1 

......F.............
======================================================================
FAIL: test_present_matching (test.TestSanta.test_present_matching)
Test matching signature in the letter.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 92, in test_present_matching
self.assertEqual(list(self.santa), ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 '])
AssertionError: Lists differ: ['toy4'] != ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 ']

Second list contains 1 additional elements.
First extra element 1:
'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 '

- ['toy4']
+ ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 ']

----------------------------------------------------------------------
Ran 20 tests in 0.039s

FAILED (failures=1)

Дискусия
История

f1import ref1import re
22
33
4class Singleton(type):4class Singleton(type):
5    _instances = {}5    _instances = {}
66
7    def __call__(cls, *args, **kwargs):7    def __call__(cls, *args, **kwargs):
8        if cls not in cls._instances:8        if cls not in cls._instances:
9            cls._instances[cls] = super().__call__(*args, **kwargs)9            cls._instances[cls] = super().__call__(*args, **kwargs)
10        return cls._instances[cls]10        return cls._instances[cls]
11    11    
1212
13class Santa(metaclass=Singleton):13class Santa(metaclass=Singleton):
nn14    _MAX_AGE = 5
15 
14    def __init__(self):16    def __init__(self):
15        self._wishes = {}17        self._wishes = {}
1618
17    def _get_wish(self, text):19    def _get_wish(self, text):
18        """Get the wish from the letter/call"""20        """Get the wish from the letter/call"""
19        21        
20        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'22        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'
21        wish = re.search(pattern, text)23        wish = re.search(pattern, text)
22        if wish:24        if wish:
23            return wish.group(1)25            return wish.group(1)
2426
25    def __call__(self, kid, text):27    def __call__(self, kid, text):
26        wish = self._get_wish(text)28        wish = self._get_wish(text)
27        if wish:29        if wish:
28           self._wishes[id(kid)] = wish  30           self._wishes[id(kid)] = wish  
29                31                
30    def _get_signature(self, text):32    def _get_signature(self, text):
31        """Get the signature of the kid from the letter"""33        """Get the signature of the kid from the letter"""
3234
33        pattern = r'\b\d+\b(?=\s*$)'35        pattern = r'\b\d+\b(?=\s*$)'
34        signature = re.search(pattern, text)36        signature = re.search(pattern, text)
35        if signature:37        if signature:
36            return signature.group().strip()38            return signature.group().strip()
37    39    
38    def __matmul__(self, text):40    def __matmul__(self, text):
39        signature = self._get_signature(text)41        signature = self._get_signature(text)
40        wish = self._get_wish(text)42        wish = self._get_wish(text)
41        if signature and wish:43        if signature and wish:
42           self._wishes[int(signature)] = wish  44           self._wishes[int(signature)] = wish  
n43    n
44    @property
45    def _generator(self):
46        for key, val in self._wishes.items():
47            yield self._wishes[key]
4845
49    def __iter__(self):46    def __iter__(self):
n50        return self._generatorn
51    
52    def _count_wish_occurence(self, wish):
53        """Count the number of times a gift has been wished"""
54 
55        count = 0
56        for key, val in self._wishes.items():47        for val in self._wishes.values():
57            if(val == wish):48            yield val
58                count += 1
59        return count
60    
61    @property
62    def _get_most_wanted_gift_count(self):
63        """Get the number of times the most wanted gift has been wished"""
64 
65        max_count = 0
66        for key, val in self._wishes.items():
67            curr_count = self._count_wish_occurence(val)
68            if curr_count > max_count:
69                max_count = curr_count
70        return max_count
71    49    
72    @property50    @property
73    def _get_most_wanted_gift(self):51    def _get_most_wanted_gift(self):
74        """Get the most wanted gift"""52        """Get the most wanted gift"""
7553
n76        most_wanted_gift_count = self._get_most_wanted_gift_countn54        wishes = list(self._wishes.values())
77        for key, val in self._wishes.items():55        return max(wishes, key=wishes.count)
78            if self._count_wish_occurence(val) == most_wanted_gift_count:
79                return val
80    56    
81    def _clear_xmas(self):57    def _clear_xmas(self):
82        """Clear the wishes and _naughty_kids"""58        """Clear the wishes and _naughty_kids"""
8359
84        self._wishes.clear()60        self._wishes.clear()
85        Kid._naughty_kids.clear()61        Kid._naughty_kids.clear()
8662
87    def xmas(self):63    def xmas(self):
88        Kid._increment_ages()64        Kid._increment_ages()
8965
90        if not self._wishes:66        if not self._wishes:
91            return67            return
92        68        
93        most_wanted_gift = self._get_most_wanted_gift69        most_wanted_gift = self._get_most_wanted_gift
94        for identity, kid in Kid._kids_instances.items():70        for identity, kid in Kid._kids_instances.items():
n95            if Kid._kids_ages[identity] <= 5:n71            if Kid._kids_ages[identity] <= self._MAX_AGE:
96                if kid in Kid._naughty_kids:72                if kid in Kid._naughty_kids:
97                    kid('coal')73                    kid('coal')
98                else:74                else:
99                    if identity in self._wishes:75                    if identity in self._wishes:
100                        wish = self._wishes[identity]76                        wish = self._wishes[identity]
101                    else:77                    else:
102                        wish = most_wanted_gift78                        wish = most_wanted_gift
103                    kid(wish)79                    kid(wish)
10480
105        self._clear_xmas()81        self._clear_xmas()
106        82        
10783
108class Kid(type):84class Kid(type):
109    _kids_ages = {}85    _kids_ages = {}
110    _kids_instances = {}86    _kids_instances = {}
111    _naughty_kids = set()87    _naughty_kids = set()
112    88    
113    @classmethod89    @classmethod
114    def _check_naughty(cls, method):90    def _check_naughty(cls, method):
115        def wrapper(self, *args, **kwargs):91        def wrapper(self, *args, **kwargs):
116            """Add the instance to _naughty_kids if an exception is raised in method"""92            """Add the instance to _naughty_kids if an exception is raised in method"""
11793
118            try:94            try:
119                return method(self, *args, **kwargs)95                return method(self, *args, **kwargs)
120            except Exception:96            except Exception:
121                cls._naughty_kids.add(self)97                cls._naughty_kids.add(self)
122                raise98                raise
123        return wrapper99        return wrapper
124100
125    def __new__(cls, name, bases, dct):101    def __new__(cls, name, bases, dct):
126        if '__call__' not in dct:102        if '__call__' not in dct:
127            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')103            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')
128        104        
129        for attribute_name, attribute_val in dct.items():105        for attribute_name, attribute_val in dct.items():
t130            if hasattr(attribute_val, '__call__'):t106            if callable(attribute_val):
131                if not attribute_name.startswith('_'):107                if not attribute_name.startswith('_'):
132                    dct[attribute_name] = cls._check_naughty(attribute_val)108                    dct[attribute_name] = cls._check_naughty(attribute_val)
133109
134        return super().__new__(cls, name, bases, dct)110        return super().__new__(cls, name, bases, dct)
135    111    
136    def __call__(cls, *args, **kwargs):      112    def __call__(cls, *args, **kwargs):      
137        new_kid = super().__call__(*args, **kwargs)113        new_kid = super().__call__(*args, **kwargs)
138        identity = id(new_kid)114        identity = id(new_kid)
139        cls._kids_ages[identity] = 0115        cls._kids_ages[identity] = 0
140        cls._kids_instances[identity] = new_kid116        cls._kids_instances[identity] = new_kid
141        return new_kid117        return new_kid
142        118        
143    @classmethod119    @classmethod
144    def _increment_ages(cls):120    def _increment_ages(cls):
145        """Increment the age of each kid by one year"""121        """Increment the age of each kid by one year"""
146122
147        for identity, age in cls._kids_ages.items():123        for identity, age in cls._kids_ages.items():
148            cls._kids_ages[identity] += 1 124            cls._kids_ages[identity] += 1 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import ref1import re
22
33
4class Singleton(type):4class Singleton(type):
5    _instances = {}5    _instances = {}
66
7    def __call__(cls, *args, **kwargs):7    def __call__(cls, *args, **kwargs):
8        if cls not in cls._instances:8        if cls not in cls._instances:
9            cls._instances[cls] = super().__call__(*args, **kwargs)9            cls._instances[cls] = super().__call__(*args, **kwargs)
10        return cls._instances[cls]10        return cls._instances[cls]
11    11    
1212
13class Santa(metaclass=Singleton):13class Santa(metaclass=Singleton):
14    def __init__(self):14    def __init__(self):
15        self._wishes = {}15        self._wishes = {}
1616
17    def _get_wish(self, text):17    def _get_wish(self, text):
18        """Get the wish from the letter/call"""18        """Get the wish from the letter/call"""
19        19        
20        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'20        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'
21        wish = re.search(pattern, text)21        wish = re.search(pattern, text)
22        if wish:22        if wish:
23            return wish.group(1)23            return wish.group(1)
2424
25    def __call__(self, kid, text):25    def __call__(self, kid, text):
26        wish = self._get_wish(text)26        wish = self._get_wish(text)
27        if wish:27        if wish:
28           self._wishes[id(kid)] = wish  28           self._wishes[id(kid)] = wish  
29                29                
30    def _get_signature(self, text):30    def _get_signature(self, text):
31        """Get the signature of the kid from the letter"""31        """Get the signature of the kid from the letter"""
3232
33        pattern = r'\b\d+\b(?=\s*$)'33        pattern = r'\b\d+\b(?=\s*$)'
34        signature = re.search(pattern, text)34        signature = re.search(pattern, text)
35        if signature:35        if signature:
36            return signature.group().strip()36            return signature.group().strip()
37    37    
38    def __matmul__(self, text):38    def __matmul__(self, text):
39        signature = self._get_signature(text)39        signature = self._get_signature(text)
40        wish = self._get_wish(text)40        wish = self._get_wish(text)
41        if signature and wish:41        if signature and wish:
42           self._wishes[int(signature)] = wish  42           self._wishes[int(signature)] = wish  
43    43    
44    @property44    @property
45    def _generator(self):45    def _generator(self):
46        for key, val in self._wishes.items():46        for key, val in self._wishes.items():
47            yield self._wishes[key]47            yield self._wishes[key]
4848
49    def __iter__(self):49    def __iter__(self):
50        return self._generator50        return self._generator
51    51    
52    def _count_wish_occurence(self, wish):52    def _count_wish_occurence(self, wish):
53        """Count the number of times a gift has been wished"""53        """Count the number of times a gift has been wished"""
5454
55        count = 055        count = 0
56        for key, val in self._wishes.items():56        for key, val in self._wishes.items():
57            if(val == wish):57            if(val == wish):
58                count += 158                count += 1
59        return count59        return count
60    60    
61    @property61    @property
62    def _get_most_wanted_gift_count(self):62    def _get_most_wanted_gift_count(self):
63        """Get the number of times the most wanted gift has been wished"""63        """Get the number of times the most wanted gift has been wished"""
6464
65        max_count = 065        max_count = 0
66        for key, val in self._wishes.items():66        for key, val in self._wishes.items():
67            curr_count = self._count_wish_occurence(val)67            curr_count = self._count_wish_occurence(val)
68            if curr_count > max_count:68            if curr_count > max_count:
69                max_count = curr_count69                max_count = curr_count
70        return max_count70        return max_count
71    71    
72    @property72    @property
73    def _get_most_wanted_gift(self):73    def _get_most_wanted_gift(self):
74        """Get the most wanted gift"""74        """Get the most wanted gift"""
7575
76        most_wanted_gift_count = self._get_most_wanted_gift_count76        most_wanted_gift_count = self._get_most_wanted_gift_count
77        for key, val in self._wishes.items():77        for key, val in self._wishes.items():
78            if self._count_wish_occurence(val) == most_wanted_gift_count:78            if self._count_wish_occurence(val) == most_wanted_gift_count:
79                return val79                return val
80    80    
81    def _clear_xmas(self):81    def _clear_xmas(self):
82        """Clear the wishes and _naughty_kids"""82        """Clear the wishes and _naughty_kids"""
8383
84        self._wishes.clear()84        self._wishes.clear()
85        Kid._naughty_kids.clear()85        Kid._naughty_kids.clear()
8686
87    def xmas(self):87    def xmas(self):
88        Kid._increment_ages()88        Kid._increment_ages()
8989
90        if not self._wishes:90        if not self._wishes:
91            return91            return
92        92        
93        most_wanted_gift = self._get_most_wanted_gift93        most_wanted_gift = self._get_most_wanted_gift
94        for identity, kid in Kid._kids_instances.items():94        for identity, kid in Kid._kids_instances.items():
95            if Kid._kids_ages[identity] <= 5:95            if Kid._kids_ages[identity] <= 5:
96                if kid in Kid._naughty_kids:96                if kid in Kid._naughty_kids:
t97                    kid("coal")t97                    kid('coal')
98                else:98                else:
99                    if identity in self._wishes:99                    if identity in self._wishes:
100                        wish = self._wishes[identity]100                        wish = self._wishes[identity]
101                    else:101                    else:
102                        wish = most_wanted_gift102                        wish = most_wanted_gift
103                    kid(wish)103                    kid(wish)
104104
105        self._clear_xmas()105        self._clear_xmas()
106        106        
107107
108class Kid(type):108class Kid(type):
109    _kids_ages = {}109    _kids_ages = {}
110    _kids_instances = {}110    _kids_instances = {}
111    _naughty_kids = set()111    _naughty_kids = set()
112    112    
113    @classmethod113    @classmethod
114    def _check_naughty(cls, method):114    def _check_naughty(cls, method):
115        def wrapper(self, *args, **kwargs):115        def wrapper(self, *args, **kwargs):
116            """Add the instance to _naughty_kids if an exception is raised in method"""116            """Add the instance to _naughty_kids if an exception is raised in method"""
117117
118            try:118            try:
119                return method(self, *args, **kwargs)119                return method(self, *args, **kwargs)
120            except Exception:120            except Exception:
121                cls._naughty_kids.add(self)121                cls._naughty_kids.add(self)
122                raise122                raise
123        return wrapper123        return wrapper
124124
125    def __new__(cls, name, bases, dct):125    def __new__(cls, name, bases, dct):
126        if '__call__' not in dct:126        if '__call__' not in dct:
127            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')127            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')
128        128        
129        for attribute_name, attribute_val in dct.items():129        for attribute_name, attribute_val in dct.items():
130            if hasattr(attribute_val, '__call__'):130            if hasattr(attribute_val, '__call__'):
131                if not attribute_name.startswith('_'):131                if not attribute_name.startswith('_'):
132                    dct[attribute_name] = cls._check_naughty(attribute_val)132                    dct[attribute_name] = cls._check_naughty(attribute_val)
133133
134        return super().__new__(cls, name, bases, dct)134        return super().__new__(cls, name, bases, dct)
135    135    
136    def __call__(cls, *args, **kwargs):      136    def __call__(cls, *args, **kwargs):      
137        new_kid = super().__call__(*args, **kwargs)137        new_kid = super().__call__(*args, **kwargs)
138        identity = id(new_kid)138        identity = id(new_kid)
139        cls._kids_ages[identity] = 0139        cls._kids_ages[identity] = 0
140        cls._kids_instances[identity] = new_kid140        cls._kids_instances[identity] = new_kid
141        return new_kid141        return new_kid
142        142        
143    @classmethod143    @classmethod
144    def _increment_ages(cls):144    def _increment_ages(cls):
145        """Increment the age of each kid by one year"""145        """Increment the age of each kid by one year"""
146146
147        for identity, age in cls._kids_ages.items():147        for identity, age in cls._kids_ages.items():
148            cls._kids_ages[identity] += 1 148            cls._kids_ages[identity] += 1 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import ref1import re
t2from unittest.mock import Mockt
32
43
5class Singleton(type):4class Singleton(type):
6    _instances = {}5    _instances = {}
76
8    def __call__(cls, *args, **kwargs):7    def __call__(cls, *args, **kwargs):
9        if cls not in cls._instances:8        if cls not in cls._instances:
10            cls._instances[cls] = super().__call__(*args, **kwargs)9            cls._instances[cls] = super().__call__(*args, **kwargs)
11        return cls._instances[cls]10        return cls._instances[cls]
12    11    
1312
14class Santa(metaclass=Singleton):13class Santa(metaclass=Singleton):
15    def __init__(self):14    def __init__(self):
16        self._wishes = {}15        self._wishes = {}
1716
18    def _get_wish(self, text):17    def _get_wish(self, text):
19        """Get the wish from the letter/call"""18        """Get the wish from the letter/call"""
20        19        
21        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'20        pattern = r'[\"\']([A-Za-z0-9 ]+)[\"\']'
22        wish = re.search(pattern, text)21        wish = re.search(pattern, text)
23        if wish:22        if wish:
24            return wish.group(1)23            return wish.group(1)
2524
26    def __call__(self, kid, text):25    def __call__(self, kid, text):
27        wish = self._get_wish(text)26        wish = self._get_wish(text)
28        if wish:27        if wish:
29           self._wishes[id(kid)] = wish  28           self._wishes[id(kid)] = wish  
30                29                
31    def _get_signature(self, text):30    def _get_signature(self, text):
32        """Get the signature of the kid from the letter"""31        """Get the signature of the kid from the letter"""
3332
34        pattern = r'\b\d+\b(?=\s*$)'33        pattern = r'\b\d+\b(?=\s*$)'
35        signature = re.search(pattern, text)34        signature = re.search(pattern, text)
36        if signature:35        if signature:
37            return signature.group().strip()36            return signature.group().strip()
38    37    
39    def __matmul__(self, text):38    def __matmul__(self, text):
40        signature = self._get_signature(text)39        signature = self._get_signature(text)
41        wish = self._get_wish(text)40        wish = self._get_wish(text)
42        if signature and wish:41        if signature and wish:
43           self._wishes[int(signature)] = wish  42           self._wishes[int(signature)] = wish  
44    43    
45    @property44    @property
46    def _generator(self):45    def _generator(self):
47        for key, val in self._wishes.items():46        for key, val in self._wishes.items():
48            yield self._wishes[key]47            yield self._wishes[key]
4948
50    def __iter__(self):49    def __iter__(self):
51        return self._generator50        return self._generator
52    51    
53    def _count_wish_occurence(self, wish):52    def _count_wish_occurence(self, wish):
54        """Count the number of times a gift has been wished"""53        """Count the number of times a gift has been wished"""
5554
56        count = 055        count = 0
57        for key, val in self._wishes.items():56        for key, val in self._wishes.items():
58            if(val == wish):57            if(val == wish):
59                count += 158                count += 1
60        return count59        return count
61    60    
62    @property61    @property
63    def _get_most_wanted_gift_count(self):62    def _get_most_wanted_gift_count(self):
64        """Get the number of times the most wanted gift has been wished"""63        """Get the number of times the most wanted gift has been wished"""
6564
66        max_count = 065        max_count = 0
67        for key, val in self._wishes.items():66        for key, val in self._wishes.items():
68            curr_count = self._count_wish_occurence(val)67            curr_count = self._count_wish_occurence(val)
69            if curr_count > max_count:68            if curr_count > max_count:
70                max_count = curr_count69                max_count = curr_count
71        return max_count70        return max_count
72    71    
73    @property72    @property
74    def _get_most_wanted_gift(self):73    def _get_most_wanted_gift(self):
75        """Get the most wanted gift"""74        """Get the most wanted gift"""
7675
77        most_wanted_gift_count = self._get_most_wanted_gift_count76        most_wanted_gift_count = self._get_most_wanted_gift_count
78        for key, val in self._wishes.items():77        for key, val in self._wishes.items():
79            if self._count_wish_occurence(val) == most_wanted_gift_count:78            if self._count_wish_occurence(val) == most_wanted_gift_count:
80                return val79                return val
81    80    
82    def _clear_xmas(self):81    def _clear_xmas(self):
83        """Clear the wishes and _naughty_kids"""82        """Clear the wishes and _naughty_kids"""
8483
85        self._wishes.clear()84        self._wishes.clear()
86        Kid._naughty_kids.clear()85        Kid._naughty_kids.clear()
8786
88    def xmas(self):87    def xmas(self):
89        Kid._increment_ages()88        Kid._increment_ages()
9089
91        if not self._wishes:90        if not self._wishes:
92            return91            return
93        92        
94        most_wanted_gift = self._get_most_wanted_gift93        most_wanted_gift = self._get_most_wanted_gift
95        for identity, kid in Kid._kids_instances.items():94        for identity, kid in Kid._kids_instances.items():
96            if Kid._kids_ages[identity] <= 5:95            if Kid._kids_ages[identity] <= 5:
97                if kid in Kid._naughty_kids:96                if kid in Kid._naughty_kids:
98                    kid("coal")97                    kid("coal")
99                else:98                else:
100                    if identity in self._wishes:99                    if identity in self._wishes:
101                        wish = self._wishes[identity]100                        wish = self._wishes[identity]
102                    else:101                    else:
103                        wish = most_wanted_gift102                        wish = most_wanted_gift
104                    kid(wish)103                    kid(wish)
105104
106        self._clear_xmas()105        self._clear_xmas()
107        106        
108107
109class Kid(type):108class Kid(type):
110    _kids_ages = {}109    _kids_ages = {}
111    _kids_instances = {}110    _kids_instances = {}
112    _naughty_kids = set()111    _naughty_kids = set()
113    112    
114    @classmethod113    @classmethod
115    def _check_naughty(cls, method):114    def _check_naughty(cls, method):
116        def wrapper(self, *args, **kwargs):115        def wrapper(self, *args, **kwargs):
117            """Add the instance to _naughty_kids if an exception is raised in method"""116            """Add the instance to _naughty_kids if an exception is raised in method"""
118117
119            try:118            try:
120                return method(self, *args, **kwargs)119                return method(self, *args, **kwargs)
121            except Exception:120            except Exception:
122                cls._naughty_kids.add(self)121                cls._naughty_kids.add(self)
123                raise122                raise
124        return wrapper123        return wrapper
125124
126    def __new__(cls, name, bases, dct):125    def __new__(cls, name, bases, dct):
127        if '__call__' not in dct:126        if '__call__' not in dct:
128            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')127            raise NotImplementedError('Sorry, but the instance of the class should be callable (dont get angry, please) :)')
129        128        
130        for attribute_name, attribute_val in dct.items():129        for attribute_name, attribute_val in dct.items():
131            if hasattr(attribute_val, '__call__'):130            if hasattr(attribute_val, '__call__'):
132                if not attribute_name.startswith('_'):131                if not attribute_name.startswith('_'):
133                    dct[attribute_name] = cls._check_naughty(attribute_val)132                    dct[attribute_name] = cls._check_naughty(attribute_val)
134133
135        return super().__new__(cls, name, bases, dct)134        return super().__new__(cls, name, bases, dct)
136    135    
137    def __call__(cls, *args, **kwargs):      136    def __call__(cls, *args, **kwargs):      
138        new_kid = super().__call__(*args, **kwargs)137        new_kid = super().__call__(*args, **kwargs)
139        identity = id(new_kid)138        identity = id(new_kid)
140        cls._kids_ages[identity] = 0139        cls._kids_ages[identity] = 0
141        cls._kids_instances[identity] = new_kid140        cls._kids_instances[identity] = new_kid
142        return new_kid141        return new_kid
143        142        
144    @classmethod143    @classmethod
145    def _increment_ages(cls):144    def _increment_ages(cls):
146        """Increment the age of each kid by one year"""145        """Increment the age of each kid by one year"""
147146
148        for identity, age in cls._kids_ages.items():147        for identity, age in cls._kids_ages.items():
149            cls._kids_ages[identity] += 1 148            cls._kids_ages[identity] += 1 
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op