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

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

8 точки общо

15 успешни теста
5 неуспешни теста
Код

  1import re
  2import random
  3
  4
  5class Kid(type):
  6    """Represents a dynamic metaclass for kid with instance tracking."""
  7
  8    _all_instances = {}
  9
 10    def __new__(cls, name, bases, dict):
 11        """Create a new class type."""
 12        if '__call__' not in dict:
 13            raise NotImplementedError(f'Class {name} should implement __call__!')
 14
 15        dict['instances'] = {}
 16        return type.__new__(cls, name, bases, dict)
 17
 18    def __call__(cls, *args, **kwargs):
 19        """Create an instances and tracking them by their ID."""
 20        instance = super(Kid, cls).__call__(*args, **kwargs)
 21        instance_id = id(instance)
 22        instance.years = 0
 23        instance.id = instance_id
 24        instance.is_naughty = False
 25
 26        for attr_name in dir(instance):
 27            if not attr_name.startswith('_'):  # Public methods
 28                attr = getattr(instance, attr_name)
 29                if callable(attr):
 30                    wrapped_method = Kid._wrap_method(attr, instance)
 31                    setattr(instance, attr_name, wrapped_method)
 32
 33        cls.instances[instance_id] = instance
 34        Kid._all_instances[instance_id] = instance
 35        return instance
 36
 37    @staticmethod
 38    def _wrap_method(method, instance):
 39        """Wrap a method to catch exceptions and mark the instance as naughty."""
 40        def wrapped(*args, **kwargs):
 41            try:
 42                return method(*args, **kwargs)
 43            except:
 44                instance.is_naughty = True
 45                raise
 46
 47        return wrapped
 48
 49    @classmethod
 50    def kids_grow(cls):
 51        """All kids grow with one passed year."""
 52        for kid_id, kid in Kid._all_instances.items():
 53            kid.years += 1
 54
 55    @classmethod
 56    def gift_presents(cls, kids_requests, most_wanted):
 57        """Gift presents to all kids."""
 58        for kid_id, kid in Kid._all_instances.items():
 59
 60            if kid.is_naughty:
 61                kid('coal')
 62                kid.is_naughty = False
 63                continue
 64            if kid.years > 5:
 65                Kid._all_instances.pop(kid_id)
 66                continue
 67
 68            if kid_id in kids_requests:
 69                kid(kids_requests[kid_id])
 70            else:
 71                kid(most_wanted)
 72
 73
 74class Santa(object):
 75    """Represents an abstract Santa class."""
 76
 77    def __new__(cls):
 78        """Create a new singleton instance of Santa."""
 79        if not hasattr(cls, '_instance'):
 80            cls._instance = super(Santa, cls).__new__(cls)
 81
 82            cls._instance.kids_requests = {}
 83            cls._instance.wishlist = {}
 84
 85        return cls._instance
 86
 87    def __call__(self, kid, wish):
 88        """Kid calls for a Christmas present wish."""
 89        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', wish)
 90        if match:
 91            gift = match.group(1)
 92            self.kids_requests[id(kid)] = gift
 93            self._add_gift_to_wishlist(gift)
 94
 95    def __matmul__(self, letter):
 96        """Kid writes a letter with a Christmas present wish."""
 97        # id_match = re.search(r'^\s*\d+\s*$', letter)
 98        id_match = re.search(r'\s*(\d+)\s*', letter)
 99        gift_match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', letter)
100
101        if gift_match and id_match:
102            gift = gift_match.group(1)
103            kid_id = int(id_match.group(0))
104
105            self.kids_requests[kid_id] = gift
106            self._add_gift_to_wishlist(gift)
107
108    def __iter__(self):
109        """Iterate over requests of kids."""
110        return iter(self.kids_requests.values())
111
112    def xmas(self):
113        """Take presents to the kids method."""
114        if self.kids_requests and self.wishlist:
115            # max_key = max(self.wishlist, key=self.wishlist.get)
116            max_key = Santa._get_most_wanted_present(self.wishlist)
117            Kid.gift_presents(self.kids_requests, max_key)
118            self.kids_requests.clear()
119            self.wishlist.clear()
120
121        Kid.kids_grow()
122
123    def _add_gift_to_wishlist(self, gift):
124        """Help method for adding to Santa's wishes."""
125        if gift not in self.wishlist:
126            self.wishlist[gift] = 1
127        else:
128            self.wishlist[gift] += 1
129
130    @staticmethod
131    def _get_most_wanted_present(wishlist):
132        """Get random present wish of most wanted present."""
133        max_value = max(wishlist.values())
134        max_keys = [key for key, value in wishlist.items() if value == max_value]
135        random_max_key = random.choice(max_keys)  # Chooses random from list with the same value
136
137        return random_max_key

...F....F.F.F.....F.
======================================================================
FAIL: test_call_and_mail_same_kid (test.TestSanta.test_call_and_mail_same_kid)
Test that calls and mails work for the same kid.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 71, in test_call_and_mail_same_kid
self.assertEqual(list(self.santa), ['toy1'])
AssertionError: Lists differ: ['toy1', 'toy1'] != ['toy1']

