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

Резултати
3 точки от тестове
-4 точки от учител

-1 точки общо

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

  1import re
  2import inspect
  3from collections import Counter
  4import random
  5
  6
  7class Santa:
  8    _instance = None
  9
 10    def __new__(cls, *args, **kwargs):
 11        if cls._instance is None:
 12            cls._instance = super(Santa, cls).__new__(cls)
 13            cls._instance.child_ages = {}
 14            cls._instance.current_wishes = {}
 15        return cls._instance
 16
 17    def __call__(self, child, message):
 18        if not isinstance(child, KidBase):
 19            raise TypeError("Expected an instance of a Kid.")
 20        if not isinstance(message, str):
 21            raise TypeError("Message must be a string.")
 22        
 23        gift = self.extract_gift(message)
 24        if gift:
 25            self.current_wishes[child] = gift
 26            print(f"Phone call from {child.__class__.__name__} (ID: {id(child)}): wants '{gift}'")
 27        else:
 28            print("Invalid message: No valid gift found.")
 29
 30    def __matmul__(self, letter):
 31        if not isinstance(letter, str):
 32            raise TypeError("Letter must be a string.")
 33        
 34        gift = self.extract_gift(letter)
 35        child_id = self.extract_signature(letter)
 36        
 37        if gift and child_id:
 38            child = self.find_child_by_id(child_id)
 39            if child:
 40                self.current_wishes[child] = gift
 41                print(f"Received a letter from child with ID {child_id}: wants '{gift}'")
 42            else:
 43                print(f"Warning: No child found with ID {child_id}.")
 44        elif not gift:
 45            print("Invalid letter: No valid gift found.")
 46        elif not child_id:
 47            print("Invalid letter: No valid signature found.")
 48
 49    @staticmethod
 50    def extract_gift(text):
 51        match = re.search(r'["\']([a-zA-Z0-9 ]+)["\']', text)
 52        return match.group(1) if match else None
 53
 54    @staticmethod
 55    def extract_signature(text):
 56        match = re.search(r'^\s*(\d+)\s*$', text, re.MULTILINE)
 57        return int(match.group(1)) if match else None
 58
 59    def find_child_by_id(self, child_id):
 60        for child in KidBase.all_children:
 61            if id(child) == child_id:
 62                return child
 63        return None
 64
 65    def xmas(self):
 66        if not self.current_wishes:
 67            print("No wishes this year. Santa is taking a break.")
 68            return
 69
 70        wish_counter = Counter(self.current_wishes.values())
 71        most_common = wish_counter.most_common(1)
 72        most_desired_gift = most_common[0][0] if most_common else None
 73
 74        for child in KidBase.all_children:
 75            if child not in self.child_ages:
 76                self.child_ages[child] = 0
 77            if self.child_ages[child] >= 5:
 78                print(f"{child.__class__.__name__} is too old for gifts!")
 79                continue
 80            self.child_ages[child] += 1
 81
 82            gift = self.current_wishes.get(child, most_desired_gift)
 83
 84            if not child.is_nice():
 85                gift = "coal"
 86
 87            child(gift)
 88
 89        self.current_wishes.clear()
 90
 91
 92class Kid(type):
 93    def __new__(cls, name, bases, dct):
 94        # Проверяваме дали "__call__" съществува в текущия клас или базовите му класове
 95        if not any("__call__" in dir(base) for base in bases) and "__call__" not in dct:
 96            raise NotImplementedError(
 97                f"Classes using the Kid metaclass must implement a __call__ method."
 98            )
 99        return super().__new__(cls, name, bases, dct)
100
101
102class KidBase(metaclass=Kid):
103    all_children = []
104
105    def __init__(self):
106        self._methods_called = {}
107        KidBase.all_children.append(self)
108
109    def __call__(self, gift):
110        print(f"{self.__class__.__name__} received '{gift}'")
111
112    def is_nice(self):
113        return all(errors == 0 for errors in self._methods_called.values())
114
115    def __getattribute__(self, name):
116        attr = object.__getattribute__(self, name)
117        if inspect.ismethod(attr) and not name.startswith("_"):
118            def wrapper(*args, **kwargs):
119                try:
120                    return attr(*args, **kwargs)
121                except Exception:
122                    self._methods_called[name] = self._methods_called.get(name, 0) + 1
123                    raise
124            return wrapper
125        return attr
126
127
128class BulgarianKid(KidBase):
129    def be_naughty(self):
130        raise RuntimeError("Няма да си изям зеленчуците!")
131
132
133class ChineseKid(KidBase):
134    pass

