Домашни > The Old Man from Scene #24 > Решения > Решението на Милица Лазарова

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

4 точки общо

25 успешни теста
0 неуспешни теста
Код

  1import re
  2import inspect
  3
  4class BridgeKeeper:
  5    def __init__(self, module_name):
  6        self.module_name = module_name
  7
  8    def __enter__(self):
  9        module = __import__(self.module_name)
 10        return Filter(module)
 11
 12    def __exit__(self, exc_type, exc_value, traceback):
 13        return False
 14
 15
 16class Filter:
 17    BASE_VALUES = {
 18        "int": 1,
 19        "float": 1.0,
 20        "str": "a",
 21        "bool": True,
 22        "complex": 1 + 0j,
 23        "bytes": b"a",
 24    }
 25
 26    def __init__(self, module):
 27        self.module = module
 28
 29    def whats_your_name(self, attribute):
 30        if hasattr(attribute, "__name__"):
 31            value = getattr(attribute, "__name__", "")
 32            return isinstance(value, str) and re.fullmatch(r"[A-Z]+.*", value)
 33        
 34        return False
 35
 36    
 37    def cartesian_product(self, sets):
 38        if not sets:
 39            yield ()
 40            return
 41
 42        for item in sets[0]:
 43            for rest in self.cartesian_product(sets[1:]):
 44                yield (item,) + rest
 45
 46    def value_from_type(self, type_name):
 47        type_name = type_name.strip()
 48
 49        if type_name in self.BASE_VALUES:
 50            return self.BASE_VALUES[type_name]
 51
 52        match = re.fullmatch(r"(list|tuple|set)\[(.+)\]", type_name)
 53
 54        if match:
 55            collection_type = match.group(1)
 56            inner_type = match.group(2).strip()
 57
 58            inner_value = self.value_from_type(inner_type)
 59
 60            if collection_type == "list":
 61                return [inner_value]
 62
 63            if collection_type == "tuple":
 64                return (inner_value,)
 65
 66            if collection_type == "set":
 67                return {inner_value}
 68
 69        match = re.fullmatch(r"dict\[(.+),\s*(.+)\]", type_name)
 70
 71        if match:
 72            key_type = match.group(1).strip()
 73            value_type = match.group(2).strip()
 74
 75            key = self.value_from_type(key_type)
 76            value = self.value_from_type(value_type)
 77
 78            return {key: value}
 79
 80        raise ValueError(f"Unknown type: {type_name}")
 81
 82
 83    def values_from_current_types(self, curr):
 84        values = []
 85
 86        for type_name in curr:
 87            values.append(self.value_from_type(type_name))
 88
 89        return values
 90
 91    def whats_your_quest(self, attribute):
 92        if not callable(attribute):
 93            return False
 94        
 95        match = ""
 96        if attribute.__doc__:
 97            match = re.search(r"Parameters\s*\n-+\s*\n([\s\S]*?)(?:\n\s*\n|$)", attribute.__doc__)
 98
 99        if match:
100            match = match.group(1)
101        else:
102            match = ""
103        
104        parameters = []
105        for line in match.splitlines():
106            line = line.strip()
107            
108            if line:
109                name, types_of_name = line.split(":", 1) 
110                name = name.strip()
111                types_of_name = types_of_name.strip()
112                parameters.append((name, types_of_name))
113        
114        signature = inspect.signature(attribute)
115
116        names = list(signature.parameters.keys())
117        doc_names = [name for name, type_of_name in parameters]
118
119        if names != doc_names:
120            return False
121        
122        types_by_parameter = []
123
124        for name, types_of_name in parameters:
125            types = [t.strip() for t in types_of_name.split("|")]
126            types_by_parameter.append(types)
127
128        for curr in self.cartesian_product(types_by_parameter):
129            vals = self.values_from_current_types(curr)
130            
131            try:
132                attribute(*vals)
133            except:
134                return  False
135
136        return True
137
138    def not_dunder(self, attribute):
139        return not (attribute.startswith("__") and attribute.endswith("__"))
140
141    def no_4_consecutive_vowels(self, attribute):
142        return re.search(r"[aeiouAEIOU]{4,}", attribute) is None
143
144    def upper_last_letter(self, attribute):
145        return re.fullmatch(r".*[A-Z][^a-z]*", attribute)
146
147    def what_is(self, attribute):
148        r_correct_attr = "[^_]" 
149        for attr in dir(attribute):
150            if self.not_dunder(attr) and self.no_4_consecutive_vowels(attr) and self.upper_last_letter(attr):
151                return True
152        return False
153
154    def isValid(self, attribute):
155        return self.whats_your_name(attribute) and self.whats_your_quest(attribute) and self.what_is(attribute)
156
157    def __getattr__(self, name):
158        attribute = getattr(self.module, name)
159
160        if self.isValid(attribute):
161            return attribute
162        
163        raise AttributeError

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

OK

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