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

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

2 точки общо

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

 1import importlib
 2import re
 3
 4class BridgeKeeper:
 5    """Context manager class (to do)"""
 6    TYPE_REGEX = r"(dict\[\w+,\s*\w+\]|\w+\[\w+\]|\w+)"
 7    NAME_REGEX = rf"^\w+ : {TYPE_REGEX}( \| {TYPE_REGEX})?$"
 8
 9    def __init__(self, module_name : str):
10        self._module_name = module_name
11        self._module = importlib.import_module(module_name)
12
13    def __enter__(self):
14        return self
15
16    def __exit__(self, exc_type, exc_val, exc_tb):
17        "Tова не виждам къде мога да го ползвам"
18        pass
19
20    def __getattr__(self, obj_name : str):
21        obj = getattr(self._module, obj_name)
22        if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
23            return obj
24        raise AttributeError
25
26    def _check_name(self, obj):
27        return hasattr(obj, "__name__") and str(obj.__name__[0]).isupper()
28
29    def _check_quest(self, obj):
30        if not callable(obj):
31            return False
32        
33        doc_str = obj.__doc__
34        args = []
35        
36        if doc_str and "Parameters" in doc_str:
37            params_match = re.search(r"Parameters\n----------\n(.*?)(\n\n|$)", doc_str, re.DOTALL)
38            if params_match:
39                for row in params_match.group(1).splitlines():
40                    if re.match(self.NAME_REGEX, row):
41                        type_str = re.match(self.NAME_REGEX, row).group(2)
42                        args.append(self._generate_arg(type_str))
43
44        try:
45            obj(*args)
46            return True
47        except Exception:
48            return False
49
50    def _check_extra_requirements(self, obj):
51        for attr_name in dir(obj):
52            if attr_name.startswith('__') and attr_name.endswith('__'):
53                continue
54            letters = re.findall(r'[a-zA-Z]', attr_name)
55            if not letters:
56                continue
57            if letters[-1].isupper() and not re.search(r'[aeiouAEIOU]{4,}', attr_name):
58                return True
59        return False
60
61    def _generate_arg(self, type_str : str):
62        if type_str.startswith("dict"):
63            return {}
64        elif "[" in type_str:
65            return []
66        elif type_str == "int":
67            return 1
68        elif type_str == "float":
69            return 1.0
70        elif type_str == "str":
71            return "a"
72        elif type_str == "bool":
73            return True
74        return None
75    

EEEEEEE.E..E............F
======================================================================
ERROR: test_allows_attribute_whose_last_letter_is_uppercase_but_name_continues (test.TestBridgeKeeper.test_allows_attribute_whose_last_letter_is_uppercase_but_name_continues)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 55, in test_allows_attribute_whose_last_letter_is_uppercase_but_name_continues
self.assertEqual(filtered.trailing_marker(7), 70)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_allows_callable_instance (test.TestBridgeKeeper.test_allows_callable_instance)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 86, in test_allows_callable_instance
self.assertEqual(filtered.callable_box([1, 2, 3]), 6)
^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_allows_dict_typed_parameter (test.TestBridgeKeeper.test_allows_dict_typed_parameter)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 68, in test_allows_dict_typed_parameter
self.assertEqual(filtered.score_map({"alice": 3, "bob": 7}), 10)
^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_allows_multi_argument_union_bonus_case (test.TestBridgeKeeper.test_allows_multi_argument_union_bonus_case)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 95, in test_allows_multi_argument_union_bonus_case
self.assertEqual(filtered.triple_union_pair(3, [1, 2]), 6)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 24, in __getattr__
raise AttributeError
AttributeError

======================================================================
ERROR: test_allows_set_typed_parameter (test.TestBridgeKeeper.test_allows_set_typed_parameter)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 77, in test_allows_set_typed_parameter
self.assertEqual(filtered.gather_tags({"bridge", "keeper"}), "bridge,keeper")
^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_allows_third_answer_name_with_trailing_double_underscores_if_not_dunder (test.TestBridgeKeeper.test_allows_third_answer_name_with_trailing_double_underscores_if_not_dunder)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 64, in test_allows_third_answer_name_with_trailing_double_underscores_if_not_dunder
self.assertEqual(filtered.trailing_underscores(4), 5)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_allows_third_answer_with_single_uppercase_letter_name (test.TestBridgeKeeper.test_allows_third_answer_with_single_uppercase_letter_name)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 117, in test_allows_third_answer_with_single_uppercase_letter_name
self.assertEqual(filtered.single_letter_answer(5), 15)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_allows_valid_function (test.TestBridgeKeeper.test_allows_valid_function)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 9, in test_allows_valid_function
self.assertEqual(filtered.multiply_text(3, "na"), "nanana")
^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
ERROR: test_ignores_parameter_like_lines_outside_parameters_block (test.TestBridgeKeeper.test_ignores_parameter_like_lines_outside_parameters_block)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 37, in test_ignores_parameter_like_lines_outside_parameters_block
self.assertEqual(filtered.tricky_doc(2, "xo"), "xoxo")
^^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 22, in __getattr__
if self._check_name(obj) and self._check_quest(obj) and self._check_extra_requirements(obj):
~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 42, in _check_quest
args.append(self._generate_arg(type_str))
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 62, in _generate_arg
if type_str.startswith("dict"):
^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'

======================================================================
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.008s

FAILED (failures=1, errors=9)

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