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

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

8 точки общо

16 успешни теста
4 неуспешни теста
Код

  1import re
  2
  3
  4class Kid(type):
  5    def __new__(cls, name, bases, attr_dict):
  6        if "__call__" not in attr_dict:
  7            raise NotImplementedError("not implemented")
  8        # test for raising errors
  9        for name, value in attr_dict.items():
 10            if callable(value) and name[0] != "_":
 11                attr_dict[name] = Kid._has_been_naughty(value)
 12        return type.__new__(cls, name, bases, attr_dict)
 13    
 14    def __call__(cls, *args, **kwargs):
 15        # add every existing kid to Santa's list
 16        instance = super().__call__(*args, **kwargs)
 17        Santa.add_kid(instance)
 18        return instance
 19    
 20    @staticmethod
 21    def _has_been_naughty(public_method):
 22        def wrapper(self, *args, **kwargs):
 23            try:
 24                public_method(self, *args, **kwargs)
 25            except Exception as exc:
 26                Santa.set_naughty(self)
 27                raise exc
 28        return wrapper
 29
 30
 31class Santa:
 32    _instance = None
 33    naughty_or_nice_list ={}
 34    # a dict where the kid is the key and the value is a dict with the info ab the kid
 35    most_wanted = {}
 36    lost_the_magic = False
 37
 38    def __new__(cls):
 39        if cls._instance is None:
 40            cls._instance = super().__new__(cls)
 41        return cls._instance
 42    
 43    @classmethod
 44    def add_kid(cls, kid):
 45        cls.naughty_or_nice_list[kid] = {"wish": None, "age": 0, "naughty": False}
 46
 47    @classmethod
 48    def set_naughty(cls, kid):
 49        cls.naughty_or_nice_list[kid]["naughty"] = True
 50    
 51    def _extract_wish(self, message):
 52        return re.search(r"['\"]([a-zA-Z0-9\s]+)['\"]", message).group(1)
 53    
 54    def _extract_kID(self, message):
 55        return re.search(r"^\s*(\d+)\s*$", message, re.MULTILINE).group(1)
 56    
 57    def __set_wish(self, kid, wish):
 58        if kid in self.naughty_or_nice_list:
 59            self.naughty_or_nice_list[kid]["wish"] = wish
 60        else:
 61            raise ValueError("Unexisting kid is trying to contact Santa")
 62
 63    def __call__(self, kid, message):
 64        wish = self._extract_wish(message)
 65        self.__set_wish(kid, wish)
 66        self.most_wanted[wish] = self.most_wanted.get(wish, 0) + 1
 67        self.lost_the_magic = False
 68
 69
 70    def __matmul__(self, message):
 71        wish = self._extract_wish(message)
 72        kID = self._extract_kID(message)
 73        for current_kid in self.naughty_or_nice_list:
 74            if int(id(current_kid)) == int(kID):
 75                self.__set_wish(current_kid, wish)
 76                break
 77        self.most_wanted[wish] = self.most_wanted.get(wish, 0) + 1
 78        self.lost_the_magic = False
 79
 80    def __iter__(self):
 81        for kid, info in self.naughty_or_nice_list.items():
 82            if info["wish"]:
 83                yield info["wish"]
 84    
 85    def __get_most_wanted(self):
 86        most_wished = None
 87        most_rep = 0
 88        for wish, rep in self.most_wanted.items():
 89            if rep > most_rep:
 90                most_wished = wish
 91                most_rep = rep
 92        return most_wished
 93    
 94    def __null_all_wishes(self):
 95        for kid in self.naughty_or_nice_list:
 96            self.naughty_or_nice_list[kid]["wish"] = None
 97
 98    def xmas(self):
 99        if self.lost_the_magic:
100            print("No magic")
101            return
102        for kid, info in self.naughty_or_nice_list.items():
103            if info["age"] > 5:
104                continue
105            info["age"] += 1
106            if info["naughty"]:
107                kid("coal")
108                continue
109            gift = info["wish"] if info["wish"] else self.__get_most_wanted()
110            kid(gift)
111        self.lost_the_magic = True
112        self.__null_all_wishes()

