new look like a jupyter notebook

notebook
a.jurcenko 2026-08-12 14:08:06 +02:00
parent 3f18b0faae
commit 0cf1b0a800
7 changed files with 1446 additions and 44 deletions

View File

@ -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

View File

@ -0,0 +1,10 @@
{
"format": "abacus-global-library",
"version": 1,
"variables": {
"alfa": 20
},
"functions": {
"double": "result*2"
}
}

View File

@ -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
}
]
}

1271
abacus_notebook.py 100644

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