Домашни > The Old Man from Scene #24 > Решения > Решението на Георги Иванов

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

4 точки общо

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

 1import re
 2
 3DUMMY_VALUES = {
 4    'int': 0,
 5    'float': 0.0,
 6    'str': '',
 7    'bool': False,
 8    'list': [],
 9    'tuple': (),
10    'set': set(),
11    'dict': {},
12}
13
14def _dummy_for_type(type_str):
15    base = type_str.strip().split('|')[0].strip().split('[')[0].strip()
16    return DUMMY_VALUES.get(base, 0)
17
18def _parse_docstring_params(obj):
19    doc = getattr(obj, '__doc__', None)
20    if not doc:
21        return []
22
23    match = re.search(r'Parameters\s*\n\s*-+\s*\n([\s\S]*?)(\n\s*\n|$)', doc)
24    if not match:
25        return []
26
27    args = []
28    for line in match.group(1).splitlines():
29        line = line.strip()
30        if re.match(r'\w+\s*:', line):
31            type_str = line.split(':', 1)[1].strip()
32            args.append(_dummy_for_type(type_str))
33    return args
34
35def _check_name(obj):
36    name = getattr(obj, '__name__', None)
37    return name is not None and name[0].isupper()
38
39def _check_quest(obj):
40    if not callable(obj):
41        return False
42    args = _parse_docstring_params(obj)
43    try:
44        obj(*args)
45        return True
46    except Exception:
47        return False
48
49def _check_attribute(obj):
50    for attr in dir(obj):
51        last = None
52        for sym in reversed(attr):
53            if sym != '_' and not sym.isdigit():
54                last = sym
55                break
56        if last is None or not last.isupper():
57            continue
58
59        max_run = run = 0
60        for sym in attr.lower():
61            if sym in 'aeiou':
62                run += 1
63                max_run = max(max_run, run)
64            else:
65                run = 0
66        if max_run > 3:
67            continue
68
69        return True
70    return False
71
72
73def _passes_all(obj):
74    return _check_name(obj) and _check_quest(obj) and _check_attribute(obj)
75
76class _FilteredModule:
77    def __init__(self, module):
78        self.__dict__['_module'] = module
79
80    def __getattr__(self, name):
81        obj = getattr(self.__dict__['_module'], name)
82        if not _passes_all(obj):
83            raise AttributeError(f"Wrong, '{name}'! You have failed to answer correctly - prepare to be cast into the Gorge of Eternal Peril!")
84        return obj
85
86class BridgeKeeper:
87    def __init__(self, module):
88        self._module = module
89
90    def __enter__(self):
91        return _FilteredModule(__import__(self._module))
92
93    def __exit__(self, exc_type, exc_val, exc_tb):
94        return False

............F.F..F...F.FF
======================================================================
FAIL: test_rejects_callable_when_parameter_names_do_not_match (test.TestBridgeKeeper.test_rejects_callable_when_parameter_names_do_not_match)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 59, in test_rejects_callable_when_parameter_names_do_not_match
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised

======================================================================
FAIL: test_rejects_dict_when_callable_does_not_work_with_documented_key_and_value_types (test.TestBridgeKeeper.test_rejects_dict_when_callable_does_not_work_with_documented_key_and_value_types)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 90, in test_rejects_dict_when_callable_does_not_work_with_documented_key_and_value_types
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised

======================================================================
FAIL: test_rejects_list_when_callable_does_not_work_with_documented_element_type (test.TestBridgeKeeper.test_rejects_list_when_callable_does_not_work_with_documented_element_type)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 102, in test_rejects_list_when_callable_does_not_work_with_documented_element_type
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised

======================================================================
FAIL: test_rejects_set_when_callable_does_not_work_with_documented_element_type (test.TestBridgeKeeper.test_rejects_set_when_callable_does_not_work_with_documented_element_type)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 112, in test_rejects_set_when_callable_does_not_work_with_documented_element_type
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised

======================================================================
FAIL: test_rejects_tuple_when_callable_does_not_work_with_documented_element_type (test.TestBridgeKeeper.test_rejects_tuple_when_callable_does_not_work_with_documented_element_type)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 107, in test_rejects_tuple_when_callable_does_not_work_with_documented_element_type
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised

======================================================================
FAIL: test_rejects_union_when_callable_does_not_support_all_union_branches (test.TestBridgeKeeper.test_rejects_union_when_callable_does_not_support_all_union_branches)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 72, in test_rejects_union_when_callable_does_not_support_all_union_branches
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised

----------------------------------------------------------------------
Ran 25 tests in 0.003s

FAILED (failures=6)

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