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

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

10 точки общо

19 успешни теста
1 неуспешни теста
Код

  1import re
  2from collections import defaultdict
  3from random import choice
  4
  5
  6class Singleton(type):
  7    class_instances = {}
  8
  9    def __call__(cls, *args, **kwargs):
 10        if cls not in cls.class_instances:
 11            cls.class_instances[cls] = super().__call__(*args, **kwargs)
 12        return cls.class_instances[cls]
 13
 14
 15class Santa(metaclass=Singleton):
 16    def __init__(self):
 17        self.gifts = {}
 18        self.count_of_xmases = defaultdict(int)
 19        self.gifts_count = defaultdict(int)
 20        self.naughty_kids = set()
 21
 22    def __call__(self, kid_instance, message):
 23        wish = self.__extract_wish(message)
 24        self.gifts[kid_instance] = wish
 25        self.gifts_count[wish] += 1
 26
 27    def __matmul__(self, letter):
 28        wish = self.__extract_wish(letter)
 29        kid_id = int(self.__extract_signature(letter))
 30        kid = Kid.created_kids.get(kid_id)
 31        self.gifts[kid] = wish
 32        self.gifts_count[wish] += 1
 33
 34    def __iter__(self):
 35        for gift in self.gifts.values():
 36            yield gift
 37
 38    def choose_random_default_gift(self):
 39        curr_gift_count = 0
 40        most_wished_gifts = []
 41        for gift, count in self.gifts_count.items():
 42            if count > curr_gift_count:
 43                curr_gift_count = count
 44                most_wished_gifts = [gift]
 45            elif count == curr_gift_count:
 46                most_wished_gifts.append(gift)
 47        return most_wished_gifts
 48    
 49    def reset_christmas(self):
 50         # Reset gifts values for the new Christmas + incrementing the xmas count by 1
 51            for kid in self.gifts.keys():
 52                self.gifts[kid] = ""
 53                self.count_of_xmases[kid] += 1
 54                
 55    def xmas(self):
 56        if all(count == 0 for count in self.gifts_count.values()):
 57            self.reset_christmas()
 58            return
 59        
 60        most_wished_gifts = self.choose_random_default_gift()
 61        default_gift = choice(most_wished_gifts) if most_wished_gifts else None
 62        
 63        for kid, gift in self.gifts.items():
 64            if self.count_of_xmases[kid] >= 5:
 65                continue
 66
 67            if kid in self.naughty_kids:
 68                kid("coal")
 69            else:
 70                if gift == "":
 71                    final_gift = default_gift
 72                else:
 73                    final_gift = gift
 74                    
 75                if final_gift:
 76                    kid(final_gift)
 77
 78        self.reset_christmas()
 79        self.naughty_kids.clear()
 80        self.gifts_count = defaultdict(int)
 81
 82    @staticmethod
 83    def __extract_wish(message):
 84        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', message)
 85        return match.group(1)
 86
 87    @staticmethod
 88    def __extract_signature(message):
 89        match = re.search(r'^\s*(\d+)\s*$', message, re.MULTILINE)
 90        return match.group(1)
 91
 92
 93class Kid(type):
 94    created_kids = {}
 95    
 96    @classmethod
 97    def is_naughty(cls, method):
 98        def wrapper(self, *args, **kwargs):
 99            try:
100                return method(self, *args, **kwargs)
101            except Exception:
102                Santa().naughty_kids.add(self)
103                raise
104        return wrapper
105
106    def __new__(cls, name, bases, dct):
107        if '__call__' not in dct:
108            raise NotImplementedError(
109                f"Tova meta dete/klas {name} neshto ne moje da se vika!")
110
111        for attr_name, attr_value in dct.items():
112            if callable(attr_value) and not attr_name.startswith("_"):
113                dct[attr_name] = cls.is_naughty(attr_value)
114        return super().__new__(cls, name, bases, dct)
115
116    def __call__(cls, *args, **kwargs):
117        instance = super().__call__(*args, **kwargs)
118        # Saving the (id -> kid) pair of each created kid for an easier access later in __matmul__
119        Kid.created_kids[id(instance)] = instance
120
121        # Set default value to each created kid
122        santa = Santa()
123        if instance not in santa.gifts:
124            santa.gifts[instance] = ""
125        return instance

