new look like a jupyter notebook
parent
3f18b0faae
commit
0cf1b0a800
140
abacus_core.py
140
abacus_core.py
|
|
@ -1,17 +1,13 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AbacusCore:
|
class AbacusCore:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._input_string = input
|
self._input_string = ""
|
||||||
self._vars = dict()
|
self._vars = dict()
|
||||||
self._funcs = dict()
|
self._funcs = dict()
|
||||||
|
|
||||||
self._vars['result'] = 0
|
self._vars['result'] = 0
|
||||||
self._vars['alphabet'] = 28
|
|
||||||
self._vars['alpha'] = 1
|
|
||||||
self._vars['beta'] = 2
|
|
||||||
|
|
||||||
self._operators = ['+', '-', '/', '*']
|
self._operators = ['+', '-', '/', '*']
|
||||||
self._delimiters = ['(', ')', '[', ']', ';', ' ']
|
self._delimiters = ['(', ')', '[', ']', ';', ' ']
|
||||||
|
|
@ -23,51 +19,107 @@ class AbacusCore:
|
||||||
return self._funcs
|
return self._funcs
|
||||||
|
|
||||||
def add_var(self, name, value):
|
def add_var(self, name, value):
|
||||||
|
name = name.strip()
|
||||||
|
if not name:
|
||||||
|
raise ValueError("Имя переменной не может быть пустым")
|
||||||
self._vars[name] = value
|
self._vars[name] = value
|
||||||
|
|
||||||
def _calculate(self, input_str):
|
def add_func(self, name, value):
|
||||||
print('input:', input_str)
|
name = name.strip()
|
||||||
try:
|
if not name:
|
||||||
return eval(input_str)
|
raise ValueError("Имя функции не может быть пустым")
|
||||||
except ZeroDivisionError:
|
self._funcs[name] = value
|
||||||
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):
|
def parse_input(self, input_str):
|
||||||
'''
|
"""
|
||||||
versuche input_str zu parsen in comment vars und andere teile
|
Execute a multiline input sequentially, line by line.
|
||||||
:param input_str:
|
|
||||||
:return:
|
All lines share the same variable/function dictionaries, so a
|
||||||
'''
|
variable created on one line is immediately available on the next.
|
||||||
comment = None
|
"""
|
||||||
|
if input_str is None:
|
||||||
|
raise ValueError("Leere Eingabe")
|
||||||
|
|
||||||
|
if not input_str.strip():
|
||||||
|
raise ValueError("Leere Eingabe")
|
||||||
|
|
||||||
|
lines = input_str.splitlines()
|
||||||
|
results = []
|
||||||
|
last_comment = None
|
||||||
|
last_name = None
|
||||||
|
last_value = None
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if not line.strip():
|
||||||
|
continue
|
||||||
|
|
||||||
|
result = self._parse_line(line)
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
orig, name, value, comment = result
|
||||||
|
results.append(result)
|
||||||
|
last_name = name
|
||||||
|
last_value = value
|
||||||
|
last_comment = comment
|
||||||
|
|
||||||
|
if not results:
|
||||||
|
raise ValueError("Leere Eingabe")
|
||||||
|
|
||||||
|
# The notebook displays the result of the last executable line.
|
||||||
|
return input_str, last_name, last_value, last_comment
|
||||||
|
|
||||||
|
def _parse_line(self, input_str):
|
||||||
|
"""Execute exactly one line."""
|
||||||
orig_input_str = input_str
|
orig_input_str = input_str
|
||||||
if len(input_str) < 1: # leere eingabe wird nicht akzeptiert
|
input_str = input_str.strip()
|
||||||
return
|
|
||||||
chunks = input_str.split('#')
|
if not input_str:
|
||||||
if len(chunks) > 1:
|
return None
|
||||||
input_str = chunks[0]
|
|
||||||
comment = ' '.join(chunks[1:])
|
input_str, comment = self._get_input_wo_commentar(input_str)
|
||||||
chunks = input_str.split('=') # gibt es variablenzuweisung?
|
|
||||||
|
if input_str is None or not input_str.strip():
|
||||||
|
return None
|
||||||
|
|
||||||
|
input_str = input_str.strip()
|
||||||
|
|
||||||
|
chunks = input_str.split("=")
|
||||||
|
|
||||||
if len(chunks) > 2:
|
if len(chunks) > 2:
|
||||||
raise ValueError('Mehrfachzuweisung wird nicht unterstützt')
|
raise ValueError("Mehrfachzuweisung wird nicht unterstützt")
|
||||||
elif len(chunks) > 1:
|
|
||||||
expression = self._with_variable_another_way(chunks[1])
|
|
||||||
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
|
|
||||||
|
|
||||||
|
if len(chunks) == 2:
|
||||||
|
name = chunks[0].strip()
|
||||||
|
expression = chunks[1].strip()
|
||||||
|
|
||||||
|
if not name:
|
||||||
|
raise ValueError("Имя переменной не может быть пустым")
|
||||||
|
if not expression:
|
||||||
|
raise ValueError("Значение переменной не может быть пустым")
|
||||||
|
|
||||||
|
value = self._with_variable_another_way(expression)
|
||||||
|
self._vars[name] = value
|
||||||
|
return orig_input_str, name, value, comment
|
||||||
|
|
||||||
|
chunks = input_str.split(":", 1)
|
||||||
|
|
||||||
|
if len(chunks) == 2:
|
||||||
|
name = chunks[0].strip()
|
||||||
|
expression = chunks[1].strip()
|
||||||
|
|
||||||
|
if not name:
|
||||||
|
raise ValueError("Имя функции не может быть пустым")
|
||||||
|
if not expression:
|
||||||
|
raise ValueError("Тело функции не может быть пустым")
|
||||||
|
|
||||||
|
self._funcs[name] = expression
|
||||||
|
return orig_input_str, name, expression, comment
|
||||||
|
|
||||||
|
result = self._with_variable_another_way(input_str)
|
||||||
|
self._vars["result"] = result
|
||||||
|
return orig_input_str, None, result, comment
|
||||||
|
|
||||||
def _with_variable_another_way(self, input_str):
|
def _with_variable_another_way(self, input_str):
|
||||||
input_str, comment = self._get_input_wo_commentar(input_str)
|
input_str, comment = self._get_input_wo_commentar(input_str)
|
||||||
|
|
@ -90,6 +142,7 @@ class AbacusCore:
|
||||||
return eval(''.join(chunks))
|
return eval(''.join(chunks))
|
||||||
|
|
||||||
def _is_a_variable_or_func(self, chunk):
|
def _is_a_variable_or_func(self, chunk):
|
||||||
|
chunk = chunk.strip()
|
||||||
var = self._vars.get(chunk)
|
var = self._vars.get(chunk)
|
||||||
if not var:
|
if not var:
|
||||||
var = self._funcs.get(chunk)
|
var = self._funcs.get(chunk)
|
||||||
|
|
@ -122,7 +175,6 @@ class AbacusCore:
|
||||||
if i == input_str_len-1:
|
if i == input_str_len-1:
|
||||||
last_position += 1
|
last_position += 1
|
||||||
temp_var = input_str[first_position:last_position]
|
temp_var = input_str[first_position:last_position]
|
||||||
print('var', temp_var)
|
|
||||||
var = self._vars.get(temp_var)
|
var = self._vars.get(temp_var)
|
||||||
if var is not None:
|
if var is not None:
|
||||||
new_input_str += str(var)
|
new_input_str += str(var)
|
||||||
|
|
@ -171,6 +223,6 @@ class AbacusCore:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
# chunks.reverse()
|
# chunks.reverse()
|
||||||
elif chunks_len == 2:
|
elif chunks_len == 2:
|
||||||
return chunks[1], chunks[0]
|
return chunks[1].strip(), chunks[0].strip()
|
||||||
else:
|
else:
|
||||||
return chunks[0], None
|
return chunks[0].strip(), None
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"format": "abacus-global-library",
|
||||||
|
"version": 1,
|
||||||
|
"variables": {
|
||||||
|
"alfa": 20
|
||||||
|
},
|
||||||
|
"functions": {
|
||||||
|
"double": "result*2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
{
|
||||||
|
"format": "abacus-notebook",
|
||||||
|
"version": 1,
|
||||||
|
"variables": {
|
||||||
|
"result": 25,
|
||||||
|
"alfa": 20
|
||||||
|
},
|
||||||
|
"functions": {
|
||||||
|
"double": "alfa*2"
|
||||||
|
},
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"step": 1,
|
||||||
|
"code": "alfa=20",
|
||||||
|
"result": 0,
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 2,
|
||||||
|
"code": "alfa+5",
|
||||||
|
"result": 25,
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 3,
|
||||||
|
"code": "double:alfa*2",
|
||||||
|
"result": 25,
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 4,
|
||||||
|
"code": "",
|
||||||
|
"result": null,
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 5,
|
||||||
|
"code": "",
|
||||||
|
"result": null,
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 6,
|
||||||
|
"code": "",
|
||||||
|
"result": null,
|
||||||
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 7,
|
||||||
|
"code": "",
|
||||||
|
"result": null,
|
||||||
|
"error": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"graph": [
|
||||||
|
{
|
||||||
|
"step": 1,
|
||||||
|
"result": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 2,
|
||||||
|
"result": 25.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": 3,
|
||||||
|
"result": 25.0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 839 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
Loading…
Reference in New Issue