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

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

10 точки общо

19 успешни теста
1 неуспешни теста
Код
Скрий всички коментари

  1import re
  2
  3
  4class Santa:
  5    _instance = None
  6
  7    def __new__(cls):
  8        if cls._instance is None:
  9            cls._instance = super(Santa, cls).__new__(cls)
 10        return cls._instance
 11
 12    def __init__(self):
 13        self.kids_requested = []
 14        self.requested_presents = []
 15        self.all_kids_ages = []
 16
 17    def __valid_kid_age(self, kid):
 18        for small_kid in self.all_kids_ages:
 19            if small_kid[0] == kid:
 20                return False if small_kid[1] > 5 else True
 21        return True
 22
 23    def __call__(self, kid, wish):
 24        match = re.search(r"([\'\"])[a-zA-Z0-9 ]*(\1)", wish)
 25
 26        if match:
 27            present = match.group(0).strip("'\"")
 28
 29            for index, kid_requested in enumerate(self.kids_requested):
 30                if kid == kid_requested:
 31                    self.requested_presents[index] = present
 32                    break
 33            else:
 34                self.kids_requested.append(kid)
 35                self.requested_presents.append(present)
 36        else:
 37            raise ValueError("Error in searching for requested present")
 38
 39    def __matmul__(self, wish):
 40        present_match = re.search(r"([\'\"])[a-zA-Z0-9 ]*(\1)", wish)
 41        signature_line_match = re.search(r"^\s*\d+\s*$", wish, re.MULTILINE)
 42
 43        if present_match and signature_line_match:
 44            present = present_match.group(0).strip("'\"")
 45            signature = signature_line_match.group(0).strip()
 46            kid = Kid.get_instance(signature)
 47
 48            for index, kid_requested in enumerate(self.kids_requested):
 49                if kid == kid_requested:
 50                    self.requested_presents[index] = present
 51                    break
 52            else:
 53                self.kids_requested.append(kid)
 54                self.requested_presents.append(present)
 55        elif present_match:
 56            raise ValueError("Error in searching for signature")
 57        elif signature_line_match:
 58            raise ValueError("Error in searching for requested present")
 59
 60    def __get_kids_not_requested(self):
 61        kids_not_requested = []
 62
 63        for kid in Kid.get_all_instances():
 64            for kid_requested in self.kids_requested:
 65                if kid == kid_requested:
 66                    break
 67            else:
 68                kids_not_requested.append(kid)
 69
 70        return kids_not_requested
 71
 72    def __update_kid_age(self, kid_to_update):
 73        for index, (kid, age) in enumerate(self.all_kids_ages):
 74            if kid == kid_to_update:
 75                self.all_kids_ages[index][1] += 1
 76                break
 77        else:
 78            self.all_kids_ages.append([kid_to_update, 1])
 79
 80    def xmas(self):
 81        if len(self.kids_requested) == 0:
 82            for kid in Kid.get_all_instances():
 83                self.__update_kid_age(kid)
 84            return
 85
 86        for index, kid_requested in enumerate(self.kids_requested):
 87            self.__update_kid_age(kid_requested)
 88            if not self.__valid_kid_age(kid_requested):
 89                continue
 90
 91            if getattr(kid_requested, "is_naughty", False) and kid_requested.is_naughty:
 92                kid_requested("coal")
 93                kid_requested.is_naughty = False
 94            else:
 95                kid_requested(self.requested_presents[index])
 96
 97        most_frequent_present = max(set(self.requested_presents), key=self.requested_presents.count)
 98
 99        for index, kid_not_requested in enumerate(self.__get_kids_not_requested()):
100            self.__update_kid_age(kid_not_requested)
101            if not self.__valid_kid_age(kid_not_requested):
102                continue
103
104            if getattr(kid_not_requested, "is_naughty", False) and kid_not_requested.is_naughty:
105                kid_not_requested("coal")
106                kid_not_requested.is_naughty = False
107            else:
108                kid_not_requested(most_frequent_present)
109
110        self.kids_requested = []
111        self.requested_presents = []
112
113    def __iter__(self):
114        return self.requested_presents.__iter__()
115
116
117class Kid(type):
118    _instances = []
119
120    def __new__(cls, name, bases, class_dict):
121        for attr_name, attr_value in class_dict.items():
122            if callable(attr_value) and not attr_name.startswith("_"):
123                class_dict[attr_name] = cls.wrap_method(attr_value)
124
125        return super().__new__(cls, name, bases, class_dict)
126
127    def __init__(cls, name, bases, dct):
128        if '__call__' not in dct:
129            raise NotImplementedError(f"Class {name} must implement __call__ method.")
130        super().__init__(name, bases, dct)
131
132    def __call__(cls, *args, **kwargs):
133        kid_instance = super().__call__(*args, **kwargs)
134        cls._instances.append(kid_instance)
135
136        return kid_instance
137
138    @staticmethod
139    def wrap_method(method):
140        def wrapped_method(self, *args, **kwargs):
141            result = 0
142
143            try:
144                result = method(self, *args, **kwargs)
145            except Exception:
146                self.is_naughty = True
147
148            return result
149
150        return wrapped_method
151
152    @classmethod
153    def get_instance(cls, identification):
154        for instance in cls._instances:
155            if id(instance) == int(identification):
156                return instance
157
158        raise ValueError("No instance with given identification")
159
160    @classmethod
161    def get_all_instances(cls):
162        return cls._instances[:]

.............F......
======================================================================
FAIL: test_xmass_naughty (test.TestSanta.test_xmass_naughty)
Test a Christmas with naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 222, in test_xmass_naughty
with self.assertRaises(ZeroDivisionError):
AssertionError: ZeroDivisionError not raised

----------------------------------------------------------------------
Ran 20 tests in 0.024s

FAILED (failures=1)

Дискусия
История
Това решение има само една версия.