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

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

10 точки общо

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

  1import re
  2
  3class Santa:
  4    instance = None
  5    MAX_KID_AGE = 5
  6    COAL_PRESENT = 'coal'
  7
  8    def xmas(self):

Бих извадил някои парчета от този метод. Станал е прекалено дълъг.

9 for child in self.children.keys(): 10 self.children[child] += 1 11 12 if not self.presents: 13 return 14 15 present_counts = dict() 16 given_presents = set() 17 for present in self.presents: 18 if self.children[present[0]] > Santa.MAX_KID_AGE: 19 continue 20 given_presents.add(present[0]) 21 if present[0] in self.blacklist: 22 self.kids_by_id[present[0]](self.COAL_PRESENT) 23 continue 24 self.kids_by_id[present[0]](present[1]) 25 present_counts[present[1]] = present_counts.get(present[1], 0) + 1 26 27 most_wanted_present = (None, 0) 28 for name, count in present_counts.items(): 29 if most_wanted_present[1] < count: 30 most_wanted_present = (name, count) 31 32 must_be_good_present = most_wanted_present[0] 33 34 for kid, age in self.children.items(): 35 if age > Santa.MAX_KID_AGE or kid in given_presents: 36 continue 37 if kid in self.blacklist: 38 self.kids_by_id[kid](self.COAL_PRESENT) 39 else: 40 self.kids_by_id[kid](must_be_good_present) 41 42 self.presents = [] 43 self.blacklist = set() 44 45 def __new__(cls, *args, **kwargs): 46 if cls.instance is None: 47 cls.instance = super().__new__(cls, *args, **kwargs) 48 return cls.instance 49 50 def __init__(self): 51 self.presents = [] 52 self.blacklist = set() 53 self.children = dict()

Препоръчва се за инициализация на речник да се ползва {}. Конвенция.

54 self.kids_by_id = dict() 55 self._iter_index = 0 56 57 def __call__(self, kid, wish): 58 kid_id = id(kid) 59 for i, present in enumerate(self.presents): 60 if present[0] == kid_id: 61 self.presents[i] = (kid_id, Santa.get_present_wish(wish))

Не е много удобно да работиш с лист от тюпъли. Един подреден речник би бил по-добро решение.

62 break 63 else: 64 self.presents.append((kid_id, Santa.get_present_wish(wish))) 65 66 def __matmul__(self, letter): 67 kid_id = Santa.get_kid_id(letter) 68 kid_wish = Santa.get_present_wish(letter) 69 for i, present in enumerate(self.presents): 70 if present[0] == kid_id: 71 self.presents[i] = (kid_id, kid_wish) 72 break 73 else: 74 self.presents.append((kid_id, kid_wish)) 75 76 def __iter__(self): 77 self._iter_index = 0 78 return self 79 80 def __next__(self): 81 if self._iter_index >= len(self.presents): 82 self._iter_index = 0 83 raise StopIteration 84 self._iter_index += 1 85 return self.presents[self._iter_index - 1][1] 86 87 @staticmethod 88 def get_present_wish(wish): 89 kid_present_r = r"(\"|\')([a-zA-Z0-9]+[a-zA-Z0-9\s]*)\1" 90 return re.search(kid_present_r, wish).group(2) 91 92 @staticmethod 93 def get_kid_id(letter):

Можеш да използваш re.MULTILINE

94 kid_id_r = r"^\s*\d+\s*$" 95 kid_id = None 96 for line in letter.splitlines(): 97 if re.match(kid_id_r, line): 98 kid_id = int(line.strip()) 99 break 100 return kid_id 101

Оставяй по два празни реда между дефинициите си на top level.

102class Kid(type): 103 104 def __new__(cls, name, bases, attr_dict): 105 if '__call__' not in attr_dict: 106 raise NotImplementedError('No __call__') 107 108 for attr, value in attr_dict.items(): 109 if not attr.startswith('_') and hasattr(value, '__call__'): 110 attr_dict[attr] = Kid.bad_kid_checker(value) 111 112 new_class = super().__new__(cls, name, bases, attr_dict) 113 old_new = new_class.__new__ 114 115 def new_new(cls, *args, **kwargs): 116 instance = old_new(cls, *args, **kwargs) 117 Santa.instance.children[id(instance)] = 0 118 Santa.instance.kids_by_id[id(instance)] = instance 119 return instance 120 121 new_class.__new__ = new_new 122 123 return new_class 124 125 @staticmethod 126 def bad_kid_checker(func): 127 def wrapper(self, *args, **kwargs): 128 try: 129 return func(self, *args, **kwargs) 130 except: 131 Santa.instance.blacklist.add(id(self)) 132 raise 133 return wrapper

.............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 229, in test_xmass_naughty
self.assertEqual(kid3.SECRET_PRESENT, 'sirenie')
AssertionError: None != 'sirenie'

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

FAILED (failures=1)

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