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

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

10 точки общо

20 успешни теста
0 неуспешни теста
Код

  1import re
  2
  3class Santa:
  4    _instance = None
  5    _WISH_PATTERN = r"(\"|\')[A-Za-z0-9\s]+\1"
  6    _ID_PATTERN = r"^\s*\d+\s*$"
  7    _MAX_XMAS_COUNT = 5
  8    _kid_presents = {}
  9    _all_presents = {}
 10    _all_kids = []
 11    _presents = []
 12
 13    def __new__(cls, *args, **kwargs):
 14        if cls._instance is None:
 15            cls._instance = super().__new__(cls)
 16        return cls._instance
 17    
 18    def _present_checker(self, present):
 19        wish_match = re.search(self._WISH_PATTERN, present) 
 20        if not wish_match:
 21            raise TypeError('not a valid wish')
 22        
 23        return re.sub(r'(\'|\")', '', wish_match.group())
 24
 25    def _add_present(self, kid, present):
 26        current_present = self._kid_presents.get(kid, None)
 27
 28        if current_present:
 29            idx = self._presents.index(current_present)
 30            self._presents[idx] = present
 31        else:
 32            self._presents.append(present)
 33
 34        self._kid_presents[kid] = present
 35        self._all_presents[present] = self._all_presents.get(present, 0) + 1
 36
 37    def __call__(self, kid, message):
 38        present = self._present_checker(message)
 39        self._add_present(kid, present)
 40
 41    def __matmul__(self, letter):
 42        present = self._present_checker(letter)
 43        id_match = re.search(self._ID_PATTERN, letter, re.MULTILINE)
 44
 45        kid_id = int(re.sub(r'\s', '', id_match.group()))
 46        kid = Kid.get_instance(kid_id)
 47
 48        if kid is None:
 49            raise TypeError('not a valid kid')
 50
 51        self._add_present(kid, present)
 52
 53    def __iter__(self):
 54        for present in self._presents:
 55            yield present
 56    
 57    def _clear_list(self):
 58        self._kid_presents.clear()
 59        self._all_presents.clear()
 60        self._presents.clear()
 61
 62    def _xmas_checker(self):
 63        for kid in self._all_kids:
 64            if kid.xmas_count == self._MAX_XMAS_COUNT:
 65                Kid.remove_from_xmas(kid)
 66                continue
 67            kid.xmas_count += 1
 68
 69    def xmas(self):
 70        self._xmas_checker()
 71        
 72        if not self._kid_presents:
 73            return None
 74        
 75        best_present = max(self._all_presents, key=self._all_presents.get)
 76
 77        for kid in self._all_kids:
 78            if not kid._has_present:
 79                continue
 80            if kid._has_exception:
 81                kid('coal')
 82                Kid.reset_exception_status(kid)
 83            else:
 84                if kid not in self._kid_presents.keys():
 85                    kid(best_present)
 86                else:
 87                    kid(self._kid_presents[kid])
 88        
 89        self._clear_list()
 90
 91    @classmethod
 92    def add_kid(cls, kid):
 93        cls._all_kids.append(kid)
 94
 95
 96class Kid(type):
 97    _instances = {}
 98
 99    def __new__(cls, name, bases, attr_dict):
100        if '__call__' not in attr_dict.keys():
101            raise NotImplementedError
102        attr_dict['xmas_count'] = 0
103        attr_dict['_has_exception'] = False
104        attr_dict['_has_present'] = True
105
106        for name, value in attr_dict.items():
107            if callable(value) and not name.startswith('_'):
108                attr_dict[name] = cls.check_exceptions(value)
109        return super().__new__(cls, name, bases, attr_dict)
110    
111    @staticmethod
112    def check_exceptions(func):
113        def decorator(self, *args, **kwargs):
114            try:
115                return func(self, *args, **kwargs)
116            except Exception as e:
117                self._has_exception = True
118                raise
119        return decorator
120
121    @classmethod
122    def reset_exception_status(cls, instance):
123        instance._has_exception = False
124
125    @classmethod
126    def remove_from_xmas(cls, instance):
127        instance._has_present = False
128
129    def __call__(cls, *args, **kwargs):
130        instance = super().__call__(*args, **kwargs)
131        Santa.add_kid(instance)
132
133        if id(instance) not in Kid._instances.keys():
134            Kid._instances[id(instance)] = instance
135        
136        return instance
137
138    @classmethod
139    def get_instance(cls, instance_id):
140        return cls._instances.get(instance_id, None)

