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

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

8 точки общо

16 успешни теста
4 неуспешни теста
Код (Засега толкова)
Скрий всички коментари

  1import re
  2import random
  3# Начална форма на домашното, не е готово, едно от нещата не знам баш как да го направя, ако се сетя ще го добавя
  4# качвам това евентуално ако го прегледате до към 12ч на четвъртък, да дадете някаква обратна връзка
  5id_to_kid = {} # ще пазя id на дете като ключ и инстанцията като стойност, за да не се налага иначе да правя некви кастове и такива c++ неща
  6DEFAULT_PRESENT = "coal"
  7
  8def default_init_method(self, *args, **kwargs): # За да стане трика с id_to_kid dict-a, ще ми трябва по някъв начин от обектите от новосъздадените класове да го пълня
  9    id_to_kid[id(self)] = self
 10
 11class Kid(type):
 12    
 13    def __new__(cls, name, bases, dictionary_of_attributes):
 14        if "__call__" not in dictionary_of_attributes:
 15            raise NotImplementedError("леко баце")
 16        dictionary_of_attributes["__init__"] = default_init_method
 17        # добавяме една променлива age, да ни казва на колко години е детето
 18        dictionary_of_attributes["age"] = 0
 19        return super().__new__(cls, name, bases, dictionary_of_attributes)
 20
 21    
 22
 23class Santa:
 24    _instance = None
 25    # причината да има както list_of_presents, така и wishlist, ще разберете отдолу при iter()
 26    _list_of_presents = []
 27    _wishlist = {}
 28
 29    def __new__(cls):
 30        # Ако това е първото извикване на new, създаваме обекта и го пращаме в _instance
 31        # При второ и всяко следващо, директно връщаме вeче създадения обект, за да постигнем singleton
 32        if cls._instance is None:
 33           cls._instance = super(Santa, cls).__new__(cls)
 34        return cls._instance
 35    
 36    def _find_index_in_list(self, present):
 37        for i in range(len(Santa._list_of_presents)):
 38            if Santa._list_of_presents[i] == present:
 39                return i
 40
 41    def __call__(self, kid, wish):
 42        # regex (smile face)
 43        try:
 44            wanted_present = re.search(r"\'[a-zA-Z0-9\s]*\'|\"[a-zA-Z0-9\s]*\"", wish).group()
 45            # слагаме го без кавичките, затова ще го slice-ваме
 46            wanted_present = wanted_present[1:len(wanted_present)-1]
 47            if id(kid) in Santa._wishlist:
 48                # по въпроса на колегата дали редът се променя ако Дете1 иска чорап, Дете2 - раница, и след това Дете1 - игра
 49                # ако детето вече е искало нещо, то новото не трябва да го бутаме отзад, ами трябва да го сложим на правилното място
 50                index = self._find_index_in_list(Santa._wishlist[id(kid)])
 51                Santa._list_of_presents[index] = wanted_present
 52            else:
 53                Santa._list_of_presents.append(wanted_present)
 54            # id на дете -> подарък, който иска
 55            Santa._wishlist[id(kid)] = wanted_present
 56        except:
 57            # Ако Писмото е невалидно
 58            pass
 59    
 60    # operator @ ?!?!?! 
 61    def __matmul__(self, letter):
 62        # regex (smile face)
 63        try:
 64            wanted_present = re.search(r"\'[a-zA-Z0-9\s]*\'|\"[a-zA-Z0-9\s]*\"", letter).group()
 65            kid_sign = re.search(r"(\n)\s*\d+\s*", letter).group()
 66            # Ще хване и whitespace, затова трябва да ги махнем
 67            kid_sign = int(kid_sign.strip())
 68            # слагаме го без кавичките, затова ще го slice-ваме
 69            wanted_present = wanted_present[1:len(wanted_present)-1]
 70            if kid_sign in Santa._wishlist:
 71                # подобни обяснения като отгоре
 72                index = self._find_index_in_list(Santa._wishlist[kid_sign])
 73                Santa._list_of_presents[index] = wanted_present
 74            else:
 75                Santa._list_of_presents.append(wanted_present)
 76            # id на дете -> подарък, който иска
 77            Santa._wishlist[kid_sign] = wanted_present
 78        except:
 79            # Ако Писмото е невалидно
 80            pass
 81
 82    def __iter__(self):
 83        # има отделно list_of_presents и wishlist, въпреки че съхраняват еднакви неща (почти)
 84        # причината е, че редът на листа е гарантиран, докато за dict-a не съм сигурен дали е рандом, или сортиран, или каквото и да е
 85        # зависи от имплементацията на dict отдолу, затова list-a е по-сигурния за мен вариант
 86        return iter(Santa._list_of_presents)
 87    
 88    def _find_most_popular_present(self):
 89        if len(Santa._list_of_presents) == 0:
 90            return None
 91        dict_of_present = {}
 92        for item in Santa._list_of_presents:
 93            if item not in dict_of_present:
 94                dict_of_present[item] = 1
 95            else:
 96                dict_of_present[item] += 1
 97        # предполагам, че очаквате да използвам random, щом в условието пише ,,На случаен принцип''
 98        # затова и трябва малко setup за random-a
 99        # или иначе казано търся си оправдание да напиша най-лошото търсене в историята
