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

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

7 точки общо

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

  1import re
  2
  3def matcher(regex, string):
  4    """Convert regex match into string."""
  5    match = re.search(regex, string)
  6    if match is None:
  7        return string
  8    start, end = match.span()
  9    return string[start:end]
 10
 11
 12class Kid(type):
 13    """Kid metaclass"""
 14
 15    def __new__(cls, name, bases, attr_dict):
 16        if '__call__' not in attr_dict.keys():
 17            raise NotImplementedError
 18        attr_dict['years_celebrated'] = 0
 19        attr_dict['__init__'] = lambda self: kids.append(self)
 20        return type.__new__(cls, name, bases, attr_dict)
 21
 22
 23class Singleton(type):
 24    """A metaclass that makes classes singletons."""
 25    created_instances = {}
 26    def __call__(cls, *args, **kwargs):
 27        if cls not in cls.created_instances:
 28            cls.created_instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
 29        return cls.created_instances[cls]
 30
 31
 32class PresentIterator:
 33    def __init__(self, presents):
 34        self.presents = presents
 35        self.index = 0
 36
 37    def __next__(self):
 38        self.index += 1
 39        try:
 40            return self.presents[self.index - 1]
 41        except IndexError as exc:
 42            self.index = 0
 43            raise StopIteration from exc
 44
 45
 46kids = [] # global list containing objects with Kid metaclass
 47
 48class Santa(metaclass=Singleton):
 49    """Festive singleton class that gives presents (or not)."""
 50    kid_presents = {} # each kid has a list of presents
 51    
 52    def __call__(self, kid, letter):
 53        # regex to read the wish from the letter
 54        wish = matcher(r'[\'\"](([a-z])*([A-z])*(\d)*( )*)*[\'\"]', letter)
 55        wish = wish[1:-1] # trim the quotation marks
 56        if id(kid) in self.kid_presents:
 57            self.kid_presents[id(kid)].append(wish)
 58        else:
 59            self.kid_presents[id(kid)] = [wish]
 60
 61    def __matmul__(self, letter):
 62        kid_id = matcher(r'(\n)(\s)*(\d)+(\s)*', letter) # with whitespace characters
 63        kid_id = int(matcher(r'\d+', kid_id)) # digits only here
 64        wish = matcher(r'[\'\"](([a-z])*([A-z])*(\d)*( )*)*[\'\"]', letter)
 65        wish = wish[1:-1] # trim the quotation marks
 66
 67        if kid_id in self.kid_presents:
 68            self.kid_presents[kid_id].append(wish)
 69        else:
 70            self.kid_presents[kid_id] = [wish]
 71    
 72    def get_presents_list(self):
 73        extracted_presents = []
 74        for present_list in self.kid_presents.values():
 75            extracted_presents.extend(present_list)
 76        return extracted_presents
 77
 78    def __iter__(self):
 79        presents = self.get_presents_list()
 80        return PresentIterator(presents)
 81    
 82    def xmas(self):
 83        if not any(self.kid_presents.values()):
 84            for kid in kids:
 85                kid.years_celebrated += 1
 86            return
 87        
 88        presents_count = {}
 89        presents = self.get_presents_list()
 90    
 91        for present in presents:
 92            if present in presents_count:
 93                presents_count[present] += 1
 94            else:
 95                presents_count[present] = 1
 96        
 97        most_wanted_present = str(max(zip(presents_count.values(), presents_count.keys()))[1])
 98        
 99        kids_copy = kids[:]
100        for kid in kids_copy:
101            if id(kid) not in self.kid_presents:
102                self.kid_presents[id(kid)] = [most_wanted_present]
103            if len(self.kid_presents[id(kid)]) == 0:
104                self.kid_presents[id(kid)].append(most_wanted_present)
105                
106            kid.years_celebrated += 1
107            if kid.years_celebrated > 5:
108                kids.remove(kid)
109                self.kid_presents.pop(id(kid))
110                continue
111
112            # give present to a kid
113            size = len(self.kid_presents[id(kid)])
114            kid(self.kid_presents[id(kid)][size - 1]) # gets the last present from the kid's list
115            self.kid_presents[id(kid)].remove(self.kid_presents[id(kid)][size - 1])

...FF..F.....FEE..E.
======================================================================
ERROR: test_xmass_no_wishes (test.TestSanta.test_xmass_no_wishes)
Test a Christmas with no wishes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 151, in test_xmass_no_wishes
self.assertEqual(kid1.SECRET_PRESENT, None)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'KidClass1' object has no attribute 'SECRET_PRESENT'

======================================================================
ERROR: 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)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'KidClass1' object has no attribute 'SECRET_PRESENT'

======================================================================
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 213, in test_xmass_years_5_and_over
self.assertEqual(kid1.SECRET_PRESENT, None)
^^^^^^^^^^^^^^^^^^^
AttributeError: 'KidClass1' object has no attribute 'SECRET_PRESENT'

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

First differing element 0:
'toy2'
'toy2v2'

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

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

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

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

----------------------------------------------------------------------
Ran 20 tests in 0.040s

FAILED (failures=4, errors=3)

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