Compare commits
8 Commits
master
...
another_pa
| Author | SHA1 | Date |
|---|---|---|
|
|
595fae4a13 | |
|
|
d608d2f077 | |
|
|
b5584bf316 | |
|
|
70d02e0c1b | |
|
|
ef5d7b9747 | |
|
|
2f580678fa | |
|
|
7f30a44f6d | |
|
|
0a42a8e272 |
|
|
@ -0,0 +1,22 @@
|
|||
import unittest
|
||||
from abacus import Abacus
|
||||
|
||||
class AbacusTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.ab = Abacus()
|
||||
self.ab.set_var('code with', 20)
|
||||
|
||||
def test_var_assignment(self):
|
||||
input_string = 'funk=(5+5)/2'
|
||||
input_string = Abacus.clean_input(input_string)
|
||||
chunks = Abacus.split_chunks(input_string)
|
||||
Abacus.validate_chunks(chunks)
|
||||
comment = Abacus.get_comment_from_chunks(chunks)
|
||||
chunks_wo_comment = Abacus.get_chunks_without_comment(chunks)
|
||||
|
||||
chunks_wo = self.ab.process_chunks(chunks_wo_comment)
|
||||
var, chunks_wo_var = Abacus.get_var_assignment_from_chunks(chunks_wo_comment)
|
||||
if var is not None:
|
||||
res = Abacus.calculate(''.join(chunks_wo_var))
|
||||
self.ab.set_var(var, res)
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
import mathematik
|
||||
|
||||
|
||||
class AbacusMultipleAssignmentException(Exception):
|
||||
pass
|
||||
|
||||
class AbacusNameAssignmentException(Exception):
|
||||
pass
|
||||
|
||||
class AbacusWrongAssignmentException(Exception):
|
||||
pass
|
||||
|
||||
class AbacusEmptyAssignmentException(Exception):
|
||||
pass
|
||||
|
||||
class AbacusDataModel:
|
||||
step_no = 0
|
||||
def __init__(self, input_string, chunks, chunks_values, value, comment, step_no=None):
|
||||
self._input_string = input_string
|
||||
self._chunks = chunks
|
||||
self._chunks_values = chunks_values
|
||||
self._value = value
|
||||
self._comment = comment
|
||||
if step_no is not None:
|
||||
self._step_no = step_no
|
||||
else:
|
||||
self._step_no = AbacusDataModel._get_next_step_no()
|
||||
|
||||
@classmethod
|
||||
def _get_next_step_no(cls):
|
||||
cls.step_no += 1
|
||||
return cls.step_no
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@property
|
||||
def input_string(self):
|
||||
return self._input_string
|
||||
|
||||
@property
|
||||
def chunks(self):
|
||||
return self._chunks
|
||||
|
||||
@property
|
||||
def chunks_values(self):
|
||||
return self._chunks_values
|
||||
|
||||
@property
|
||||
def comment(self):
|
||||
return self._comment
|
||||
|
||||
def __repr__(self):
|
||||
return self._step_no, self._input_string, str(self._chunks), str(self._chunks_values), self._value, self._comment
|
||||
|
||||
|
||||
|
||||
class Abacus:
|
||||
stop_operators = [':', '=']
|
||||
operators = ['+', '-', '*', '/', ',']
|
||||
brackets = ['(', ')']
|
||||
comment = '#'
|
||||
math_operator = '>'
|
||||
|
||||
def __init__(self):
|
||||
self._vars = {'result': '0', 'cba': 'result+20+add'}
|
||||
self._formel = {'add': 'result+10', 'abc': 'cba-result'} # dict()
|
||||
|
||||
def get_vars(self):
|
||||
return self._vars
|
||||
|
||||
|
||||
|
||||
def get_var_by_name(self, name):
|
||||
return self._vars.get(name, None)
|
||||
|
||||
def get_formel_by_name(self, name):
|
||||
return self._formel.get(name, None)
|
||||
|
||||
def set_var(self, name, value):
|
||||
if name in Abacus.stop_operators or name in Abacus.operators or name in Abacus.comment or name in Abacus.brackets:
|
||||
raise AbacusNameAssignmentException('Name cannot be a operator')
|
||||
res = self.get_formel_by_name(name)
|
||||
if res:
|
||||
raise AbacusNameAssignmentException('Name {} already exists'.format(name))
|
||||
self._vars[name] = str(value)
|
||||
|
||||
def set_formel(self, name, value):
|
||||
if name in Abacus.stop_operators or name in Abacus.operators or name in Abacus.comment or name in Abacus.brackets:
|
||||
raise AbacusNameAssignmentException('Name cannot be a operator')
|
||||
res = self.get_var_by_name(name)
|
||||
if res:
|
||||
raise AbacusNameAssignmentException('Name {} already exists'.format(name))
|
||||
self._formel[name] = str(value)
|
||||
|
||||
|
||||
@classmethod
|
||||
def calculate(cls, input_string):
|
||||
try:
|
||||
return eval(input_string)
|
||||
except Exception as e:
|
||||
return e
|
||||
|
||||
@classmethod
|
||||
def clean_input(cls, input_string):
|
||||
input_string = str(input_string)
|
||||
# input_string = input_string.replace(' ', '')
|
||||
# input_string = input_string.replace('.', '')
|
||||
input_string = input_string.replace(',', '.')
|
||||
input_string = input_string.replace(';', ',')
|
||||
return input_string.strip()
|
||||
|
||||
|
||||
@classmethod
|
||||
def split_chunks(cls, input_string):
|
||||
chunks = list()
|
||||
last_pos = 0
|
||||
cnt_stop = 0
|
||||
for i, c in enumerate(input_string):
|
||||
if c == cls.comment:
|
||||
if last_pos != i:
|
||||
chunks.append(input_string[last_pos:i].strip())
|
||||
chunks.append(input_string[i:].strip())
|
||||
return chunks
|
||||
if c in cls.stop_operators and cnt_stop == 0:
|
||||
chunks.append(input_string[last_pos:i].strip())
|
||||
chunks.append(input_string[i])
|
||||
last_pos = i+1
|
||||
cnt_stop += 1
|
||||
elif c in cls.stop_operators and cnt_stop > 0:
|
||||
raise AbacusMultipleAssignmentException('Multiple assignments not supported')
|
||||
|
||||
if c in cls.operators or c in cls.brackets:
|
||||
if i != last_pos:
|
||||
chunks.append(input_string[last_pos:i].strip())
|
||||
chunks.append(input_string[i].strip())
|
||||
last_pos = i+1
|
||||
elif i == len(input_string)-1: # das letzte zeichen
|
||||
chunks.append(input_string[last_pos:i+1].strip())
|
||||
return chunks
|
||||
|
||||
@classmethod
|
||||
def validate_chunks(cls, chunks):
|
||||
input_str = ''.join(chunks)
|
||||
if input_str[-1] in cls.operators:
|
||||
raise AbacusWrongAssignmentException('Last character cannot be a operator')
|
||||
for i, chunk in enumerate(chunks):
|
||||
if chunk in cls.stop_operators and i != 1:
|
||||
raise AbacusWrongAssignmentException('Wrong assignment expression')
|
||||
|
||||
@classmethod
|
||||
def replace_operator_to_math(cls, input_string):
|
||||
return input_string.replace(cls.math_operator, 'mathematik.')
|
||||
|
||||
|
||||
def process_chunks(self, chunks):
|
||||
chunks = chunks[:]
|
||||
for i, chunk in enumerate(chunks):
|
||||
res = self.get_var_by_name(chunk)
|
||||
if res is not None:
|
||||
chunks[i] = res
|
||||
else:
|
||||
res = self.get_formel_by_name(chunk)
|
||||
if res is not None:
|
||||
cchunks = Abacus.split_chunks(res)
|
||||
res_var = self.process_chunks(cchunks)
|
||||
for i in res_var:
|
||||
chunks.insert()[i] = res_var # TODO: Unboxing die Liste und integration in die bestehende
|
||||
|
||||
return chunks
|
||||
|
||||
def _replace_formel_and_vars(self, input_str):
|
||||
chunks = Abacus.split_chunks(input_str)
|
||||
for i, chunk in enumerate(chunks):
|
||||
res = self.get_var_by_name(chunk)
|
||||
if res is not None:
|
||||
chunks[i] = self._replace_formel_and_vars(res)
|
||||
else:
|
||||
res = self.get_formel_by_name(chunk)
|
||||
if res is not None:
|
||||
chunks[i] = self._replace_formel_and_vars(res)
|
||||
return ''.join(chunks)
|
||||
|
||||
|
||||
|
||||
def process_input(self, input_str):
|
||||
input_string = Abacus.clean_input(input_str)
|
||||
input_string = self.replace_operator_to_math(input_string)
|
||||
if len(input_string) == 0:
|
||||
raise AbacusEmptyAssignmentException('Empty assignment expression')
|
||||
chunks = Abacus.split_chunks(input_string)
|
||||
comment, chunks = Abacus.get_comment_and_rest(chunks)
|
||||
Abacus.validate_chunks(chunks)
|
||||
formel, var_chunks = Abacus.get_function_assignment_from_chunks(chunks)
|
||||
if formel is not None:
|
||||
self.set_formel(formel, ''.join(var_chunks))
|
||||
clean_chunks = self._replace_formel_and_vars(''.join(var_chunks))
|
||||
value = Abacus.calculate(clean_chunks)
|
||||
return input_string, chunks, clean_chunks, value, comment
|
||||
else:
|
||||
var, formel_chunks = Abacus.get_var_assignment_from_chunks(chunks)
|
||||
if var is not None:
|
||||
self.set_var(var, ''.join(formel_chunks))
|
||||
clean_chunks = self._replace_formel_and_vars(''.join(formel_chunks))
|
||||
value = Abacus.calculate(clean_chunks)
|
||||
return input_string, chunks, clean_chunks, value, comment
|
||||
else:
|
||||
clean_chunks = self._replace_formel_and_vars(''.join(chunks))
|
||||
value = Abacus.calculate(clean_chunks)
|
||||
return input_string, chunks, clean_chunks, value, comment
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_var_assignment_from_chunks(cls, chunks):
|
||||
chunks = chunks[:]
|
||||
chunks = ''.join(chunks).split(cls.stop_operators[1])
|
||||
if len(chunks) > 2:
|
||||
raise AbacusMultipleAssignmentException('Multiple assignments not supported')
|
||||
if len(chunks) == 2:
|
||||
return chunks[0], chunks[1:]
|
||||
return None, None
|
||||
|
||||
@classmethod
|
||||
def get_function_assignment_from_chunks(cls, chunks):
|
||||
chunks = chunks[:]
|
||||
chunks = ''.join(chunks).split(cls.stop_operators[0])
|
||||
if len(chunks) > 2:
|
||||
raise AbacusMultipleAssignmentException('Multiple assignments not supported')
|
||||
if len(chunks) == 2:
|
||||
return chunks[0], chunks[1:]
|
||||
return None, None
|
||||
|
||||
@classmethod
|
||||
def get_comment_from_chunks(cls, chunks):
|
||||
for chunk in chunks:
|
||||
chunk = str(chunk)
|
||||
if chunk.startswith(cls.comment):
|
||||
chunk = chunk[1:]
|
||||
return chunk.strip()
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_chunks_without_comment(cls, chunks):
|
||||
for i, chunk in enumerate(chunks):
|
||||
chunk = str(chunk)
|
||||
if chunk.startswith(cls.comment):
|
||||
return chunks[:i]
|
||||
return chunks
|
||||
|
||||
@classmethod
|
||||
def get_comment_and_rest(cls, chunks):
|
||||
comment = cls.get_comment_from_chunks(chunks)
|
||||
rest = cls.get_chunks_without_comment(chunks)
|
||||
return comment, rest
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
input_string = ['10+5', 'bbc:(10+10)', 'bba=(bbc+20)', 'bba//bbc']
|
||||
steps = list()
|
||||
ab = Abacus()
|
||||
|
||||
for i_s in input_string:
|
||||
res = ab.process_input(i_s)
|
||||
adm = AbacusDataModel(*res)
|
||||
steps.append(adm)
|
||||
|
||||
for s in steps:
|
||||
s.__repr__()
|
||||
|
||||
229
abacus_core.py
229
abacus_core.py
|
|
@ -4,95 +4,178 @@
|
|||
class AbacusCore:
|
||||
|
||||
def __init__(self):
|
||||
self._input_string = input
|
||||
self._input_string = ""
|
||||
self._vars = dict()
|
||||
self._funcs = dict()
|
||||
|
||||
self._vars['result'] = 0
|
||||
self._vars['alphabet'] = 28
|
||||
self._vars['alpha'] = 1
|
||||
self._vars['beta'] = 2
|
||||
|
||||
self._funcs['r2'] = lambda x: round(x, 2)
|
||||
self._funcs['r0'] = lambda x: int(x)
|
||||
|
||||
|
||||
def _calculate(self, input_str):
|
||||
try:
|
||||
return True, eval(input_str)
|
||||
except ZeroDivisionError:
|
||||
res = 'Division by Zero'
|
||||
except NameError as e:
|
||||
res = 'Variable '+ e.name + ' not exists'
|
||||
return False, res
|
||||
self._operators = ['+', '-', '/', '*']
|
||||
self._delimiters = ['(', ')', '[', ']', ';', ' ']
|
||||
|
||||
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:
|
||||
'''
|
||||
input_str = input_str.strip()
|
||||
comment = None
|
||||
input_wo_com = None
|
||||
success = False
|
||||
input_str = str(input_str).strip()
|
||||
orig_input_str = input_str
|
||||
if len(input_str) < 1: # leere eingabe wird nicht akzeptiert
|
||||
return
|
||||
if input_str[0] == '#': # ganze eingabe ist ein kommentar
|
||||
comment = input_str
|
||||
return None, None, None, comment
|
||||
chunks = input_str.split('#')
|
||||
if len(chunks) > 1:
|
||||
input_str = chunks[0]
|
||||
comment = ' '.join(chunks[1:])
|
||||
chunks = input_str.split('=') # gibt es variablenzuweisung?
|
||||
if len(chunks) > 2:
|
||||
raise ValueError('Mehrfachzuweisung wird nicht unterstützt')
|
||||
elif len(chunks) > 1:
|
||||
expression = self._with_variable_another_way(chunks[1])
|
||||
chunks[0] = '_'.join(chunks[0].strip().split(' '))
|
||||
self._vars[chunks[0]] = expression
|
||||
return
|
||||
chunks = input_str.split(':') # gibt es funktionsdefinition?
|
||||
if len(chunks) > 1:
|
||||
self._funcs[chunks[0]] = chunks[1]
|
||||
return
|
||||
res = self._with_variable_another_way(input_str)
|
||||
self._vars['result'] = res
|
||||
return orig_input_str, None, res, comment
|
||||
|
||||
|
||||
|
||||
|
||||
def _with_variable_another_way(self, input_str):
|
||||
input_str, comment = self._get_input_wo_commentar(input_str)
|
||||
input_str = ''.join(input_str.split()) # entferne alle leerzeichen
|
||||
input_str = input_str.replace(',', '.')
|
||||
if input_str[0] == '#':
|
||||
comment = input_str[1:]
|
||||
com_index = input_str.find('#')
|
||||
if com_index > -1:
|
||||
input_wo_com = input_str[:com_index]
|
||||
comment = input_str[com_index + 1:]
|
||||
if input_wo_com is None:
|
||||
input_wo_com = input_str
|
||||
print('comment', comment)
|
||||
result = self._split_input(input_wo_com)
|
||||
print('result:',result)
|
||||
if result[1] is not None:
|
||||
success, res = self._calculate(result[1])
|
||||
if success:
|
||||
operators = result[0]
|
||||
operators.reverse()
|
||||
for op in operators:
|
||||
if op[-1] == '=':
|
||||
self._vars[op[:-1]] = res
|
||||
elif op[-1] == ':':
|
||||
res = self._funcs.get(op[:-1])(res)
|
||||
print('vars:', self._vars)
|
||||
else:
|
||||
print("Error")
|
||||
|
||||
|
||||
def _split_input(self, input_str):
|
||||
last_position = 0
|
||||
varchunks = list()
|
||||
for i, c in enumerate(input_str):
|
||||
if c in [':', '=']:
|
||||
chunk = input_str[last_position:i].strip()
|
||||
chunk = chunk + input_str[i]
|
||||
varchunks.append(chunk)
|
||||
last_position = i+1
|
||||
rest = input_str[last_position:].strip()
|
||||
print('rest', rest)
|
||||
rest = self._find_vars(rest)[1]
|
||||
return varchunks, rest
|
||||
|
||||
def _find_vars(self, input_str):
|
||||
opdel = self._operators + self._delimiters
|
||||
chunks = list()
|
||||
last_position = 0
|
||||
for i, c in enumerate(input_str):
|
||||
if c in ['+', '-', '/', '*', '(', ')', '[', ']', ';']:
|
||||
ch = input_str[last_position:i].strip()
|
||||
if len(ch)>0:
|
||||
chunks.append(ch)
|
||||
chunks.append(input_str[i].strip())
|
||||
last_position = i+1
|
||||
last_index = 0
|
||||
for i, v in enumerate(input_str):
|
||||
if v in opdel:
|
||||
chunk = input_str[last_index:i]
|
||||
chunk = self._is_a_variable_or_func(chunk)
|
||||
chunks.append(chunk)
|
||||
chunks.append(input_str[i])
|
||||
last_index = i+1
|
||||
elif i == len(input_str)-1:
|
||||
chunk = input_str[last_index:i+1]
|
||||
chunk = self._is_a_variable_or_func(chunk)
|
||||
chunks.append(chunk)
|
||||
return eval(''.join(chunks))
|
||||
|
||||
if last_position<len(input_str):
|
||||
chunks.append(input_str[last_position:].strip())
|
||||
cp_chunks = chunks.copy()
|
||||
for i, chunk in enumerate(chunks):
|
||||
if chunk in self._vars:
|
||||
cp_chunks[i] = str(self._vars.get(chunk))
|
||||
print(chunks, cp_chunks)
|
||||
return len(cp_chunks)>1, ''.join(cp_chunks)
|
||||
def _is_a_variable_or_func(self, chunk):
|
||||
var = self._vars.get(chunk)
|
||||
if not var:
|
||||
var = self._funcs.get(chunk)
|
||||
if var:
|
||||
var = self._with_variable_another_way(var)
|
||||
if var:
|
||||
return str(var)
|
||||
else:
|
||||
return chunk
|
||||
|
||||
|
||||
|
||||
|
||||
def _replace_vars(self, input_str):
|
||||
'''
|
||||
try to find vars and replace them
|
||||
:param input_str:
|
||||
:return:
|
||||
'''
|
||||
first_position = None
|
||||
new_input_str = ''
|
||||
op_del = self._operators + self._delimiters
|
||||
if input_str[0] in self._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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
from abacus_core import AbacusCore
|
||||
|
||||
ab = AbacusCore()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
step = 0
|
||||
res = 0
|
||||
while True:
|
||||
var = input('gib was ein:')
|
||||
if var == 'vars':
|
||||
print(ab.get_vars())
|
||||
elif var == 'func':
|
||||
print(ab.get_funcs())
|
||||
elif var == 'res':
|
||||
print(res)
|
||||
else:
|
||||
step += 1
|
||||
res = ab.parse_input(str(var))
|
||||
print('step', step, 'result', res)
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>735</width>
|
||||
<height>770</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>AbacusNG</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="le_input"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_enter">
|
||||
<property name="text">
|
||||
<string>Rechne!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Verlauf</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="lv_history"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Variablen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QListView" name="lv_variable">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="resizeMode">
|
||||
<enum>QListView::ResizeMode::Adjust</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_var_new">
|
||||
<property name="text">
|
||||
<string>Neu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_var_edit">
|
||||
<property name="text">
|
||||
<string>Bearbeiten</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_var_remove">
|
||||
<property name="text">
|
||||
<string>Löschen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Funktionen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="lv_func"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_func_new">
|
||||
<property name="text">
|
||||
<string>Neu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_func_edit">
|
||||
<property name="text">
|
||||
<string>Bearbeiten</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="but_func_remove">
|
||||
<property name="text">
|
||||
<string>Löschnen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>735</width>
|
||||
<height>33</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuDatei">
|
||||
<property name="title">
|
||||
<string>Datei</string>
|
||||
</property>
|
||||
<addaction name="actionNeu"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSpeichern"/>
|
||||
<addaction name="actionSpeichern_unter"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionDrucken"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<addaction name="menuDatei"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="actionNeu">
|
||||
<property name="text">
|
||||
<string>Neu</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSpeichern">
|
||||
<property name="text">
|
||||
<string>Speichern</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSpeichern_unter">
|
||||
<property name="text">
|
||||
<string>Speichern unter</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDrucken">
|
||||
<property name="text">
|
||||
<string>Drucken</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Beenden</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
75
main.py
75
main.py
|
|
@ -1,7 +1,74 @@
|
|||
from abacus_core import AbacusCore
|
||||
import sys
|
||||
|
||||
ab = AbacusCore()
|
||||
from PySide6.QtGui import QStandardItemModel, QStandardItem
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
from PySide6.QtWidgets import QApplication, QFileDialog
|
||||
from PySide6.QtCore import QFile, QIODevice, QModelIndex, QAbstractTableModel
|
||||
from abacus import Abacus, AbacusDataModel, AbacusEmptyAssignmentException
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ab.parse_input('12')
|
||||
class AbacusGUI:
|
||||
|
||||
def __init__(self):
|
||||
self._abacus = Abacus()
|
||||
self._history = []
|
||||
|
||||
self._app = QApplication(sys.argv)
|
||||
ui_file_name = "gui.ui"
|
||||
ui_file = QFile(ui_file_name)
|
||||
if not ui_file.open(QIODevice.ReadOnly):
|
||||
print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")
|
||||
sys.exit(-1)
|
||||
loader = QUiLoader()
|
||||
self._window = loader.load(ui_file)
|
||||
ui_file.close()
|
||||
if not self._window:
|
||||
print(loader.errorString())
|
||||
sys.exit(-1)
|
||||
self._window.show()
|
||||
self._window.but_enter.clicked.connect(self._berechne)
|
||||
self._window.le_input.returnPressed.connect(self._berechne)
|
||||
self._history_model = QStandardItemModel()
|
||||
self._window.lv_history.setModel(self._history_model)
|
||||
self._var_model = QStandardItemModel()
|
||||
self._func_model = QStandardItemModel()
|
||||
self._window.lv_variable.setModel(self._var_model)
|
||||
self._window.lv_func.setModel(self._func_model)
|
||||
self._check_models()
|
||||
sys.exit(self._app.exec())
|
||||
|
||||
def _berechne(self):
|
||||
input_str = self._window.le_input.text()
|
||||
try:
|
||||
self._abacus.process_input(input_str)
|
||||
except AbacusEmptyAssignmentException as e:
|
||||
print(e)
|
||||
return
|
||||
result = self._abacus.process_input(input_str)
|
||||
if result:
|
||||
adm = AbacusDataModel(*result)
|
||||
self._history.append(adm)
|
||||
self._history.append(result)
|
||||
# item = QStandardItem('Halllo')
|
||||
item = QStandardItem(str(result))
|
||||
self._history_model.appendRow(item)
|
||||
self._abacus.set_var('result', result[3])
|
||||
self._window.le_input.setText(str(result[3]))
|
||||
else:
|
||||
self._window.le_input.setText('')
|
||||
self._check_models()
|
||||
|
||||
def _check_models(self):
|
||||
self._var_model.clear()
|
||||
self._func_model.clear()
|
||||
for k, v in self._abacus.get_vars().items():
|
||||
item = QStandardItem(k+' = '+str(v))
|
||||
self._var_model.appendRow(item)
|
||||
# for k, v in self._abacus_core.get_funcs().items():
|
||||
# item = QStandardItem(k+' = '+str(v))
|
||||
# self._func_model.appendRow(item)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ag = AbacusGUI()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
import math
|
||||
|
||||
|
||||
def runden(number, ndigits=None):
|
||||
return round(number, ndigits)
|
||||
|
||||
def potenz(x, y):
|
||||
return math.pow(x,y)
|
||||
|
||||
def prozent_von(number, von):
|
||||
return von / 100 * number
|
||||
Loading…
Reference in New Issue