.......F.......F.FF
Stdout:
No magic
No magic
No magic
No magic
.
======================================================================
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']

======================================================================
FAIL: 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)
AssertionError: 'coal' != None

======================================================================
FAIL: 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)
AssertionError: None != 42

======================================================================
FAIL: 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)
AssertionError: 'toy' != None

Stdout:
No magic
No magic
No magic
No magic

----------------------------------------------------------------------
Ran 20 tests in 0.077s

FAILED (failures=4)

Дискусия
Виктор Бечев
20.12.2024 11:26

Беше ми любопитно дали има разлика - минава ти един тест повече. Да знаеш, просто. :smile:
Габриела Николова
19.12.2024 20:22

``` #final revised version with corrections import re class Kid(type): def __new__(cls, name, bases, attr_dict): if "__call__" not in attr_dict: raise NotImplementedError("not implemented") # test for raising errors for name, value in attr_dict.items(): if callable(value) and name[0] != "_": attr_dict[name] = Kid._has_been_naughty(value) return type.__new__(cls, name, bases, attr_dict) def __call__(cls, *args, **kwargs): # add every existing kid to Santa's list instance = super().__call__(*args, **kwargs) Santa.add_kid(instance) return instance @staticmethod def _has_been_naughty(public_method): def wrapper(self, *args, **kwargs): try: public_method(self, *args, **kwargs) except Exception as exc: Santa.set_naughty(self) raise exc return wrapper class Santa: _instance = None naughty_or_nice_list ={} # a dict where the kid is the key and the value is a dict with the info ab the kid most_wanted = {} lost_the_magic = False def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance @classmethod def add_kid(cls, kid): cls.naughty_or_nice_list[kid] = {"wish": None, "age": 1, "naughty": False} @classmethod def set_naughty(cls, kid): cls.naughty_or_nice_list[kid]["naughty"] = True def _extract_wish(self, message): return re.search(r"['\"]([a-zA-Z0-9\s]+)['\"]", message).group(1) def _extract_kID(self, message): return re.search(r"^\s*(\d+)\s*$", message, re.MULTILINE).group(1) def __set_wish(self, kid, wish): if kid in self.naughty_or_nice_list: self.naughty_or_nice_list[kid]["wish"] = wish else: raise ValueError("Unexisting kid is trying to contact Santa") def __call__(self, kid, message): wish = self._extract_wish(message) self.__set_wish(kid, wish) self.most_wanted[wish] = self.most_wanted.get(wish, 0) + 1 self.lost_the_magic = False def __matmul__(self, message): wish = self._extract_wish(message) kID = self._extract_kID(message) for current_kid in self.naughty_or_nice_list: if int(id(current_kid)) == int(kID): self.__set_wish(current_kid, wish) break self.most_wanted[wish] = self.most_wanted.get(wish, 0) + 1 self.lost_the_magic = False def __iter__(self): for kid, info in self.naughty_or_nice_list.items(): if info["wish"]: yield info["wish"] def __get_most_wanted(self): most_wished = None most_rep = 0 for wish, rep in self.most_wanted.items(): if rep > most_rep: most_wished = wish most_rep = rep return most_wished def __null_all_wishes(self): for kid in self.naughty_or_nice_list: self.__set_wish(kid, None) for wish in self.most_wanted: self.most_wanted[wish] = 0 def xmas(self): if self.lost_the_magic: print("lost the magic") pass else: for kid, info in self.naughty_or_nice_list.items(): if info["age"] > 5: continue if info["naughty"]: kid("coal") info["naughty"] = False # null it for next year continue gift = info["wish"] if info["wish"] else self.__get_most_wanted() kid(gift) self.lost_the_magic = True self.__null_all_wishes() for info in self.naughty_or_nice_list.values(): info["age"] += 1 ``` PS много се извинявам за закъснението, пращам го само за да си го имам
Габриела Николова
19.12.2024 15:00

Да, опитвах се да оправя проблемите, ще пусна тестовете му
Виктор Бечев
19.12.2024 13:52

