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

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

8 точки общо

16 успешни теста
4 неуспешни теста
Код (better late than never)

  1import gc
  2import re
  3
  4
  5class SingletonMeta(type):
  6    _instances = {}
  7
  8    def __call__(cls, *args, **kwargs):
  9        if cls not in cls._instances:
 10            cls._instances[cls] = super().__call__(*args, **kwargs)
 11        return cls._instances[cls]
 12    
 13
 14class Santa(metaclass=SingletonMeta):
 15
 16    _kids_dict = {}
 17    _wanted_gifts = 0
 18
 19    def __call__(self, kid_instance, present_str):
 20        gift_pattern = r"(['\"])([A-Za-z0-9\s]+)\1"
 21        match = re.search(gift_pattern, present_str)
 22
 23        if match:
 24            gift = match.group(2)
 25            self._kids_dict[id(kid_instance)]["present"] = gift
 26            self._wanted_gifts += 1
 27
 28    def __matmul__(self, letter):
 29        gift_pattern = r"(['\"])([A-Za-z0-9\s]+?)\1"
 30        gift_match = re.search(gift_pattern, letter)
 31        if gift_match:
 32            gift = gift_match.group(2)
 33
 34            signature_pattern = r"^\s*(\d+)\s*$"
 35            signature_match = re.search(
 36                signature_pattern, letter.strip().splitlines()[-1]
 37            )
 38
 39            if signature_match:
 40                child_id = signature_match.group(1)
 41                self._kids_dict[int(child_id)]["present"] = gift
 42                self._wanted_gifts += 1
 43
 44    def __iter__(self):
 45        value = True
 46        for kid in self._kids_dict.items():
 47            kid_id = kid[0]
 48            if self._kids_dict[kid_id]["present"]:
 49               value = False 
 50
 51        if value:
 52            return
 53
 54        for key, value in self._kids_dict.items():
 55            yield value["present"]
 56
 57    @staticmethod
 58    def add_kid(kid_class):
 59        Santa._kids_dict[id(kid_class)] = {"age": 0, "error_cnt": 0, "present": None}
 60
 61    @staticmethod
 62    def add_error(kid_class, error):
 63        Santa._kids_dict[id(kid_class)]["error_cnt"] += 1
 64
 65    def xmas(self):
 66        for kid in self._kids_dict.items():
 67            kid_id = kid[0]
 68            self._kids_dict[kid_id]["age"] += 1
 69
 70        if self._wanted_gifts < 1:
 71            return
 72        self._wanted_gifts = 0
 73
 74        for kid in self._kids_dict.items():
 75            kid_id = kid[0]
 76            if self._kids_dict[kid_id]["age"] > 5:
 77                continue
 78
 79            if self._kids_dict[kid_id]["error_cnt"] > 0:
 80                kid = get_instance_by_id(kid_id)
 81                kid("coal")
 82                self._kids_dict[kid_id]["error_cnt"] = 0
 83                continue
 84
 85            if kid[1]["present"] is not None:
 86                kid_instance = get_instance_by_id(kid_id)
 87                kid_instance(kid[1]["present"])
 88                continue
 89
 90            count_sort_arr = {}
 91            for present in self:
 92                if present is not None:
 93                    if present is not count_sort_arr:
 94                        count_sort_arr[present] = 0
 95                    else:
 96                        count_sort_arr[present] += 1
 97            most_frequent = max(count_sort_arr, key=count_sort_arr.get)
 98            kid_instance = get_instance_by_id(kid_id)
 99            kid_instance(most_frequent)
100
101            self._kids_dict[kid_id]["age"] += 1
102
103        for kid in self._kids_dict.items():
104            kid_id = kid[0]
105            self._kids_dict[kid_id]["present"] = None
106
107def get_instance_by_id(obj_id):
108    for obj in gc.get_objects():
109        if id(obj) == obj_id:
110            return obj
111    return None
112
113
114class Kid(type):
115    def __call__(cls, *args, **kwargs):
116        instance = super().__call__(*args, **kwargs)
117        Santa.add_kid(instance)
118        return instance
119
120    def __new__(cls, name, bases, dct):
121
122        if "__call__" not in dct:
123            raise NotImplementedError
124
125        for attr_name, attr_value in dct.items():
126            if (
127                callable(attr_value)
128                and not attr_name.startswith("__")
129                and not attr_name.startswith("_")
130            ):
131
132                def wrapper(self, *args, **kwargs):
133                    try:
134                        return attr_value(self, *args, **kwargs)
135                    except Exception as e:
136                        Santa.add_error(self, e)
137                        raise e
138
139                dct[attr_name] = wrapper
140        return super().__new__(cls, name, bases, dct)