.......F............
======================================================================
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.030s

FAILED (failures=1)

Дискусия
Виктор Бечев
16.12.2024 00:24

Да, Дядо Коледа дава нов шанс на всички всяка Коледа.
Василена Станойска
15.12.2024 21:33

Може ли да попитам само, когато едно дете е било непослушно например първата година, то следващата вече си е послушно и може да получава подарък различен от "coal", нали?
История

f1import ref1import re
nn2from collections import defaultdict
2from random import choice3from random import choice
n3from collections import defaultdictn
44
55
6class Singleton(type):6class Singleton(type):
7    class_instances = {}7    class_instances = {}
88
9    def __call__(cls, *args, **kwargs):9    def __call__(cls, *args, **kwargs):
10        if cls not in cls.class_instances:10        if cls not in cls.class_instances:
11            cls.class_instances[cls] = super().__call__(*args, **kwargs)11            cls.class_instances[cls] = super().__call__(*args, **kwargs)
12        return cls.class_instances[cls]12        return cls.class_instances[cls]
1313
1414
15class Santa(metaclass=Singleton):15class Santa(metaclass=Singleton):
16    def __init__(self):16    def __init__(self):
17        self.gifts = {}17        self.gifts = {}
18        self.count_of_xmases = defaultdict(int)18        self.count_of_xmases = defaultdict(int)
19        self.gifts_count = defaultdict(int)19        self.gifts_count = defaultdict(int)
20        self.naughty_kids = set()20        self.naughty_kids = set()
2121
22    def __call__(self, kid_instance, message):22    def __call__(self, kid_instance, message):
n23        wish = self.__extract_wish__(message)n23        wish = self.__extract_wish(message)
24        self.gifts[kid_instance] = wish24        self.gifts[kid_instance] = wish
25        self.gifts_count[wish] += 125        self.gifts_count[wish] += 1
2626
27    def __matmul__(self, letter):27    def __matmul__(self, letter):
n28        wish = self.__extract_wish__(letter)n28        wish = self.__extract_wish(letter)
29        kid_id = int(self.__extract_signature__(letter))29        kid_id = int(self.__extract_signature(letter))
30        kid = Kid.created_kids.get(kid_id)30        kid = Kid.created_kids.get(kid_id)
31        self.gifts[kid] = wish31        self.gifts[kid] = wish
32        self.gifts_count[wish] += 132        self.gifts_count[wish] += 1
3333
34    def __iter__(self):34    def __iter__(self):
35        for gift in self.gifts.values():35        for gift in self.gifts.values():
36            yield gift36            yield gift
3737
n38    def xmas(self):n38    def choose_random_default_gift(self):
39        if all(count == 0 for count in self.gifts_count.values()):
40            # Reset gifts values for the new Christmas + incrementing the xmas count by 1
41            for kid in self.gifts.keys():
42                self.gifts[kid] = ""
43                self.count_of_xmases[kid] += 1
44            return
45 
46        curr_gift_count = 039        curr_gift_count = 0
47        most_wished_gifts = []40        most_wished_gifts = []
48        for gift, count in self.gifts_count.items():41        for gift, count in self.gifts_count.items():
49            if count > curr_gift_count:42            if count > curr_gift_count:
50                curr_gift_count = count43                curr_gift_count = count
51                most_wished_gifts = [gift]44                most_wished_gifts = [gift]
52            elif count == curr_gift_count:45            elif count == curr_gift_count:
53                most_wished_gifts.append(gift)46                most_wished_gifts.append(gift)
n54 n47        return most_wished_gifts
48    
49    def reset_christmas(self):
50         # Reset gifts values for the new Christmas + incrementing the xmas count by 1
51            for kid in self.gifts.keys():
52                self.gifts[kid] = ""
53                self.count_of_xmases[kid] += 1
54                
55    def xmas(self):
56        if all(count == 0 for count in self.gifts_count.values()):
57            self.reset_christmas()
58            return
59        
60        most_wished_gifts = self.choose_random_default_gift()
55        default_gift = choice(most_wished_gifts) if most_wished_gifts else None61        default_gift = choice(most_wished_gifts) if most_wished_gifts else None
nn62        
56        for kid in list(self.gifts.keys()):63        for kid, gift in self.gifts.items():
57            if self.count_of_xmases[kid] >= 5:64            if self.count_of_xmases[kid] >= 5:
58                continue65                continue
5966
60            if kid in self.naughty_kids:67            if kid in self.naughty_kids:
61                kid("coal")68                kid("coal")
62            else:69            else:
n63                if self.gifts[kid] == "":n70                if gift == "":
64                    final_gift = default_gift71                    final_gift = default_gift
65                else:72                else:
n66                    final_gift = self.gifts[kid]n73                    final_gift = gift
67                    74                    
68                if final_gift:75                if final_gift:
69                    kid(final_gift)76                    kid(final_gift)
7077
n71        # Reset gifts values for the new Christmas + incrementing the xmas count by 1n78        self.reset_christmas()
72        for kid in self.gifts.keys():79        self.naughty_kids.clear()
73            self.gifts[kid] = ""
74            self.count_of_xmases[kid] += 1
75        self.gifts_count = defaultdict(int)80        self.gifts_count = defaultdict(int)
7681
77    @staticmethod82    @staticmethod
n78    def __extract_wish__(message):n83    def __extract_wish(message):
79        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', message)84        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', message)
80        return match.group(1)85        return match.group(1)
8186
82    @staticmethod87    @staticmethod
n83    def __extract_signature__(message):n88    def __extract_signature(message):
84        match = re.search(r'^\s*(\d+)\s*$', message, re.MULTILINE)89        match = re.search(r'^\s*(\d+)\s*$', message, re.MULTILINE)
85        return match.group(1)90        return match.group(1)
8691
8792
88class Kid(type):93class Kid(type):
89    created_kids = {}94    created_kids = {}
90    95    
n91    @staticmethodn96    @classmethod
92    def is_naughty(method):97    def is_naughty(cls, method):
93        def wrapper(self, *args, **kwargs):98        def wrapper(self, *args, **kwargs):
94            try:99            try:
95                return method(self, *args, **kwargs)100                return method(self, *args, **kwargs)
96            except Exception:101            except Exception:
97                Santa().naughty_kids.add(self)102                Santa().naughty_kids.add(self)
98                raise103                raise
99        return wrapper104        return wrapper
100105
101    def __new__(cls, name, bases, dct):106    def __new__(cls, name, bases, dct):
102        if '__call__' not in dct:107        if '__call__' not in dct:
103            raise NotImplementedError(108            raise NotImplementedError(
104                f"Tova meta dete/klas {name} neshto ne moje da se vika!")109                f"Tova meta dete/klas {name} neshto ne moje da se vika!")
105110
106        for attr_name, attr_value in dct.items():111        for attr_name, attr_value in dct.items():
107            if callable(attr_value) and not attr_name.startswith("_"):112            if callable(attr_value) and not attr_name.startswith("_"):
t108                dct[attr_name] = Kid.is_naughty(attr_value)t113                dct[attr_name] = cls.is_naughty(attr_value)
109        return super().__new__(cls, name, bases, dct)114        return super().__new__(cls, name, bases, dct)
110115
111    def __call__(cls, *args, **kwargs):116    def __call__(cls, *args, **kwargs):
112        instance = super().__call__(*args, **kwargs)117        instance = super().__call__(*args, **kwargs)
113        # Saving the (id -> kid) pair of each created kid for an easier access later in __matmul__118        # Saving the (id -> kid) pair of each created kid for an easier access later in __matmul__
114        Kid.created_kids[id(instance)] = instance119        Kid.created_kids[id(instance)] = instance
115120
116        # Set default value to each created kid121        # Set default value to each created kid
117        santa = Santa()122        santa = Santa()
118        if instance not in santa.gifts:123        if instance not in santa.gifts:
119            santa.gifts[instance] = ""124            santa.gifts[instance] = ""
120        return instance125        return instance
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op