import class_Expression as cex
from pyodide import create_proxy, to_js
import js
import numpy as np
import re
numpart=0
strpart=""
exp_py=cex.Expression()
exp_py.add_branch('+','x')
exp_py.add_branch('+','2')
exp_py.add_branch('*','y')
document.getElementById("factor-input").value=exp_py.print_tree('l')
def zero_expression(event):
global exp_py
del exp_py
exp_py=cex.Expression()
exp_py.add_branch('+','0')
document.getElementById("factor-input").value=exp_py.print_tree('l')
def clear_selection(event):
js.document.getElementById("print-tree").innerHTML=""
js.selectedNodes=[]
def show_expression(event):
txt=exp_py.print_tree('l', js.document.getElementById("print-tree").innerHTML)
js.set_answerMathField(create_proxy(txt))
def push_vars(event):
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
def parseFactor():
document.getElementById("print-tree").innerHTML="parseFactor"
global numpart
global strpart
numpart=0;
strpart="";
expString=js.document.getElementById("factor-input").value
if not(re.search("^-?[0-9]*[a-z]*$", expString)):
raise ValueError("your expression must be in the form (-)(number)(lowercase letters)")
for i in range(0, len(expString)):
if expString[i].isdigit():
numpart=int(expString[0:i+1])
strpart=expString[i+1:]
if numpart==0 and strpart=="":
strpart=expString
def treeFactor(numpart, strpart):
exp_sub=cex.Expression()
if numpart>1:
exp_sub.add_branch('+',str(numpart))
elif numpart==1 and strpart=='':
exp_sub.add_branch('+',str(numpart))
elif numpart<0:
exp_sub.add_branch('-',str(-1*numpart))
elif strpart[0]=='-':
exp_sub.add_branch('-', '1')
strpart=strpart[1:]
else:
exp_sub.add_branch('+',strpart[0])
strpart=strpart[1:]
while len(strpart)>0:
exp_sub.add_branch('*',strpart[0])
strpart=strpart[1:]
return exp_sub
def add_exp(event):
global numpart
global strpart
global exp_py
try:
parseFactor()
except:
document.getElementById("print-tree").innerHTML="your expression must be in the form (-)(number)(lowercase letters)"
else:
document.getElementById("print-tree").innerHTML=str(numpart)+","+strpart
tops=js.findtops()
selectedtop=tops[0]
exptop=tops[1]
document.getElementById("print-tree").innerHTML=str(exptop)+","+str(selectedtop)
if (selectedtop==exptop and js.isSelectedNode(selectedtop)) or selectedtop==999:
exp_insert=treeFactor(numpart, strpart)
if len(exp_insert.elements)==1:
exp_py.add_branch('+', exp_insert.elements[0][1])
else:
maxindex=exp_py.elements[:,0].max()
for x1 in exp_insert.elements:
x1[0]=x1[0]+1+maxindex
if x1[2]!=None:
x1[2]=x1[2]+1+maxindex
x1[3]=x1[3]+1+maxindex
maxinsindex=exp_insert.elements[:,0].max()
oldelements=exp_py.elements
exp_py.elements=np.concatenate((oldelements, [[maxinsindex+1, '+', int(maxindex), int(maxinsindex)]], exp_insert.elements), axis=0)
else:
operators=js.find_operators()[0]
document.getElementById("print-tree").innerHTML=operators
exp_insert=treeFactor(numpart, strpart)
minindex_py=int(exp_py.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
for x1 in exp_insert.elements:
x1[0]=x1[0]-maxindex_insert-1+minindex_py
if x1[2] is not None:
x1[2]=x1[2]-maxindex_insert-1+minindex_py
x1[3]=x1[3]-maxindex_insert-1+minindex_py
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
numpart=1
strpart=''
fallenBranch=[]
for x1 in exp_py.elements:
if js.isSelectedNode(x1[0]) and not js.isSelectedNode(js.find_parent(x1[0])) and x1[2] is None:
if x1[1][-1].isdigit():
numpart=numpart*int(x1[1])
if x1[1].islower():
strpart=strpart+x1[1]
if exp_py.elements[exp_py.find_pointer(js.find_parent(x1[0]))][1]=='+':
x1[1]='0'
else:
x1[1]='1'
linknode=x1[0]
elif js.isSelectedNode(x1[0]):
fallenBranch.append([x1[0],x1[1],x1[2],x1[3]])
newnode=[999,'+',None,None]
newnode1=[998,'0',None,None]
if numpart!=1 or strpart!='':
exp_fallenLeafs=treeFactor(numpart, strpart)
for x1 in exp_fallenLeafs.elements:
if x1[2]!=None:
x1[1]=exp_py.elements[exp_py.find_pointer(selectedtop)][1]
else:
exp_fallenLeafs=cex.Expression()
if len(fallenBranch)>0:
p=js.find_parent(fallenBranch[0][0])
fallenBranchStump=fallenBranch[0][0]
while p in [x2[0] for x2 in fallenBranch]:
fallenBranchStump=p
p=js.find_parent(p)
filter_arr=[]
for x1 in exp_py.elements:
if x1[0] in [x2[0] for x2 in fallenBranch] and x1[0]!=fallenBranchStump:
filter_arr.append(False)
elif x1[0] in [x2[0] for x2 in fallenBranch] and x1[0]==fallenBranchStump:
filter_arr.append(False)
else:
filter_arr.append(True)
exp_py.elements=exp_py.elements[filter_arr]
linknode=fallenBranchStump
if not (numpart!=1 or strpart!='') and len(fallenBranch)>0:
newnode[0]=minindex_insert-1
newnode[2]=linknode
newnode[3]=maxindex_insert
p=js.find_parent(linknode)
if exp_py.elements[exp_py.find_pointer(p)][2]==linknode:
exp_py.elements[exp_py.find_pointer(p)][2]=minindex_insert-1
if exp_py.elements[exp_py.find_pointer(p)][3]==linknode:
exp_py.elements[exp_py.find_pointer(p)][3]=minindex_insert-1
exp_py.elements=np.concatenate((exp_py.elements,[newnode], fallenBranch ,exp_insert.elements), axis=0)
elif (numpart!=1 or strpart!='') and len(fallenBranch)==0:
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
minindex_py=int(exp_py.elements[:,0].min())
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
for x1 in exp_fallenLeafs.elements:
x1[0]=x1[0]-maxindex_fl-1+minindex_insert
if x1[2] is not None:
x1[2]=x1[2]-maxindex_fl-1+minindex_insert
x1[3]=x1[3]-maxindex_fl-1+minindex_insert
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
exp_py.elements[exp_py.find_pointer(linknode)][1]='+'
exp_py.elements[exp_py.find_pointer(linknode)][2]=maxindex_fl
exp_py.elements[exp_py.find_pointer(linknode)][3]=maxindex_insert
exp_py.elements=np.concatenate((exp_py.elements,exp_fallenLeafs.elements ,exp_insert.elements), axis=0)
elif (numpart!=1 or strpart!='') and len(fallenBranch)>0:
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
minindex_py=int(exp_py.elements[:,0].min())
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
for x1 in exp_fallenLeafs.elements:
x1[0]=x1[0]-maxindex_fl-1+minindex_insert
if x1[2] is not None:
x1[2]=x1[2]-maxindex_fl-1+minindex_insert
x1[3]=x1[3]-maxindex_fl-1+minindex_insert
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
newnode[0]=minindex_fl-1
newnode[2]=minindex_fl-2
newnode[3]=maxindex_insert
p=js.find_parent(linknode)
if exp_py.elements[exp_py.find_pointer(p)][2]==linknode:
exp_py.elements[exp_py.find_pointer(p)][2]=minindex_fl-1
if exp_py.elements[exp_py.find_pointer(p)][3]==linknode:
exp_py.elements[exp_py.find_pointer(p)][3]=minindex_fl-1
newnode1[0]=minindex_fl-2
newnode1[2]=linknode
newnode1[3]=maxindex_fl
newnode1[1]=exp_py.elements[exp_py.find_pointer(selectedtop)][1]
exp_py.elements=np.concatenate((exp_py.elements,[newnode],[newnode1],exp_fallenLeafs.elements, fallenBranch ,exp_insert.elements), axis=0)
document.getElementById("print-tree").innerHTML= "B" + str(exp_py.elements)
for x1 in exp_py.elements:
x1[0]=int(x1[0])
if x1[2] is not None:
x1[2]=int(x1[2])
x1[3]=int(x1[3])
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
#document.getElementById("print-tree").innerHTML=""
def multiply_exp(event):
global numpart
global strpart
global exp_py
try:
parseFactor()
except:
document.getElementById("print-tree").innerHTML="your expression must be in the form (-)(number)(lowercase letters)"
else:
document.getElementById("print-tree").innerHTML=str(numpart)+","+strpart
tops=js.findtops()
selectedtop=tops[0]
exptop=tops[1]
document.getElementById("print-tree").innerHTML=str(exptop)+","+str(selectedtop)+","+str(js.isSelectedNode(selectedtop))
if (selectedtop==exptop and js.isSelectedNode(selectedtop)) or selectedtop==999:
exp_insert=treeFactor(numpart, strpart)
if len(exp_insert.elements)==1:
exp_py.add_branch('*', exp_insert.elements[0][1])
else:
maxindex=exp_py.elements[:,0].max()
for x1 in exp_insert.elements:
x1[0]=x1[0]+1+maxindex
if x1[2]!=None:
x1[2]=x1[2]+1+maxindex
x1[3]=x1[3]+1+maxindex
maxinsindex=exp_insert.elements[:,0].max()
oldelements=exp_py.elements
exp_py.elements=np.concatenate((oldelements, [[maxinsindex+1, '*', int(maxindex), int(maxinsindex)]], exp_insert.elements), axis=0)
#document.getElementById("print-tree").innerHTML= str(exp_insert.elements)+";"+ str(exp_py.elements)
else:
operators=js.find_operators()[0]
document.getElementById("print-tree").innerHTML=operators
exp_insert=treeFactor(numpart, strpart)
minindex_py=int(exp_py.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
for x1 in exp_insert.elements:
x1[0]=x1[0]-maxindex_insert-1+minindex_py
if x1[2] is not None:
x1[2]=x1[2]-maxindex_insert-1+minindex_py
x1[3]=x1[3]-maxindex_insert-1+minindex_py
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
numpart=1
strpart=''
fallenBranch=[]
for x1 in exp_py.elements:
if js.isSelectedNode(x1[0]) and not js.isSelectedNode(js.find_parent(x1[0])) and x1[2] is None:
if x1[1][-1].isdigit():
numpart=numpart*int(x1[1])
if x1[1].islower():
strpart=strpart+x1[1]
if exp_py.elements[exp_py.find_pointer(js.find_parent(x1[0]))][1]=='+':
x1[1]='0'
else:
x1[1]='1'
linknode=x1[0]
elif js.isSelectedNode(x1[0]):
fallenBranch.append([x1[0],x1[1],x1[2],x1[3]])
newnode=[999,'*',None,None]
newnode1=[998,'0',None,None]
if numpart!=1 or strpart!='':
exp_fallenLeafs=treeFactor(numpart, strpart)
for x1 in exp_fallenLeafs.elements:
if x1[2]!=None:
x1[1]=exp_py.elements[exp_py.find_pointer(selectedtop)][1]
else:
exp_fallenLeafs=cex.Expression()
if len(fallenBranch)>0:
p=js.find_parent(fallenBranch[0][0])
fallenBranchStump=fallenBranch[0][0]
while p in [x2[0] for x2 in fallenBranch]:
fallenBranchStump=p
p=js.find_parent(p)
filter_arr=[]
for x1 in exp_py.elements:
if x1[0] in [x2[0] for x2 in fallenBranch] and x1[0]!=fallenBranchStump:
filter_arr.append(False)
elif x1[0] in [x2[0] for x2 in fallenBranch] and x1[0]==fallenBranchStump:
filter_arr.append(False)
else:
filter_arr.append(True)
exp_py.elements=exp_py.elements[filter_arr]
linknode=fallenBranchStump
if not (numpart!=1 or strpart!='') and len(fallenBranch)>0:
newnode[0]=minindex_insert-1
newnode[2]=linknode
newnode[3]=maxindex_insert
p=js.find_parent(linknode)
if exp_py.elements[exp_py.find_pointer(p)][2]==linknode:
exp_py.elements[exp_py.find_pointer(p)][2]=minindex_insert-1
if exp_py.elements[exp_py.find_pointer(p)][3]==linknode:
exp_py.elements[exp_py.find_pointer(p)][3]=minindex_insert-1
exp_py.elements=np.concatenate((exp_py.elements,[newnode], fallenBranch ,exp_insert.elements), axis=0)
elif (numpart!=1 or strpart!='') and len(fallenBranch)==0:
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
minindex_py=int(exp_py.elements[:,0].min())
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
for x1 in exp_fallenLeafs.elements:
x1[0]=x1[0]-maxindex_fl-1+minindex_insert
if x1[2] is not None:
x1[2]=x1[2]-maxindex_fl-1+minindex_insert
x1[3]=x1[3]-maxindex_fl-1+minindex_insert
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
exp_py.elements[exp_py.find_pointer(linknode)][1]='*'
exp_py.elements[exp_py.find_pointer(linknode)][2]=maxindex_fl
exp_py.elements[exp_py.find_pointer(linknode)][3]=maxindex_insert
exp_py.elements=np.concatenate((exp_py.elements,exp_fallenLeafs.elements ,exp_insert.elements), axis=0)
elif (numpart!=1 or strpart!='') and len(fallenBranch)>0:
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
minindex_py=int(exp_py.elements[:,0].min())
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
for x1 in exp_fallenLeafs.elements:
x1[0]=x1[0]-maxindex_fl-1+minindex_insert
if x1[2] is not None:
x1[2]=x1[2]-maxindex_fl-1+minindex_insert
x1[3]=x1[3]-maxindex_fl-1+minindex_insert
maxindex_fl=int(exp_fallenLeafs.elements[:,0].max())
minindex_fl=int(exp_fallenLeafs.elements[:,0].min())
newnode[0]=minindex_fl-1
newnode[2]=minindex_fl-2
newnode[3]=maxindex_insert
p=js.find_parent(linknode)
if exp_py.elements[exp_py.find_pointer(p)][2]==linknode:
exp_py.elements[exp_py.find_pointer(p)][2]=minindex_fl-1
if exp_py.elements[exp_py.find_pointer(p)][3]==linknode:
exp_py.elements[exp_py.find_pointer(p)][3]=minindex_fl-1
newnode1[0]=minindex_fl-2
newnode1[2]=linknode
newnode1[3]=maxindex_fl
newnode1[1]=exp_py.elements[exp_py.find_pointer(selectedtop)][1]
exp_py.elements=np.concatenate((exp_py.elements,[newnode],[newnode1],exp_fallenLeafs.elements, fallenBranch ,exp_insert.elements), axis=0)
document.getElementById("factor-input").value=str(exp_py.elements)+','+str(exp_insert.elements)+','+str(fallenBranch)+','+str(exp_fallenLeafs.elements)+','+str(newnode)+','+str(newnode1)
for x1 in exp_py.elements:
x1[0]=int(x1[0])
if x1[2] is not None:
x1[2]=int(x1[2])
x1[3]=int(x1[3])
document.getElementById("print-tree").innerHTML=exp_py.print_tree('o')
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def tidy_exp(event):
try:
exp_py.tidy_up()
except:
document.getElementById("print-tree").innerHTML="Error: Division by zero"
js.set_answerMathField(create_proxy("\\text{Error: Division by zero}"))
else:
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def expand_exp(event):
exp_py.expand_brackets()
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def factorise_exp(event):
selectedNodes=js.get_selectedNodes()
try:
parseFactor()
except:
document.getElementById("print-tree").innerHTML="your expression must be in the form (-)(number)(lowercase letters)"
else:
if numpart!=0:
factor=str(numpart)
else:
factor=strpart[0]
try:
exp_py.factorise_selected(factor,selectedNodes)
except:
document.getElementById("print-tree").innerHTML="Error in Factorisation"
js.set_answerMathField(create_proxy("\\text{Error in Factorisation}"))
else:
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def cancel_exp(event):
exp_py.cancel()
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def add_constants_exp(event):
exp_py.add_constants()
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def multiply_constants_exp(event):
exp_py.multiply_constants()
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def add_expressions_exp(event):
exp_py.add_expressions()
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
def divide_exp(event):
global numpart
global strpart
global exp_py
try:
parseFactor()
except:
document.getElementById("print-tree").innerHTML="your expression must be in the form (-)(number)(lowercase letters)"
else:
document.getElementById("print-tree").innerHTML=str(numpart)+","+strpart
tops=js.findtops()
selectedtop=tops[0]
exptop=tops[1]
document.getElementById("print-tree").innerHTML=str(exptop)+","+str(selectedtop)
if selectedtop==exptop or selectedtop==999:
exp_insert=treeFactor(numpart, strpart)
if len(exp_insert.elements)==1:
exp_py.add_branch('/', exp_insert.elements[0][1])
else:
maxindex=exp_py.elements[:,0].max()
for x1 in exp_insert.elements:
x1[0]=x1[0]+1+maxindex
if x1[2]!=None:
x1[2]=x1[2]+1+maxindex
x1[3]=x1[3]+1+maxindex
maxinsindex=exp_insert.elements[:,0].max()
oldelements=exp_py.elements
exp_py.elements=np.concatenate((oldelements, [[maxinsindex+2, '*', int(maxindex), int(maxinsindex+1)], [maxinsindex+1, '/', int(maxinsindex), int(maxinsindex)]], exp_insert.elements), axis=0)
else:
operators=js.find_operators()[0]
document.getElementById("print-tree").innerHTML=operators
exp_insert=treeFactor(numpart, strpart)
minindex_py=int(exp_py.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
for x1 in exp_insert.elements:
x1[0]=x1[0]-maxindex_insert-3+minindex_py
if x1[2] is not None:
x1[2]=x1[2]-maxindex_insert-3+minindex_py
x1[3]=x1[3]-maxindex_insert-3+minindex_py
minindex_insert=int(exp_insert.elements[:,0].min())
maxindex_insert=int(exp_insert.elements[:,0].max())
pp=js.find_parent(selectedtop)
if exp_py.elements[exp_py.find_pointer(pp)][2]==selectedtop:
exp_py.elements[exp_py.find_pointer(pp)][2]=minindex_py-1
if exp_py.elements[exp_py.find_pointer(pp)][1]=='/':
exp_py.elements[exp_py.find_pointer(pp)][3]=minindex_py-1
else:
exp_py.elements[exp_py.find_pointer(pp)][3]=minindex_py-1
if exp_py.elements[exp_py.find_pointer(pp)][1]=='/':
exp_py.elements[exp_py.find_pointer(pp)][2]=minindex_py-1
newnode1=[int(minindex_py-1), '*', selectedtop, minindex_py-2]
newnode2=[int(minindex_py-2), '/', minindex_py-3, minindex_py-3]
oldtree=exp_py
exp_py.elements=np.concatenate((oldtree.elements,[newnode1, newnode2],exp_insert.elements), axis=0)
for x1 in exp_py.elements:
x1[0]=int(x1[0])
if x1[2] is not None:
x1[2]=int(x1[2])
x1[3]=int(x1[3])
document.getElementById("print-tree").innerHTML=exp_py.print_tree('o')
js.get_exp1(create_proxy(exp_py.elements))
js.get_printTree(create_proxy([exp_py.print_tree('r'), exp_py.print_tree('l')]))
js.set_answerMathField(create_proxy( exp_py.print_tree('l')))
js.document.getElementById("new-expression-btn").addEventListener("click", create_proxy(zero_expression))
js.document.getElementById("new-expression-btn").addEventListener("click", create_proxy(push_vars))
js.document.getElementById("new-expression-btn").addEventListener("click", create_proxy(show_expression))
js.document.getElementById("clear-selection-btn").addEventListener("click", create_proxy(clear_selection))
js.document.getElementById("clear-selection-btn").addEventListener("click", create_proxy(push_vars))
js.document.getElementById("clear-selection-btn").addEventListener("click", create_proxy(show_expression))
js.document.getElementById("show-btn").addEventListener("click", create_proxy(push_vars))
js.document.getElementById("show-btn").addEventListener("click", create_proxy(show_expression))
js.document.getElementById("add-btn").addEventListener("click", create_proxy(add_exp))
js.document.getElementById("multiply-btn").addEventListener("click", create_proxy(multiply_exp))
js.document.getElementById("divide-btn").addEventListener("click", create_proxy(divide_exp))
js.document.getElementById("tidy-btn").addEventListener("click", create_proxy(tidy_exp))
js.document.getElementById("expand-btn").addEventListener("click", create_proxy(expand_exp))
js.document.getElementById("factorise-btn").addEventListener("click", create_proxy(factorise_exp))
js.document.getElementById("cancel-btn").addEventListener("click", create_proxy(cancel_exp))
js.document.getElementById("add-constants-btn").addEventListener("click", create_proxy(add_constants_exp))
js.document.getElementById("multiply-constants-btn").addEventListener("click", create_proxy(multiply_constants_exp))
js.document.getElementById("add-expressions-btn").addEventListener("click", create_proxy(add_expressions_exp))