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

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

9 точки общо

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

  1import re
  2import random
  3
  4
  5class Kid(type):
  6    _all_kids = {}
  7    _creation_year = {}
  8
  9    def __new__(cls, name, bases, dct):
 10        if "__call__" not in dct:
 11            raise NotImplementedError("Not implemented __call__")
 12
 13        for name, value in dct.items():
 14            if not name.startswith('__') and callable(value):
 15                dct[name] = cls.checker(value)
 16        return super().__new__(cls, name, bases, dct)
 17
 18    def checker(method):
 19        def wrapper(self, *args, **kwargs):
 20            try:
 21                return method(self, *args, **kwargs)
 22            except Exception:
 23                self._is_bad = True
 24                raise
 25        return wrapper
 26
 27    def __call__(cls, *args, **kwargs):
 28        instance = super().__call__(*args, **kwargs)
 29        instance._is_bad = False
 30
 31        cls._all_kids[id(instance)] = instance
 32        cls._creation_year[id(instance)] = Santa._curr_year
 33        return instance
 34
 35
 36class Santa:
 37    _instance = None
 38    _curr_year = 0
 39    _MAX_AGE = 5
 40
 41    def __new__(cls, *args, **kwargs):
 42        if cls._instance is None:
 43            cls._instance = super().__new__(cls)
 44            cls._instance._initialized = False
 45        return cls._instance
 46
 47    def __init__(self):
 48        if not self._initialized:
 49            self._wishes = {}
 50            self._curr_year_wishes = []
 51            self._initialized = True
 52
 53    def _extract_wish(self, text):
 54        match = re.search(r'[\'"]([A-Za-z0-9 ]+)[\'"]', text)
 55        return match.group(1) if match else None
 56
 57    def __call__(self, kid, message):
 58        wish = self._extract_wish(message)
 59        if wish:
 60            self._wishes[id(kid)] = wish
 61            self._curr_year_wishes.append(wish)
 62
 63    def __matmul__(self, other):
 64        kid_id = None
 65        lines = other.strip().split('\n')
 66        for line in lines:
 67            if re.match(r'^\s*\d+\s*$', line):
 68                kid_id = int(line.strip())
 69                break
 70
 71        if kid_id is None:
 72            return
 73
 74        kid = Kid._all_kids.get(kid_id)
 75        if kid:
 76            wish = self._extract_wish(other)
 77            if wish:
 78                self._wishes[kid_id] = wish
 79                self._curr_year_wishes.append(wish)
 80
 81    def __iter__(self):
 82        return iter(self._curr_year_wishes)
 83
 84    def xmas(self):
 85        Santa._curr_year += 1
 86
 87        if not self._curr_year_wishes:
 88            self._wishes.clear()
 89            self._curr_year_wishes.clear()
 90            return
 91
 92        wish_count = {}
 93        max_count = 0
 94
 95        for wish in self._curr_year_wishes:
 96            wish_count[wish] = wish_count.get(wish, 0) + 1
 97            max_count = max(max_count, wish_count[wish])
 98
 99        most_common = [wish for wish, count in wish_count.items() if count == max_count]
100        most_common = random.choice(most_common)
101
102        for kid in Kid._all_kids.values():
103            if Santa._curr_year - Kid._creation_year[id(kid)] >= self._MAX_AGE:
104                continue
105
106            if kid._is_bad:
107                kid('coal')
108                kid._is_bad = False
109            else:
110                gift = self._wishes.get(id(kid), most_common)
111                kid(gift)
112
113        self._wishes.clear()
114        self._curr_year_wishes.clear()

...FF..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_iterable (test.TestSanta.test_iterable)
Ensure Santa can be iterated multiple times including overwriting presents.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 129, in test_iterable
self.assertEqual(list(self.santa), ['something', 'something else'])
AssertionError: Lists differ: ['something', 'something not used', 'something else'] != ['something', 'something else']

First differing element 1:
'something not used'
'something else'

First list contains 1 additional elements.
First extra element 2:
'something else'

- ['something', 'something not used', 'something else']
+ ['something', 'something else']

======================================================================
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: ['toy2', 'toy3', 'toy1', 'toy2v2'] != ['toy2v2', 'toy3', 'toy1']

First differing element 0:
'toy2'
'toy2v2'

First list contains 1 additional elements.
First extra element 3:
'toy2v2'

- ['toy2', 'toy3', 'toy1', 'toy2v2']
+ ['toy2v2', 'toy3', 'toy1']

======================================================================
FAIL: test_xmass_private_with_error (test.TestSanta.test_xmass_private_with_error)
Test a Christmas with not-so-naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 240, in test_xmass_private_with_error
self.assertEqual(kid1.SECRET_PRESENT, 'sirenie')
AssertionError: 'coal' != 'sirenie'
- coal
+ sirenie

======================================================================
FAIL: test_xmass_years_under_5 (test.TestSanta.test_xmass_years_under_5)
Test with passing years with a kid under 5 years old.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 201, in test_xmass_years_under_5
self.assertEqual(kid1.SECRET_PRESENT, 'toy2')
AssertionError: None != 'toy2'

----------------------------------------------------------------------
Ran 20 tests in 0.061s

FAILED (failures=5)

Дискусия
Виктор Бечев
19.12.2024 17:13

Харесва ми колко различни инструмента си използвала из решението си. Също така си единствената с това решение на проблема с годините. Very nice.
История
Това решение има само една версия.