Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import re
- class MealyError(Exception):
- pass
- class Mealy:
- paths: dict = {}
- func_names: list = []
- currentVertex = ''
- def build(self, s: str = 'A -> foo 0 -> B') -> None:
- s = re.sub("(?m)^\\s+", "", s)
- s = s.split('\n')[:-1]
- keys = ['vertex', 'del1', 'func', 'res', 'del2', 'vTo']
- s = [dict(zip(keys, line.split(' '))) for line in s]
- db: dict = {}
- self.currentVertex = s[0].get('vertex')
- for item in s:
- if item['vertex'] not in db:
- db[item['vertex']] = {
- item['func']: {
- 'res': int(item['res']),
- 'vTo': item['vTo']
- }
- }
- else:
- db[item['vertex']][item['func']] = {
- 'res': int(item['res']),
- 'vTo': item['vTo']
- }
- if item['vTo'] not in db:
- db[item['vTo']] = {}
- if item['func'] not in self.func_names:
- self.func_names.append(item['func'])
- self.__add_func(item['func'])
- self.paths = db
- def test(self):
- for v in self.paths:
- self.__invoke_func_test(v)
- pass
- def __add_func(self, func_name: str = 'foo'):
- def func():
- return self.__invoke_func(func_name)
- func.__name__ = func_name
- self.__setattr__(func_name, func)
- def __build_test(self):
- data = '''
- A -> foo 0 -> B
- A -> bar 1 -> D
- B -> cat 2 -> C
- B -> foo 3 -> D
- C -> cat 5 -> C
- C -> bar 4 -> D
- '''
- self.build(data)
- paths = {'A': {'foo': {'res': 0, 'vTo': 'B'},
- 'bar': {'res': 1, 'vTo': 'D'}},
- 'B': {'cat': {'res': 2, 'vTo': 'C'},
- 'foo': {'res': 3, 'vTo': 'D'}},
- 'C': {'cat': {'res': 5, 'vTo': 'C'},
- 'bar': {'res': 4, 'vTo': 'D'}},
- 'D': {}}
- assert self.currentVertex == 'A'
- assert self.paths == paths
- assert self.func_names == ['foo', 'bar', 'cat']
- for func_name in self.func_names:
- self.__delattr__(func_name)
- self.currentVertex = ''
- self.paths = {}
- self.func_names = []
- def __invoke_func(self, func_name: str = '') -> int:
- try:
- func_res: dict = self.paths[self.currentVertex][func_name]
- self.currentVertex = func_res['vTo']
- return func_res['res']
- except KeyError:
- raise MealyError(func_name)
- def __add_func_test(self):
- self.currentVertex = 'A'
- self.paths = {'A': {'foo': {'res': 0, 'vTo': 'B'}},
- 'B': {'bar': {'res': 1, 'vTo': 'C'}},
- 'C': {'cat': {'res': 2, 'vTo': 'A'}}}
- for vertex, func in self.paths.items():
- func_name = list(func.keys())[0]
- self.__add_func(func_name=func_name)
- assert self.__getattribute__(func_name)() == \
- func[func_name]['res']
- self.__delattr__(func_name)
- def __invoke_func_test(self, vertex: str = 'A'):
- initial_vertex = self.currentVertex
- self.currentVertex = vertex
- v_funcs = self.paths[vertex]
- for func_name in self.func_names:
- if func_name in v_funcs:
- assert self.__invoke_func(func_name) == \
- v_funcs[func_name].get('res')
- assert self.currentVertex == \
- v_funcs[func_name].get('vTo')
- self.currentVertex = vertex
- else:
- try:
- self.__invoke_func(func_name)
- except MealyError as e:
- assert e.args[0] == func_name
- self.currentVertex = initial_vertex
- def __init__(self):
- self.__build_test()
- self.__add_func_test()
- pass
- def main():
- o = Mealy()
- o.build('''
- A -> log 0 -> B
- A -> make 1 -> D
- B -> jog 2 -> C
- B -> log 3 -> D
- C -> log 5 -> C
- C -> make 4 -> D
- D -> log 6 -> E
- D -> pose 8 -> F
- D -> jog 7 -> G
- E -> jog 9 -> F
- F -> pose 10 -> G
- G -> log 11 -> H
- ''')
- return o
- def test():
- o = main()
- o.test()
- if __name__ == '__main__':
- test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement