Домашни > The Old Man from Scene #24 > Решения > Решението на Ариф Мехмедали

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

5 точки общо

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

 1import re
 2from itertools import product
 3
 4def dummy_var(attr_type: str):
 5    if attr_type == "int":
 6        return 1
 7    if attr_type == "float":
 8        return 1.
 9    if attr_type == "str":
10        return "1"
11    if attr_type == "bool":
12        return True
13    if attr_type.startswith("list"):
14        return [dummy_var(attr_type[5:-1])]
15    if attr_type.startswith("set"):
16        return {dummy_var(attr_type[4:-1])}
17    if attr_type.startswith("dict"):
18        t1, t2 = attr_type[5:-1].split(",")
19        return {dummy_var(t1.strip()) : dummy_var(t2.strip())}
20    if attr_type.startswith("tuple"):
21        return (dummy_var(attr_type[6:-1]), dummy_var(attr_type[6:-1]))
22    
23
24class FilteredModule:
25    def __init__(self, module):
26        self._module = module
27
28    def __getattr__(self, name):
29        attr = getattr(self._module, name)
30
31        attr_name = getattr(attr, "__name__", None)
32        if not attr_name or not attr_name[0].isupper():
33            raise AttributeError
34        
35        if not callable(attr):
36            raise AttributeError
37        
38        docstr = attr.__doc__ if attr.__doc__ else ""
39        matched = re.search(r"Parameters\n----------(.*?)(?:$|\n\n)", docstr, re.DOTALL)
40        params = matched.group(1) if matched else ""
41        param_types = re.findall(r"^[^:]+\s*:\s*([^\n]+)",params, re.MULTILINE)
42        param_types_combinations = [c for c in product(*[[x.strip() for x in t.split("|")] for t in param_types])]
43        param_values = [tuple(dummy_var(t) for t in combo) for combo in param_types_combinations]
44        
45        for args in param_values:
46            try:
47                attr(*args)
48            except Exception:
49                raise AttributeError
50            
51        for attr_name in dir(attr):
52
53            if attr_name.startswith("__") and attr_name.endswith("__"):
54                continue
55
56            if re.search(r"[aeiou]{4,}", attr_name.lower()):
57                continue
58
59            last_letter = re.search(r"[a-zA-Z][^a-zA-Z]*$", attr_name)
60            if not last_letter or not last_letter.group()[0].isupper():
61                continue
62
63            return attr
64
65        raise AttributeError
66
67    
68class BridgeKeeper:
69    def __init__(self, module_name):
70        self._module_name = module_name
71
72    def __enter__(self):
73        self._module = __import__(self._module_name)
74        return FilteredModule(self._module)
75
76    def __exit__(self, ex_type, exc, tb):
77        pass

............F............
======================================================================
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

----------------------------------------------------------------------
Ran 25 tests in 0.002s

FAILED (failures=1)

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

Отвъд дребните забележки и един изпуснат интервал - добре написано решение.
История
Това решение има само една версия.