......FF.....E...E..
======================================================================
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 223, in test_xmass_naughty
kid1.public_with_error()
File "/tmp/solution.py", line 137, in wrapper
raise e
File "/tmp/solution.py", line 134, in wrapper
return attr_value(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/test.py", line 30, in <lambda>
'_private_with_error': lambda self: not_existing,
^^^^^^^^^^^^
NameError: name 'not_existing' is not defined

======================================================================
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 246, in test_xmass_public_with_no_error
self.assertEqual(kid1.public_without_error(), 42)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 137, in wrapper
raise e
File "/tmp/solution.py", line 134, in wrapper
return attr_value(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/test.py", line 30, in <lambda>
'_private_with_error': lambda self: not_existing,
^^^^^^^^^^^^
NameError: name 'not_existing' is not defined

======================================================================
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', None] != ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 ']

First differing element 1:
None
'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 '

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

======================================================================
FAIL: test_santa_gift_order (test.TestSanta.test_santa_gift_order)
Test ordering of the Santa iterator.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 260, in test_santa_gift_order
self.assertEqual(list(self.santa), ["toy2v2", "toy3", "toy1"])
AssertionError: Lists differ: ['toy1', 'toy2v2', 'toy3'] != ['toy2v2', 'toy3', 'toy1']

First differing element 0:
'toy1'
'toy2v2'

- ['toy1', 'toy2v2', 'toy3']
+ ['toy2v2', 'toy3', 'toy1']

----------------------------------------------------------------------
Ran 20 tests in 0.074s

FAILED (failures=2, errors=2)

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

f1import gcf1import gc
2import re2import re
33
44
5class SingletonMeta(type):5class SingletonMeta(type):
6    _instances = {}6    _instances = {}
77
8    def __call__(cls, *args, **kwargs):8    def __call__(cls, *args, **kwargs):
9        if cls not in cls._instances:9        if cls not in cls._instances:
10            cls._instances[cls] = super().__call__(*args, **kwargs)10            cls._instances[cls] = super().__call__(*args, **kwargs)
11        return cls._instances[cls]11        return cls._instances[cls]
n12 n12    
1313
14class Santa(metaclass=SingletonMeta):14class Santa(metaclass=SingletonMeta):
1515
16    _kids_dict = {}16    _kids_dict = {}
17    _wanted_gifts = 017    _wanted_gifts = 0
1818
n19    def __call__(self, kid_class, present_str):n19    def __call__(self, kid_instance, present_str):
20        gift_pattern = r"(['\"])([A-Za-z0-9\s]+)\1"20        gift_pattern = r"(['\"])([A-Za-z0-9\s]+)\1"
21        match = re.search(gift_pattern, present_str)21        match = re.search(gift_pattern, present_str)
2222
23        if match:23        if match:
24            gift = match.group(2)24            gift = match.group(2)
n25            self._kids_dict[id(kid_class)]["present"] = giftn25            self._kids_dict[id(kid_instance)]["present"] = gift
26            self._wanted_gifts += 126            self._wanted_gifts += 1
2727
28    def __matmul__(self, letter):28    def __matmul__(self, letter):
29        gift_pattern = r"(['\"])([A-Za-z0-9\s]+?)\1"29        gift_pattern = r"(['\"])([A-Za-z0-9\s]+?)\1"
30        gift_match = re.search(gift_pattern, letter)30        gift_match = re.search(gift_pattern, letter)
31        if gift_match:31        if gift_match:
32            gift = gift_match.group(2)32            gift = gift_match.group(2)
3333
34            signature_pattern = r"^\s*(\d+)\s*$"34            signature_pattern = r"^\s*(\d+)\s*$"
35            signature_match = re.search(35            signature_match = re.search(
36                signature_pattern, letter.strip().splitlines()[-1]36                signature_pattern, letter.strip().splitlines()[-1]
37            )37            )
3838
39            if signature_match:39            if signature_match:
40                child_id = signature_match.group(1)40                child_id = signature_match.group(1)
41                self._kids_dict[int(child_id)]["present"] = gift41                self._kids_dict[int(child_id)]["present"] = gift
42                self._wanted_gifts += 142                self._wanted_gifts += 1
4343
44    def __iter__(self):44    def __iter__(self):
nn45        value = True
46        for kid in self._kids_dict.items():
47            kid_id = kid[0]
48            if self._kids_dict[kid_id]["present"]:
49               value = False 
50 
51        if value:
52            return
53 
45        for key, value in self._kids_dict.items():54        for key, value in self._kids_dict.items():
46            yield value["present"]55            yield value["present"]
4756
48    @staticmethod57    @staticmethod
49    def add_kid(kid_class):58    def add_kid(kid_class):
50        Santa._kids_dict[id(kid_class)] = {"age": 0, "error_cnt": 0, "present": None}59        Santa._kids_dict[id(kid_class)] = {"age": 0, "error_cnt": 0, "present": None}
5160
52    @staticmethod61    @staticmethod
53    def add_error(kid_class, error):62    def add_error(kid_class, error):
54        Santa._kids_dict[id(kid_class)]["error_cnt"] += 163        Santa._kids_dict[id(kid_class)]["error_cnt"] += 1
5564
56    def xmas(self):65    def xmas(self):
57        for kid in self._kids_dict.items():66        for kid in self._kids_dict.items():
58            kid_id = kid[0]67            kid_id = kid[0]
59            self._kids_dict[kid_id]["age"] += 168            self._kids_dict[kid_id]["age"] += 1
6069
61        if self._wanted_gifts < 1:70        if self._wanted_gifts < 1:
62            return71            return
63        self._wanted_gifts = 072        self._wanted_gifts = 0
6473
65        for kid in self._kids_dict.items():74        for kid in self._kids_dict.items():
66            kid_id = kid[0]75            kid_id = kid[0]
n67            if self._kids_dict[kid_id]["age"] > 6:n76            if self._kids_dict[kid_id]["age"] > 5:
68                continue77                continue
6978
70            if self._kids_dict[kid_id]["error_cnt"] > 0:79            if self._kids_dict[kid_id]["error_cnt"] > 0:
71                kid = get_instance_by_id(kid_id)80                kid = get_instance_by_id(kid_id)
72                kid("coal")81                kid("coal")
73                self._kids_dict[kid_id]["error_cnt"] = 082                self._kids_dict[kid_id]["error_cnt"] = 0
74                continue83                continue
7584
76            if kid[1]["present"] is not None:85            if kid[1]["present"] is not None:
77                kid_instance = get_instance_by_id(kid_id)86                kid_instance = get_instance_by_id(kid_id)
78                kid_instance(kid[1]["present"])87                kid_instance(kid[1]["present"])
79                continue88                continue
8089
81            count_sort_arr = {}90            count_sort_arr = {}
82            for present in self:91            for present in self:
83                if present is not None:92                if present is not None:
84                    if present is not count_sort_arr:93                    if present is not count_sort_arr:
85                        count_sort_arr[present] = 094                        count_sort_arr[present] = 0
86                    else:95                    else:
87                        count_sort_arr[present] += 196                        count_sort_arr[present] += 1
88            most_frequent = max(count_sort_arr, key=count_sort_arr.get)97            most_frequent = max(count_sort_arr, key=count_sort_arr.get)
89            kid_instance = get_instance_by_id(kid_id)98            kid_instance = get_instance_by_id(kid_id)
90            kid_instance(most_frequent)99            kid_instance(most_frequent)
91100
92            self._kids_dict[kid_id]["age"] += 1101            self._kids_dict[kid_id]["age"] += 1
93102
94        for kid in self._kids_dict.items():103        for kid in self._kids_dict.items():
95            kid_id = kid[0]104            kid_id = kid[0]
96            self._kids_dict[kid_id]["present"] = None105            self._kids_dict[kid_id]["present"] = None
97106
n98 n
99def get_instance_by_id(obj_id):107def get_instance_by_id(obj_id):
100    for obj in gc.get_objects():108    for obj in gc.get_objects():
101        if id(obj) == obj_id:109        if id(obj) == obj_id:
102            return obj110            return obj
103    return None111    return None
104112
105113
106class Kid(type):114class Kid(type):
107    def __call__(cls, *args, **kwargs):115    def __call__(cls, *args, **kwargs):
108        instance = super().__call__(*args, **kwargs)116        instance = super().__call__(*args, **kwargs)
109        Santa.add_kid(instance)117        Santa.add_kid(instance)
110        return instance118        return instance
111119
112    def __new__(cls, name, bases, dct):120    def __new__(cls, name, bases, dct):
nn121 
122        if "__call__" not in dct:
123            raise NotImplementedError
124 
113        for attr_name, attr_value in dct.items():125        for attr_name, attr_value in dct.items():
114            if (126            if (
115                callable(attr_value)127                callable(attr_value)
116                and not attr_name.startswith("__")128                and not attr_name.startswith("__")
117                and not attr_name.startswith("_")129                and not attr_name.startswith("_")
118            ):130            ):
119131
120                def wrapper(self, *args, **kwargs):132                def wrapper(self, *args, **kwargs):
121                    try:133                    try:
122                        return attr_value(self, *args, **kwargs)134                        return attr_value(self, *args, **kwargs)
123                    except Exception as e:135                    except Exception as e:
124                        Santa.add_error(self, e)136                        Santa.add_error(self, e)
125                        raise e137                        raise e
126138
127                dct[attr_name] = wrapper139                dct[attr_name] = wrapper
128        return super().__new__(cls, name, bases, dct)140        return super().__new__(cls, name, bases, dct)
t129 t
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op