100        max_app = 0
101        for app in dict_of_present.values():
102            if app > max_app:
103                max_app = app
104        list_of_popular_presents = []
105        for item in dict_of_present.keys():
106            if dict_of_present[item] == max_app:
107                list_of_popular_presents.append(item)
108        random_position = random.randint(0, len(list_of_popular_presents) - 1)
109        return list_of_popular_presents[random_position]
110 
111    def xmas(self):
112        for kid_id in id_to_kid.keys():
113            if id_to_kid[kid_id].age >= 5: # по скоро е броя на изминалите коледи, а не е възраст
114                continue
115            else:
116                # не знам как да направя проверка дали дете е хвърлило exception :(
117                if kid_id in Santa._wishlist:
118                    id_to_kid[kid_id].__call__(Santa._wishlist[kid_id])
119                else:
120                    most_popular_present = self._find_most_popular_present()
121                    if most_popular_present is not None:
122                        id_to_kid[kid_id].__call__(most_popular_present)
123            id_to_kid[kid_id].age += 1
124        Santa._list_of_presents = []
125        Santa._wishlist = {}

.............FEE..E.
======================================================================
ERROR: test_xmass_no_wishes (test.TestSanta.test_xmass_no_wishes)
Test a Christmas with no wishes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 151, in test_xmass_no_wishes
self.assertEqual(kid1.SECRET_PRESENT, None)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'KidClass1' object has no attribute 'SECRET_PRESENT'

======================================================================
ERROR: test_xmass_no_wishes_but_naughty_kids (test.TestSanta.test_xmass_no_wishes_but_naughty_kids)
Test a Christmas with no wishes, but naughty kids present.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 163, in test_xmass_no_wishes_but_naughty_kids
self.assertEqual(kid1.SECRET_PRESENT, None)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'KidClass1' object has no attribute 'SECRET_PRESENT'

======================================================================
ERROR: test_xmass_years_5_and_over (test.TestSanta.test_xmass_years_5_and_over)
Test with passing years with kid aged 5 and over.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 213, in test_xmass_years_5_and_over
self.assertEqual(kid1.SECRET_PRESENT, None)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'KidClass1' object has no attribute 'SECRET_PRESENT'

======================================================================
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 227, in test_xmass_naughty
self.assertEqual(kid1.SECRET_PRESENT, 'coal')
AssertionError: 'sirenie' != 'coal'
- sirenie
+ coal

----------------------------------------------------------------------
Ran 20 tests in 0.026s

FAILED (failures=1, errors=3)

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