class AbacusCore: def __init__(self): self._input_string = input self._vars = dict() self._funcs = dict() self._vars['result'] = 0 self._vars['alphabet'] = 28 self._vars['alpha'] = 1 self._vars['beta'] = 2 def get_vars(self): return self._vars def get_funcs(self): return self._funcs def add_var(self, name, value): self._vars[name] = value def _calculate(self, input_str): print('input:', input_str) try: return eval(input_str) except ZeroDivisionError: res = 'Division by Zero' except NameError as e: res = 'Variable '+ e.name + ' not exists' except SyntaxError as e: res = 'Syntax Error' return res def parse_input(self, input_str): ''' versuche input_str zu parsen in comment vars und andere teile :param input_str: :return: ''' if input_str.find(':')>-1: chunks = input_str.split(':') if len(chunks) == 2: self._funcs[chunks[0]] = chunks[1] else: return self._with_variable(input_str) def _with_variable(self, input_str): input_str, comment = self._get_input_wo_commentar(input_str) func = self._funcs.get(input_str) if func: input_str = func input_str = ''.join(input_str.split()) # entferne alle leerzeichen input_str = input_str.replace(',', '.') if input_str is not None: expression, new_var = self._is_new_variable(input_str) # chunks für variablenzuweisung # print('expression', expression) expression_wo_vars = self._replace_vars(expression) # print('expression wo vars', expression_wo_vars) expression_calculated = self._calculate(expression_wo_vars) # print('eval', expression_calculated) if new_var is not None: self._vars[new_var] = expression_calculated self._vars['result'] = expression_calculated return input_str, expression_wo_vars, expression_calculated, comment else: return 'comment', comment def _replace_vars(self, input_str): ''' try to find vars and replace them :param input_str: :return: ''' first_position = None new_input_str = '' operators = ['+', '-', '/', '*'] delimiters = ['(', ')', '[', ']', ';'] op_del = operators + delimiters if input_str[0] in operators: input_str = 'result' + input_str input_str_len = len(input_str) for i, c in enumerate(input_str): if c in op_del or i == input_str_len-1: # and first_position is not None: if first_position is not None: last_position = i if i == input_str_len-1: last_position += 1 temp_var = input_str[first_position:last_position] print('var', temp_var) var = self._vars.get(temp_var) if var is not None: new_input_str += str(var) else: func = self._funcs.get(temp_var) if func: new_input_str += str(func) else: raise NotImplemented() first_position = None if i == input_str_len - 1: continue new_input_str += input_str[i] elif c.isalpha() or c=='_': if first_position is None: first_position = i else: new_input_str += input_str[i] return new_input_str def _get_input_wo_commentar(self, input_str): ''' Zerlege input in input und kommentar :param input_str: :return: ''' input_str = input_str.strip() comment_index = input_str.find('#') if comment_index == 0: # die ganze zeile ist ein kommentar return None, input_str elif comment_index == -1: return input_str, None else: comment = input_str[comment_index + 1:] input_str = input_str[:comment_index] return input_str, comment def _is_new_variable(self, input_str): ''' ''' chunks = input_str.split('=') chunks_len = len(chunks) if chunks_len > 2: raise ValueError() # chunks.reverse() elif chunks_len == 2: return chunks[1], chunks[0] else: return chunks[0], None