....................
----------------------------------------------------------------------
Ran 20 tests in 0.060s

OK

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

f1import ref1import re
22
3class Santa:3class Santa:
4    _instance = None4    _instance = None
n5    _wish_pattern = r"(\"|\')[A-Za-z0-9\s]+\1"n5    _WISH_PATTERN = r"(\"|\')[A-Za-z0-9\s]+\1"
6    _id_pattern = r"^\s*\d+\s*$"6    _ID_PATTERN = r"^\s*\d+\s*$"
7    _MAX_XMAS_COUNT = 5
7    _kid_presents = {}8    _kid_presents = {}
8    _all_presents = {}9    _all_presents = {}
9    _all_kids = []10    _all_kids = []
10    _presents = []11    _presents = []
1112
12    def __new__(cls, *args, **kwargs):13    def __new__(cls, *args, **kwargs):
13        if cls._instance is None:14        if cls._instance is None:
14            cls._instance = super().__new__(cls)15            cls._instance = super().__new__(cls)
15        return cls._instance16        return cls._instance
16    17    
17    def _present_checker(self, present):18    def _present_checker(self, present):
n18        wish_match = re.search(self._wish_pattern, present) n19        wish_match = re.search(self._WISH_PATTERN, present) 
19        if not wish_match:20        if not wish_match:
20            raise TypeError('not a valid wish')21            raise TypeError('not a valid wish')
21        22        
22        return re.sub(r'(\'|\")', '', wish_match.group())23        return re.sub(r'(\'|\")', '', wish_match.group())
2324
24    def _add_present(self, kid, present):25    def _add_present(self, kid, present):
25        current_present = self._kid_presents.get(kid, None)26        current_present = self._kid_presents.get(kid, None)
2627
27        if current_present:28        if current_present:
28            idx = self._presents.index(current_present)29            idx = self._presents.index(current_present)
29            self._presents[idx] = present30            self._presents[idx] = present
30        else:31        else:
31            self._presents.append(present)32            self._presents.append(present)
3233
33        self._kid_presents[kid] = present34        self._kid_presents[kid] = present
n34        if present not in self._all_presents.keys():n35        self._all_presents[present] = self._all_presents.get(present, 0) + 1
35            self._all_presents[present] = 0
36        self._all_presents[present] += 1
3736
38    def __call__(self, kid, message):37    def __call__(self, kid, message):
39        present = self._present_checker(message)38        present = self._present_checker(message)
40        self._add_present(kid, present)39        self._add_present(kid, present)
4140
42    def __matmul__(self, letter):41    def __matmul__(self, letter):
43        present = self._present_checker(letter)42        present = self._present_checker(letter)
n44        id_match = re.search(self._id_pattern, letter, re.MULTILINE)n43        id_match = re.search(self._ID_PATTERN, letter, re.MULTILINE)
4544
46        kid_id = int(re.sub(r'\s', '', id_match.group()))45        kid_id = int(re.sub(r'\s', '', id_match.group()))
47        kid = Kid.get_instance(kid_id)46        kid = Kid.get_instance(kid_id)
4847
49        if kid is None:48        if kid is None:
50            raise TypeError('not a valid kid')49            raise TypeError('not a valid kid')
5150
52        self._add_present(kid, present)51        self._add_present(kid, present)
5352
54    def __iter__(self):53    def __iter__(self):
n55        for _ in self._presents:n54        for present in self._presents:
56            yield _55            yield present
57    56    
58    def _clear_list(self):57    def _clear_list(self):
59        self._kid_presents.clear()58        self._kid_presents.clear()
60        self._all_presents.clear()59        self._all_presents.clear()
61        self._presents.clear()60        self._presents.clear()
6261
63    def _xmas_checker(self):62    def _xmas_checker(self):
64        for kid in self._all_kids:63        for kid in self._all_kids:
n65            if kid.xmas_count == 5:n64            if kid.xmas_count == self._MAX_XMAS_COUNT:
66                Kid.remove_from_xmas(kid)65                Kid.remove_from_xmas(kid)
67                continue66                continue
68            kid.xmas_count += 167            kid.xmas_count += 1
6968
70    def xmas(self):69    def xmas(self):
71        self._xmas_checker()70        self._xmas_checker()
72        71        
73        if not self._kid_presents:72        if not self._kid_presents:
74            return None73            return None
75        74        
n76        best_present = self._most_wished_present()n75        best_present = max(self._all_presents, key=self._all_presents.get)
7776
78        for kid in self._all_kids:77        for kid in self._all_kids:
79            if not kid._has_present:78            if not kid._has_present:
80                continue79                continue
81            if kid._has_exception:80            if kid._has_exception:
82                kid('coal')81                kid('coal')
83                Kid.reset_exception_status(kid)82                Kid.reset_exception_status(kid)
84            else:83            else:
85                if kid not in self._kid_presents.keys():84                if kid not in self._kid_presents.keys():
86                    kid(best_present)85                    kid(best_present)
87                else:86                else:
88                    kid(self._kid_presents[kid])87                    kid(self._kid_presents[kid])
89        88        
90        self._clear_list()89        self._clear_list()
t91 t
92 
93    def _most_wished_present(self):
94        counter = 0
95        present = ''
96 
97        for curr_present, curr_count in self._all_presents.items():
98            if curr_count >= counter:
99                present = curr_present
100                counter = curr_count
101        
102        return present
103 
10490
105    @classmethod91    @classmethod
106    def add_kid(cls, kid):92    def add_kid(cls, kid):
107        cls._all_kids.append(kid)93        cls._all_kids.append(kid)
10894
10995
110class Kid(type):96class Kid(type):
111    _instances = {}97    _instances = {}
11298
113    def __new__(cls, name, bases, attr_dict):99    def __new__(cls, name, bases, attr_dict):
114        if '__call__' not in attr_dict.keys():100        if '__call__' not in attr_dict.keys():
115            raise NotImplementedError101            raise NotImplementedError
116        attr_dict['xmas_count'] = 0102        attr_dict['xmas_count'] = 0
117        attr_dict['_has_exception'] = False103        attr_dict['_has_exception'] = False
118        attr_dict['_has_present'] = True104        attr_dict['_has_present'] = True
119105
120        for name, value in attr_dict.items():106        for name, value in attr_dict.items():
121            if callable(value) and not name.startswith('_'):107            if callable(value) and not name.startswith('_'):
122                attr_dict[name] = cls.check_exceptions(value)108                attr_dict[name] = cls.check_exceptions(value)
123        return super().__new__(cls, name, bases, attr_dict)109        return super().__new__(cls, name, bases, attr_dict)
124    110    
125    @staticmethod111    @staticmethod
126    def check_exceptions(func):112    def check_exceptions(func):
127        def decorator(self, *args, **kwargs):113        def decorator(self, *args, **kwargs):
128            try:114            try:
129                return func(self, *args, **kwargs)115                return func(self, *args, **kwargs)
130            except Exception as e:116            except Exception as e:
131                self._has_exception = True117                self._has_exception = True
132                raise118                raise
133        return decorator119        return decorator
134120
135    @classmethod121    @classmethod
136    def reset_exception_status(cls, instance):122    def reset_exception_status(cls, instance):
137        instance._has_exception = False123        instance._has_exception = False
138124
139    @classmethod125    @classmethod
140    def remove_from_xmas(cls, instance):126    def remove_from_xmas(cls, instance):
141        instance._has_present = False127        instance._has_present = False
142128
143    def __call__(cls, *args, **kwargs):129    def __call__(cls, *args, **kwargs):
144        instance = super().__call__(*args, **kwargs)130        instance = super().__call__(*args, **kwargs)
145        Santa.add_kid(instance)131        Santa.add_kid(instance)
146132
147        if id(instance) not in Kid._instances.keys():133        if id(instance) not in Kid._instances.keys():
148            Kid._instances[id(instance)] = instance134            Kid._instances[id(instance)] = instance
149        135        
150        return instance136        return instance
151137
152    @classmethod138    @classmethod
153    def get_instance(cls, instance_id):139    def get_instance(cls, instance_id):
154        return cls._instances.get(instance_id, None)140        return cls._instances.get(instance_id, None)
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op