First list contains 1 additional elements.
First extra element 1:
'toy1'

- ['toy1', 'toy1']
+ ['toy1']

======================================================================
FAIL: test_signature_matching (test.TestSanta.test_signature_matching)
Test matching present in the letter / call.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 119, in test_signature_matching
self.assertEqual(kid2.SECRET_PRESENT, 'toy2')
AssertionError: 'toy1' != 'toy2'
- toy1
? ^
+ toy2
? ^

======================================================================
FAIL: test_xmass (test.TestSanta.test_xmass)
Test a simple Christmas case.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 143, in test_xmass
self.assertEqual(kid3.SECRET_PRESENT, 'toy3')
AssertionError: 'toy2' != 'toy3'
- toy2
? ^
+ toy3
? ^

======================================================================
FAIL: test_xmass_kid_without_a_wish (test.TestSanta.test_xmass_kid_without_a_wish)
Test a Christmas with a kids that hasn't sent a wish.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 177, in test_xmass_kid_without_a_wish
self.assertEqual(kid3.SECRET_PRESENT, 'toy2')
AssertionError: 'toy1' != 'toy2'
- toy1
? ^
+ toy2
? ^

======================================================================
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

----------------------------------------------------------------------
Ran 20 tests in 0.048s

FAILED (failures=5)

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