Добре, не бях сигурен дали ще предаваш нова версия или не, затова до момента нищо не съм ти казал по темата. Имаш два проблема, заради които ти гърмят повечето тестове. Препоръчвам ти да пуснеш [тестовете на колегата Павел](https://py-fmi.org/homework/6#comment83) за да си видиш грешките, да не отива на вятъра това, което си свършила. П.П. Липсва му `unittest.main()` отдолу.
Виктор Бечев
16.12.2024 01:14

Ммммм, добър въпрос, печелиш точка за него. За в бъдеще е хубаво да ги задаваш публично, за да са полезни и за колегите ти. Приемаме, че не могат да се създават деца преди първия Дядо Коледа. Как така той не е бил дете като малък - никой не знае. Имаше една сладка книга на Тери Пратчет - Дядо Прас, която имаше интересно тълкувание за измислените ни entity-та, но пак не обяснява как така. Ама за нашето домашно е така. **Едит:** Това важи за **инстанции** на класовете, които използват `Kid` за метаклас! Не важи за самите класове. Т.е. е напълно валидно да имаме следното: ``` class SomeKidClass(metaclass=Kid): pass santa = Santa() goshko = SomeKidClass() ``` Инстанциите - само след наличието на Дядо Коледа, но класовете - могат и преди това.
Габриела Николова
16.12.2024 01:07

Исках само да питам дали може да се създава дете преди да се създаде първият santa? Ако да, значи децата трябва да се пазят в Kid, но пък тогава няма само Santa да знае кой какво иска и кой е бил послушен
История

f1import ref1import re
nn2 
23
3class Kid(type):4class Kid(type):
4    def __new__(cls, name, bases, attr_dict):5    def __new__(cls, name, bases, attr_dict):
nn6        if "__call__" not in attr_dict:
7            raise NotImplementedError("not implemented")
8        # test for raising errors
9        for name, value in attr_dict.items():
10            if callable(value) and name[0] != "_":
11                attr_dict[name] = Kid._has_been_naughty(value)
5        return type.__new__(cls, name, bases, attr_dict)12        return type.__new__(cls, name, bases, attr_dict)
nn13    
14    def __call__(cls, *args, **kwargs):
15        # add every existing kid to Santa's list
16        instance = super().__call__(*args, **kwargs)
17        Santa.add_kid(instance)
18        return instance
19    
20    @staticmethod
21    def _has_been_naughty(public_method):
22        def wrapper(self, *args, **kwargs):
23            try:
24                public_method(self, *args, **kwargs)
25            except Exception as exc:
26                Santa.set_naughty(self)
27                raise exc
28        return wrapper
29 
630
7class Santa:31class Santa:
8    _instance = None32    _instance = None
nn33    naughty_or_nice_list ={}
9    naughty_or_nice_list ={"most_wanted":{}} # a dict where the kid is the key and the value is a dict with the info ab the kid34    a dict where the kid is the key and the value is a dict with the info ab the kid
10    # a genius ORIGINAL idea !35    most_wanted = {}
11    # ------------------------36    lost_the_magic = False
37 
12    def __new__(cls):38    def __new__(cls):
13        if cls._instance is None:39        if cls._instance is None:
14            cls._instance = super().__new__(cls)40            cls._instance = super().__new__(cls)
15        return cls._instance41        return cls._instance
16    42    
nn43    @classmethod
44    def add_kid(cls, kid):
45        cls.naughty_or_nice_list[kid] = {"wish": None, "age": 0, "naughty": False}
46 
47    @classmethod
48    def set_naughty(cls, kid):
49        cls.naughty_or_nice_list[kid]["naughty"] = True
50    
17    def _extract_wish(self, message):51    def _extract_wish(self, message):
18        return re.search(r"['\"]([a-zA-Z0-9\s]+)['\"]", message).group(1)52        return re.search(r"['\"]([a-zA-Z0-9\s]+)['\"]", message).group(1)
19    53    
n20    def _extract_kid(self, message):n54    def _extract_kID(self, message):
21        return re.search(r"^\s*(\d+)\s*$", message, re.MULTILINE).group(1)55        return re.search(r"^\s*(\d+)\s*$", message, re.MULTILINE).group(1)
22    56    
n23    def __call__(self, kid, message):n57    def __set_wish(self, kid, wish):
24        # ako veche e zvynqlo Promenqme jelanieto i ako e nad 5 go ignorirame
25        wish = self._extract_wish(message)
26        if kid in self.naughty_or_nice_list.keys():58        if kid in self.naughty_or_nice_list:
27            self.naughty_or_nice_list[kid]["wish"] = wish59            self.naughty_or_nice_list[kid]["wish"] = wish
28        else:60        else:
n29            self.naughty_or_nice_list[kid] = {"wish": wish, "age": 0, "naughty": False}n61            raise ValueError("Unexisting kid is trying to contact Santa")
30        # posle proverqvame dali jelanieto e v spisyka most_wanted62 
31        if wish in self.naughty_or_nice_list["most_wanted"].keys():63    def __call__(self, kid, message):
32            self.naughty_or_nice_list["most_wanted"][wish] += 164        wish = self._extract_wish(message)
33        else:65        self.__set_wish(kid, wish)
34            self.naughty_or_nice_list["most_wanted"][wish] = 166        self.most_wanted[wish] = self.most_wanted.get(wish, 0) + 1
67        self.lost_the_magic = False
68 
3569
36    def __matmul__(self, message):70    def __matmul__(self, message):
n37        # ako veche e zvynqlo same as above -> moje da se iznese vyv functionn
38        wish = self._extract_wish(message)71        wish = self._extract_wish(message)
n39        kid = self._extract_kid(message)n72        kID = self._extract_kID(message)
40        if kid in self.naughty_or_nice_list.keys():73        for current_kid in self.naughty_or_nice_list:
41            self.naughty_or_nice_list[kid]["wish"] = wish74            if int(id(current_kid)) == int(kID):
42        else:75                self.__set_wish(current_kid, wish)
43            self.naughty_or_nice_list[kid] = {"wish": wish, "age": 0, "naughty": False}76                break
44 77        self.most_wanted[wish] = self.most_wanted.get(wish, 0) + 1
45        if wish in self.naughty_or_nice_list["most_wanted"].keys():78        self.lost_the_magic = False
46            self.naughty_or_nice_list["most_wanted"][wish] += 1
47        else:
48            self.naughty_or_nice_list["most_wanted"][wish] = 1
49        # tova moje da se izkara vyv vynshna function
5079
51    def __iter__(self):80    def __iter__(self):
n52        return iter(self.wishes.values())n81        for kid, info in self.naughty_or_nice_list.items():
82            if info["wish"]:
83                yield info["wish"]
84    
85    def __get_most_wanted(self):
86        most_wished = None
87        most_rep = 0
88        for wish, rep in self.most_wanted.items():
89            if rep > most_rep:
90                most_wished = wish
91                most_rep = rep
92        return most_wished
93    
94    def __null_all_wishes(self):
95        for kid in self.naughty_or_nice_list:
96            self.naughty_or_nice_list[kid]["wish"] = None
5397
54    def xmas(self):98    def xmas(self):
nn99        if self.lost_the_magic:
100            print("No magic")
101            return
55        for kid, info in self.naughty_or_nice_list.items():102        for kid, info in self.naughty_or_nice_list.items():
56            if info["age"] > 5:103            if info["age"] > 5:
n57                pass # santa go e otsviriln104                continue
105            info["age"] += 1
58            if info["naughty"]:106            if info["naughty"]:
t59                return kid("coal") # TRQBVA DA VRUSHTA KONKRETNO DETEt107                kid("coal")
60            info["age"] += 1108                continue
61 109            gift = info["wish"] if info["wish"] else self.__get_most_wanted()
62 110            kid(gift)
63 111        self.lost_the_magic = True
64# -----------------------------------------------------------------------------------------------------------------112        self.__null_all_wishes()
65# -----------------------------------------------------------------------------------------------------------------
66# -------------------------------------------- Testing ------------------------------------------------------------
67# -----------------------------------------------------------------------------------------------------------------
68# -----------------------------------------------------------------------------------------------------------------
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op