..EEEE
Stdout:
Warning: No child found with ID 133690676232160.
Warning: No child found with ID 133690676825504.
E
Stdout:
Warning: No child found with ID 133690676825456.
Warning: No child found with ID 133690676833712.
EF
Stdout:
Warning: No child found with ID 133690676838272.
Warning: No child found with ID 133690676838368.
Warning: No child found with ID 133690676824208.
No wishes this year. Santa is taking a break.
.EEEE..EEE
Stdout:
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
E
======================================================================
ERROR: test_call (test.TestSanta.test_call)
Test sending message via calling.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 54, in test_call
self.santa(kid1, "'toy1'")
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: 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 69, in test_call_and_mail_same_kid
self.santa(kid1, "'toy1'")
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: 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 126, in test_iterable
self.santa(kid1, '"something"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: test_mail (test.TestSanta.test_mail)
Test sending message via email.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 64, in test_mail
self.assertEqual(list(self.santa), ['toy1', 'toy2'])
^^^^^^^^^^^^^^^^
TypeError: 'Santa' object is not iterable

Stdout:
Warning: No child found with ID 133690676232160.
Warning: No child found with ID 133690676825504.

======================================================================
ERROR: test_present_matching (test.TestSanta.test_present_matching)
Test matching signature in the letter.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 92, in test_present_matching
self.assertEqual(list(self.santa), ['toy4', 'abcdefgHIJKLMNopQRstUVwxYZ 1 2 3 4567890 '])
^^^^^^^^^^^^^^^^
TypeError: 'Santa' object is not iterable

Stdout:
Warning: No child found with ID 133690676825456.
Warning: No child found with ID 133690676833712.

======================================================================
ERROR: 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 255, in test_santa_gift_order
self.santa(kid2, '"toy2"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: test_xmass (test.TestSanta.test_xmass)
Test a simple Christmas case.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 137, in test_xmass
self.santa(kid1, '"toy1"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: test_xmass_kid_with_multiple_wishes (test.TestSanta.test_xmass_kid_with_multiple_wishes)
Test a Christmas with a kid who sends multiple wishes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 183, in test_xmass_kid_with_multiple_wishes
self.santa(kid1, '"toy1"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: 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 171, in test_xmass_kid_without_a_wish
self.santa(kid1, '"toy1"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: test_xmass_naughty (test.TestSanta.test_xmass_naughty)
Test a Christmas with naughty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 220, in test_xmass_naughty
self.santa(kid1, "'sirenie'")
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: 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 234, in test_xmass_private_with_error
self.santa(kid1, "'sirenie'")
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
ERROR: 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 245, in test_xmass_public_with_no_error
self.santa(kid1, "'sirenie'")
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
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 211, in test_xmass_years_5_and_over
self.santa(kid1, '"toy"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

Stdout:
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.
No wishes this year. Santa is taking a break.

======================================================================
ERROR: 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 192, in test_xmass_years_under_5
self.santa(kid1, '"toy1"')
File "/tmp/solution.py", line 19, in __call__
raise TypeError("Expected an instance of a Kid.")
TypeError: Expected an instance of a Kid.

======================================================================
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 118, in test_signature_matching
self.assertEqual(kid1.SECRET_PRESENT, 'toy1')
AssertionError: None != 'toy1'

Stdout:
Warning: No child found with ID 133690676838272.
Warning: No child found with ID 133690676838368.
Warning: No child found with ID 133690676824208.
No wishes this year. Santa is taking a break.

----------------------------------------------------------------------
Ran 20 tests in 0.038s

FAILED (failures=1, errors=14)

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