f1import ref1import re
2import random2import random
33
44
5class Kid(type):5class Kid(type):
6    """Represents a dynamic metaclass for kid with instance tracking."""6    """Represents a dynamic metaclass for kid with instance tracking."""
77
8    _all_instances = {}8    _all_instances = {}
99
10    def __new__(cls, name, bases, dict):10    def __new__(cls, name, bases, dict):
11        """Create a new class type."""11        """Create a new class type."""
12        if '__call__' not in dict:12        if '__call__' not in dict:
13            raise NotImplementedError(f'Class {name} should implement __call__!')13            raise NotImplementedError(f'Class {name} should implement __call__!')
1414
15        dict['instances'] = {}15        dict['instances'] = {}
n16        return super(Kid, cls).__new__(cls, name, bases, dict)n16        return type.__new__(cls, name, bases, dict)
1717
18    def __call__(cls, *args, **kwargs):18    def __call__(cls, *args, **kwargs):
19        """Create an instances and tracking them by their ID."""19        """Create an instances and tracking them by their ID."""
20        instance = super(Kid, cls).__call__(*args, **kwargs)20        instance = super(Kid, cls).__call__(*args, **kwargs)
21        instance_id = id(instance)21        instance_id = id(instance)
22        instance.years = 022        instance.years = 0
23        instance.id = instance_id23        instance.id = instance_id
24        instance.is_naughty = False24        instance.is_naughty = False
2525
26        for attr_name in dir(instance):26        for attr_name in dir(instance):
27            if not attr_name.startswith('_'):  # Public methods27            if not attr_name.startswith('_'):  # Public methods
28                attr = getattr(instance, attr_name)28                attr = getattr(instance, attr_name)
29                if callable(attr):29                if callable(attr):
30                    wrapped_method = Kid._wrap_method(attr, instance)30                    wrapped_method = Kid._wrap_method(attr, instance)
31                    setattr(instance, attr_name, wrapped_method)31                    setattr(instance, attr_name, wrapped_method)
3232
33        cls.instances[instance_id] = instance33        cls.instances[instance_id] = instance
34        Kid._all_instances[instance_id] = instance34        Kid._all_instances[instance_id] = instance
35        return instance35        return instance
3636
37    @staticmethod37    @staticmethod
38    def _wrap_method(method, instance):38    def _wrap_method(method, instance):
39        """Wrap a method to catch exceptions and mark the instance as naughty."""39        """Wrap a method to catch exceptions and mark the instance as naughty."""
40        def wrapped(*args, **kwargs):40        def wrapped(*args, **kwargs):
41            try:41            try:
42                return method(*args, **kwargs)42                return method(*args, **kwargs)
n43            except Exception:n43            except:
44                instance.is_naughty = True44                instance.is_naughty = True
45                raise45                raise
4646
47        return wrapped47        return wrapped
4848
49    @classmethod49    @classmethod
50    def kids_grow(cls):50    def kids_grow(cls):
51        """All kids grow with one passed year."""51        """All kids grow with one passed year."""
52        for kid_id, kid in Kid._all_instances.items():52        for kid_id, kid in Kid._all_instances.items():
53            kid.years += 153            kid.years += 1
5454
55    @classmethod55    @classmethod
56    def gift_presents(cls, kids_requests, most_wanted):56    def gift_presents(cls, kids_requests, most_wanted):
57        """Gift presents to all kids."""57        """Gift presents to all kids."""
58        for kid_id, kid in Kid._all_instances.items():58        for kid_id, kid in Kid._all_instances.items():
5959
60            if kid.is_naughty:60            if kid.is_naughty:
61                kid('coal')61                kid('coal')
62                kid.is_naughty = False62                kid.is_naughty = False
63                continue63                continue
64            if kid.years > 5:64            if kid.years > 5:
65                Kid._all_instances.pop(kid_id)65                Kid._all_instances.pop(kid_id)
66                continue66                continue
6767
68            if kid_id in kids_requests:68            if kid_id in kids_requests:
69                kid(kids_requests[kid_id])69                kid(kids_requests[kid_id])
70            else:70            else:
71                kid(most_wanted)71                kid(most_wanted)
n72 n
73            kid.years += 1
7472
7573
76class Santa(object):74class Santa(object):
77    """Represents an abstract Santa class."""75    """Represents an abstract Santa class."""
7876
79    def __new__(cls):77    def __new__(cls):
80        """Create a new singleton instance of Santa."""78        """Create a new singleton instance of Santa."""
81        if not hasattr(cls, '_instance'):79        if not hasattr(cls, '_instance'):
82            cls._instance = super(Santa, cls).__new__(cls)80            cls._instance = super(Santa, cls).__new__(cls)
8381
84            cls._instance.kids_requests = {}82            cls._instance.kids_requests = {}
85            cls._instance.wishlist = {}83            cls._instance.wishlist = {}
8684
87        return cls._instance85        return cls._instance
8886
89    def __call__(self, kid, wish):87    def __call__(self, kid, wish):
90        """Kid calls for a Christmas present wish."""88        """Kid calls for a Christmas present wish."""
91        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', wish)89        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', wish)
92        if match:90        if match:
93            gift = match.group(1)91            gift = match.group(1)
94            self.kids_requests[id(kid)] = gift92            self.kids_requests[id(kid)] = gift
95            self._add_gift_to_wishlist(gift)93            self._add_gift_to_wishlist(gift)
9694
97    def __matmul__(self, letter):95    def __matmul__(self, letter):
98        """Kid writes a letter with a Christmas present wish."""96        """Kid writes a letter with a Christmas present wish."""
99        # id_match = re.search(r'^\s*\d+\s*$', letter)97        # id_match = re.search(r'^\s*\d+\s*$', letter)
100        id_match = re.search(r'\s*(\d+)\s*', letter)98        id_match = re.search(r'\s*(\d+)\s*', letter)
101        gift_match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', letter)99        gift_match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', letter)
102100
103        if gift_match and id_match:101        if gift_match and id_match:
104            gift = gift_match.group(1)102            gift = gift_match.group(1)
105            kid_id = int(id_match.group(0))103            kid_id = int(id_match.group(0))
106104
107            self.kids_requests[kid_id] = gift105            self.kids_requests[kid_id] = gift
108            self._add_gift_to_wishlist(gift)106            self._add_gift_to_wishlist(gift)
n109        else:n
110            Kid.kids_grow()
111107
112    def __iter__(self):108    def __iter__(self):
113        """Iterate over requests of kids."""109        """Iterate over requests of kids."""
114        return iter(self.kids_requests.values())110        return iter(self.kids_requests.values())
115111
116    def xmas(self):112    def xmas(self):
117        """Take presents to the kids method."""113        """Take presents to the kids method."""
118        if self.kids_requests and self.wishlist:114        if self.kids_requests and self.wishlist:
119            # max_key = max(self.wishlist, key=self.wishlist.get)115            # max_key = max(self.wishlist, key=self.wishlist.get)
n120            max_key = self._get_most_wanted_present(self.wishlist)n116            max_key = Santa._get_most_wanted_present(self.wishlist)
121            Kid.gift_presents(self.kids_requests, max_key)117            Kid.gift_presents(self.kids_requests, max_key)
122            self.kids_requests.clear()118            self.kids_requests.clear()
123            self.wishlist.clear()119            self.wishlist.clear()
n124        else:n120 
125            Kid.kids_grow()121        Kid.kids_grow()
126122
127    def _add_gift_to_wishlist(self, gift):123    def _add_gift_to_wishlist(self, gift):
128        """Help method for adding to Santa's wishes."""124        """Help method for adding to Santa's wishes."""
129        if gift not in self.wishlist:125        if gift not in self.wishlist:
130            self.wishlist[gift] = 1126            self.wishlist[gift] = 1
131        else:127        else:
132            self.wishlist[gift] += 1128            self.wishlist[gift] += 1
133129
tt130    @staticmethod
134    def _get_most_wanted_present(self, wishlist):131    def _get_most_wanted_present(wishlist):
135        """Get random present wish of most wanted present."""132        """Get random present wish of most wanted present."""
136        max_value = max(wishlist.values())133        max_value = max(wishlist.values())
137        max_keys = [key for key, value in wishlist.items() if value == max_value]134        max_keys = [key for key, value in wishlist.items() if value == max_value]
138        random_max_key = random.choice(max_keys)  # Chooses random from list with the same value135        random_max_key = random.choice(max_keys)  # Chooses random from list with the same value
139136
140        return random_max_key137        return random_max_key
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op