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

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

4 точки общо

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

 1import importlib
 2import re
 3import itertools
 4
 5def check_name(name):
 6    if not name or not name[0].isupper():
 7        raise AttributeError("Name is not correct!")
 8
 9def check_attribute(attr):
10    if attr.startswith("__") and attr.endswith("__"):
11        return False
12    if re.search(r'[aeouiAEOUI]{4}', attr):
13        return False
14    
15    letters = [char for char in attr if char.isalpha()]
16    if letters and letters[-1].isupper():
17        return True
18    
19    
20def make_args(obj):
21    doc = getattr(obj, "__doc__", "") or ""
22    args = []
23   
24
25    match = re.search(r'Parameters\s*\n\s*-+\s*\n(.*?)(?:\n[ \t]*\n|$)', doc, re.DOTALL)
26    if match:
27        for line in match.group(1).splitlines():
28            if ":" in line:
29                type_part = line.split(":", 1)[1].strip()
30                types = []
31                for t_str in type_part.split('|'):
32                    t_str = t_str.strip()
33                    val = 1
34                
35                    if "str" in t_str: val = 'a'
36                    elif "int" in t_str: val = 1
37                    elif "float" in t_str: val = 1.0
38                    elif "bool" in t_str: val = True
39
40                    if t_str.startswith("list"): val = [val]
41                    elif t_str.startswith('tuple'): val = (val,)
42                    elif t_str.startswith('set'): val = {val}
43                    elif t_str.startswith('dict'): val = {'a': 1}
44
45                    types.append(val)
46                args.append(types)
47    return itertools.product(*args)
48
49def check_object(obj):
50    if not callable(obj):
51        return False
52    
53    combinations = make_args(obj)
54
55    for arg in combinations:
56        try:
57            obj(*arg)
58        except Exception:
59            raise AttributeError("Object is not correct!")
60
61class BridgeKeeper:
62    def __init__(self, module_name):
63        self.module = importlib.import_module(module_name)
64   
65    def __enter__(self):
66        class ModuleProxy:
67            def __getattr__(_, name):
68                try:
69                    obj = getattr(self.module, name)
70                except AttributeError:
71                    raise AttributeError(f"Module has no attribute '{name}'")
72                
73                check_name(getattr(obj, '__name__', ''))
74       
75                check_object(obj)
76     
77                if not any(check_attribute(attr) for attr in dir(obj)):
78                    raise AttributeError("No secret attribute found!")
79                    
80                return obj
81                
82        return ModuleProxy()
83    
84    def __exit__(self, exc_type, exc_val, exc_tb):
85        pass

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

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

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

FAILED (failures=2)

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

Отвъд горното - кодът изглежда добре. Прост е, използвани са правилните питонски механизми. Може би пропускам някакви дреболии, защото нещо ме човърка като го гледам, но нищо, което да се набива на очи.
История
Това решение има само една версия.