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:
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._operators = ['+', '-', '/', '*']
self._delimiters = ['(', ')', '[', ']', ';', ' ']
@ -23,51 +19,107 @@ class AbacusCore:
return self._funcs
def add_var(self, name, value):
name = name.strip()
if not name:
raise ValueError("Имя переменной не может быть пустым")
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 add_func(self, name, value):
name = name.strip()
if not name:
raise ValueError("Имя функции не может быть пустым")
self._funcs[name] = value
def parse_input(self, input_str):
'''
versuche input_str zu parsen in comment vars und andere teile
:param input_str:
:return:
'''
comment = None
"""
Execute a multiline input sequentially, line by line.
All lines share the same variable/function dictionaries, so a
variable created on one line is immediately available on the next.
"""
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
if len(input_str) < 1: # leere eingabe wird nicht akzeptiert
return
chunks = input_str.split('#')
if len(chunks) > 1:
input_str = chunks[0]
comment = ' '.join(chunks[1:])
chunks = input_str.split('=') # gibt es variablenzuweisung?
input_str = input_str.strip()
if not input_str:
return None
input_str, comment = self._get_input_wo_commentar(input_str)
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:
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
raise ValueError("Mehrfachzuweisung wird nicht unterstützt")
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):
input_str, comment = self._get_input_wo_commentar(input_str)
@ -90,6 +142,7 @@ class AbacusCore:
return eval(''.join(chunks))
def _is_a_variable_or_func(self, chunk):
chunk = chunk.strip()
var = self._vars.get(chunk)
if not var:
var = self._funcs.get(chunk)
@ -122,7 +175,6 @@ class AbacusCore:
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)
@ -171,6 +223,6 @@ class AbacusCore:
raise ValueError()
# chunks.reverse()
elif chunks_len == 2:
return chunks[1], chunks[0]
return chunks[1].strip(), chunks[0].strip()
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