diff --git a/models/dimers random walk.xml b/models/dimers random walk.xml
index 7f5db43..2762fa4 100644
--- a/models/dimers random walk.xml
+++ b/models/dimers random walk.xml
@@ -102,6 +102,8 @@
+
+
@@ -117,7 +119,7 @@
+ parent="10" probability="1">
@@ -146,6 +148,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/models/newick_first b/models/newick_first
new file mode 100644
index 0000000..7479078
--- /dev/null
+++ b/models/newick_first
@@ -0,0 +1 @@
+('(b,(c,(d,(e,(f,g))h)i)a)')[0]
\ No newline at end of file
diff --git a/src/__pycache__/newick.cpython-39.pyc b/src/__pycache__/newick.cpython-39.pyc
new file mode 100644
index 0000000..db11a62
Binary files /dev/null and b/src/__pycache__/newick.cpython-39.pyc differ
diff --git a/src/__pycache__/rules_tree.cpython-39.pyc b/src/__pycache__/rules_tree.cpython-39.pyc
index 73566a2..c56fd18 100644
Binary files a/src/__pycache__/rules_tree.cpython-39.pyc and b/src/__pycache__/rules_tree.cpython-39.pyc differ
diff --git a/src/engine.py b/src/engine.py
new file mode 100644
index 0000000..8753f09
--- /dev/null
+++ b/src/engine.py
@@ -0,0 +1,248 @@
+# import measures.MeasuresManager
+# import rule.FormulasManager
+# import rule.FormulasManagerAccess
+# import session.ViewControls
+# import state.StateManager
+# import state.StateManagerLocal
+# import views.MODEL
+# import views.ViewsManagerAccess
+
+# @see MonoThread
+class Formula():
+ def getFormula():
+ return 0
+
+ def doActions():
+ pass
+
+
+class ViewControls():
+
+ def isDoSelected():
+ return True
+
+ def execDo():
+ pass
+
+
+class ViewsManagerAccess():
+ pass
+
+
+class StateManagerLocal():
+ def getReferenceOrientation_1():
+ pass
+
+
+class FormulasManager():
+ def iterateToFindAFormula():
+ return 1
+
+ def getFormula(formula_key):
+ return 0
+
+
+class MeasuresManager():
+ def startMeasuringAFormulaEffect(formula_key):
+ pass
+
+ def endMeasuringAFormulaEffect(formula_key):
+ pass
+
+
+class SingleTransition:
+ '''
+ SingleTransition is a loop with one interruption and two instructions:
+ if (session.MainView.isStartStopButtonSelected())
+ state.StateManagerLocal.chooseLocalOrigin(false)
+ new SingleTransition(true)
+ '''
+
+ is_done = False
+ elapsed = ''
+ present = 0
+ selected_formula = -1
+ undoStackSize = 100 # used by ViewControls (for image of the buffer state)
+ formula = [0, 1, 2]
+ x = []
+ y = []
+ z = []
+ o = [0, 1, 2]
+ DO_UNDO_REDO_comment = False
+
+ def __init__(self):
+ self.present = 0
+ # if (step_by_step) StateManagerLocal.circlePresentState()
+ if ViewControls.isDoSelected():
+ self.execute_do(self.prepare_do(False))
+ elif ViewControls.isUndoSelected():
+ SingleTransition.execute_undo(SingleTransition.prepare_undo(False))
+ elif ViewControls.isRedoSelected():
+ SingleTransition.execute_redo(SingleTransition.prepare_redo(False))
+ # if (ViewControls.undo_buffer < undoStackSize): do something
+ # ViewControls.setTimeBufferBar(ViewControls.undo_buffer)
+ # MainView.addElapsedTime() Clock should be independent from any view
+
+ def prepare_do(self, step_by_step) :
+ # ThreadsManager.addCycle() > nb_cycles ++ < no formula may be applied
+ selected_formula = FormulasManager.iterateToFindAFormula()
+ return selected_formula
+
+ def execute_do(self, formula_key):
+ # formula.doActions()
+ # print(" execute_do: formula key=" + formula_key +" ")
+ if formula_key < 0:
+ if StateManagerLocal.comment_origins:
+ print("execute_do failure: formula key=", formula_key)
+ return
+
+ MeasuresManager.startMeasuringAFormulaEffect(formula_key)
+ # print("execute_do "+ FormulasManager.formula.get(formula_key).name)
+ # TODO FormulasManager.getFormula().get(formula_key).doActions()
+ # for (i = 0 i < action.length i++): action[i].doAction ()
+ # StateManagerLocal.endRule(action_swap, action_name)}
+ MeasuresManager.endMeasuringAFormulaEffect(formula_key)
+ self.writePresentState(formula_key)
+ self.present += 1
+ if self.present == self.undoStackSize:
+ self.present = 0
+ # MainView.setStartStopButtonSelected(False)
+ # if (present == 1):
+ # MainView.setStartStopButtonSelected(False)
+ # out.println("MonoThread.execute_do > stop ! (present == 1)")
+ ViewControls.execDo()
+ # doRepaint()
+ if self.DO_UNDO_REDO_comment:
+ self.comment_do(formula_key)
+
+ def prepare_undo(self, step_by_step):
+ # MonoTest.present-- return MonoTest.f[MonoTest.present]
+ if (ViewControls.isUndoBufferEmpty()):
+ print("prepare_undo stop !")
+ # undo_buffer is always >= 0
+ else:
+ self.present -= 1
+ if self.present == -1:
+ self.present = self.undoStackSize - 1
+ ViewControls.execUndo()
+
+ self.formula_key = self.readPresentState(step_by_step)
+ # if (step_by_step) StateManagerLocal.circlePresentState()
+ return self.formula_key
+
+ def execute_undo(self, formula_key):
+ # formula.unDoActions() {for (i = 0 i < action.length i++) ...}
+ FormulasManager.getFormula().get(formula_key).unDoActions()
+ # for (i = 0 i < action.length i++) action[i].doAction ()
+ # StateManagerLocal.endRule(action_swap, action_name)
+ ViewControls.setRedoSelected()
+ # StateManagerLocal.circlePresentState()
+ # ThreadsManager.removeEfficientCycle() {nb_effective_cycles --}
+ self.doRepaint()
+ if self.DO_UNDO_REDO_comment:
+ self.comment_undo()
+
+ def prepare_redo(self, step_by_step):
+ # return MonoThread
+ # Test.f[MonoThreadTest.pStateManagerLocalresent]
+ self.formula_key = self.readPresentState(step_by_step)
+ # ThreadsManager.addEfficientCycle() # {nb_effective_cycles ++}
+ # if (step_by_step) StateManagerLocal.circlePresentState()
+ return self.formula_key
+
+ def execute_redo(self, formula_key):
+ # formula.doActions() {for (i = 0 i < action.length i++) ...}
+ # the redo_buffer is always >= 0
+ # (if the re_do buffer is empty, the re_do button is deactivated)
+ if not ViewControls.isRedoBufferEmpty():
+ FormulasManager.getFormula().get(formula_key).doActions()
+ # {for (i = 0 i < action.length i++) action[i].doAction()
+ # StateManagerLocal.endRule(action_swap, action_name)}
+ self.present += 1
+ if self.present == self.undoStackSize:
+ self.present = 0
+ ViewControls.execRedo()
+
+ ViewControls.setUndoSelected()
+ self.doRepaint()
+ if self.DO_UNDO_REDO_comment:
+ self.comment_redo()
+
+ def writePresentState(self, formula_key):
+ # x[present] = StateManagerLocal.local_space_origin_X ...
+ self.formula[self.present] = formula_key
+ self.o[self.present] = StateManagerLocal.getReferenceOrientation_1()
+ '''
+ switch(StateManager.space_dimension) { # no break in this switch
+ case THREE: z[present] = (byte) StateManagerLocal.local_space_origin_Z
+ case TWO: y[present] = (byte) StateManagerLocal.local_space_origin_Y
+ case ONE: x[present] = (byte) StateManagerLocal.local_space_origin_X
+ default: }
+ '''
+
+ def readPresentState(self, step_by_step):
+ # StateManagerLocal.local_space_origin_X = x [present] ...
+ '''
+ switch(StateManager.space_dimension) { # no break in this switch
+ case THREE : StateManagerLocal.local_space_origin_Z = z[present]
+ case TWO : StateManagerLocal.local_space_origin_Y = y[present]
+ case ONE : StateManagerLocal.local_space_origin_X = x[present]
+ default: }
+ '''
+ StateManagerLocal.setReferenceOrientation_1(self.o[self.present])
+ return self.formula[self.present]
+
+ def doRepaint(self):
+ # plus tard !
+ # ViewsManagerAccess.getView(MODEL.SPACE, "MonoThread.",
+ # "execute_do_undo_redo()").repaint()
+ pass
+
+ def comment_do(self, rank) :
+ if self.present == 0:
+ self.present = self.undoStackSize
+ print(" do -----> ", self.present,
+ " (", ViewControls.undo_buffer - 1,
+ "+1=", ViewControls.undo_buffer, " /",
+ ViewControls.redo_buffer,
+ " -", ViewControls.redo_buffer, ") xyzo (",
+ self.x[self.present - 1], ",",
+ self.y[self.present - 1], ",",
+ self.z[self.present - 1], ") ",
+ self.o[self.present - 1], " f=",
+ self.formula[self.present - 1])
+ if self.present == self.undoStackSize:
+ self.present = 0
+
+ def comment_undo(self):
+ # present ++ if (present == stack_size) present = 0
+ # This comment is triggered after present was decreased of one unit
+ print(" undo <--| ", self.present,
+ " (", (ViewControls.undo_buffer + 1),
+ "-1=", ViewControls.undo_buffer + " /",
+ ViewControls.redo_buffer - 1, "+1=",
+ ViewControls.redo_buffer, ") ", "xyzo (",
+ self.x[self.present], ",",
+ self.y[self.present], ",",
+ self.z[self.present], ") ",
+ self.o[self.present], " f=",
+ self.formula[self.present])
+
+ def comment_redo(self):
+ if self.present == 0:
+ self.present = self.undoStackSize
+ print(" redo |--> ", self.present,
+ " (" + (ViewControls.undo_buffer - 1),
+ "+1=" + ViewControls.undo_buffer + " /",
+ ViewControls.redo_buffer + 1, "-1=",
+ ViewControls.redo_buffer, ") xyzo (",
+ self.x[self.present - 1], ",",
+ self.y[self.present - 1], ",",
+ self.z[self.present - 1], ") ",
+ self.o[self.present - 1], " f=",
+ self.formula[self.present - 1])
+ if self.present == self.undoStackSize:
+ self.present = 0
+
+
+SingleTransition()
diff --git a/src/erreur.py b/src/erreur.py
new file mode 100644
index 0000000..f38f40a
--- /dev/null
+++ b/src/erreur.py
@@ -0,0 +1,18 @@
+class XXX:
+
+ present = 8
+
+ def __init__(self):
+ self.present = 0
+ print(self.present,
+ 'UnboundLocalError: local variable referenced before assignment')
+
+ def do_something(self):
+ # instance.present = 5
+ # self.present = 7
+ pass
+
+
+instance = XXX()
+instance.do_something()
+print(XXX.present, instance.present)
diff --git a/src/newick.py b/src/newick.py
new file mode 100644
index 0000000..9d9871d
--- /dev/null
+++ b/src/newick.py
@@ -0,0 +1,18 @@
+# https://evolution.genetics.washington.edu/phylip/newicktree.html
+# import io
+import newick
+# from newick import loads
+
+tree = newick.loads('(b,(c,(d,(e,(f,g))h)i)a)')[0]
+
+print(tree.ascii_art())
+'''
+from newick import loads
+
+newick.loads('[a comment](a,b)c;', strip_comments=True)[0].newick '(a,b)c'
+
+with io.open('../models/newick_first', encoding='utf8') as fp:
+ trees = loads(fp)
+ print(tree.ascii_art())
+ print(trees[0].name, [n.name for n in trees[0].descendants])
+'''
diff --git a/src/rules_tree.py b/src/rules_tree.py
index 691e921..5d92987 100644
--- a/src/rules_tree.py
+++ b/src/rules_tree.py
@@ -1,12 +1,13 @@
# https://anytree.readthedocs.io/en/latest/_modules/anytree/node/nodemixin.html
from anytree import NodeMixin, LevelOrderIter # , RenderTree
+# from newick import loads
import model
# TODO Contrôles de cohérence des données
# 1) node_id <> pas de doublons
# 2) tout node doit avoir un node_parent_id
# Process
-# 1) lors de l'adoption, le parent doit exister
+# 1) lors de l'adoption, le parent doit être une feuille et exister
class TreeNode(NodeMixin):
diff --git a/src/show_tree.py b/src/show_tree.py
deleted file mode 100644
index 5967f33..0000000
--- a/src/show_tree.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# from ete2 import Tree
-from anytree import RenderTree
-import rules_tree
-
-tree = rules_tree.get_tree()
-
-for pre, fill, node in RenderTree(tree):
- treestr = u"%s%s" % (pre, node.id)
- print(treestr.ljust(0))
-
-print('\ntype: ', type(tree))
-print('path: ', tree.path)
-print('children: ', tree.children)
-print('descendants[0]: ', tree.descendants[0])
-print(tree.depth, ' < depth')
-print(tree.is_leaf, ' < is_leaf')
-print(tree.is_root, ' < is_root')
-print(tree.height, ' < height')
-print(tree.parent, ' < parent')
-print(tree.ancestors, ' < ancestors')
-print(tree.anchestors, ' < anchestors')
-print(tree.siblings, ' < siblings')
-print(len(tree.leaves), ' < len(tree.leaves)')
-print(len(tree.path), ' < len(tree.path)\n')
-
-for pre, fill, node in RenderTree(tree):
- if node.path[len(node.path) - 1].is_leaf:
- print('at depth', len(node.path),
- 'is rule', node.path[len(node.path) - 1].parent_id,
- 'whose path (tracked by conditions weights) is:', end=' ')
- for i in range(0, len(node.path) - 1):
- print(node.path[i].weight, ',', end='')
- print(' transition', node.path[len(node.path) - 1].id)
-
-print('\nNext step: single rule extraction from tree.',
- ' 😃️\nand learn how to use the Newick format.')
-# http://etetoolkit.org/docs/2.3/tutorial/tutorial_trees.html
diff --git a/src/view_rule.py b/src/view_rule.py
new file mode 100644
index 0000000..3ae7078
--- /dev/null
+++ b/src/view_rule.py
@@ -0,0 +1,29 @@
+from anytree import RenderTree
+import rules_tree
+
+tree = rules_tree.get_tree()
+
+any_node = tree.children[1].children[0]
+print('\nproperties of node: ', any_node.id)
+print('type: ', type(any_node))
+print('len(path): ', len(any_node.path))
+print('nb children: ', len(any_node.children))
+# print('descendants[0]: ', any_node.descendants[0])
+print('depth ', any_node.depth)
+print('is_leaf ', any_node.is_leaf)
+print('is_root ', any_node.is_root)
+print('height ', any_node.height)
+print('parent ', any_node.parent)
+print('nb ancestors ', len(any_node.ancestors))
+print('nb anchestors ', len(any_node.anchestors))
+print('siblings ', any_node.siblings)
+print('nb (subtree.leaves) ', len(any_node.leaves), '\n')
+
+for pre, fill, node in RenderTree(tree):
+ if node.path[len(node.path) - 1].is_leaf:
+ print('at depth', len(node.path),
+ 'is rule', node.path[len(node.path) - 1].parent_id,
+ 'whose path (tracked by conditions weights) is:', end=' ')
+ for i in range(0, len(node.path) - 1):
+ print(node.path[i].weight, ',', end='')
+ print(' transition is:', node.path[len(node.path) - 1].id)
diff --git a/src/view_tree.py b/src/view_tree.py
new file mode 100644
index 0000000..5d76cf2
--- /dev/null
+++ b/src/view_tree.py
@@ -0,0 +1,40 @@
+# from ete2 import Tree
+from anytree import RenderTree
+import rules_tree
+
+tree = rules_tree.get_tree()
+
+for pre, fill, node in RenderTree(tree):
+ treestr = u"%s%s" % (pre, node.id)
+ print(treestr.ljust(0))
+'''
+any_node = tree.children[1].children[0].children[0]
+print('\nproperties of node: ', any_node.id)
+print('type: ', type(any_node))
+print('len(path): ', len(any_node.path))
+print('nb children: ', len(any_node.children))
+print('descendants[0]: ', any_node.descendants[0])
+print('depth ', any_node.depth)
+print('is_leaf ', any_node.is_leaf)
+print('is_root ', any_node.is_root)
+print('height ', any_node.height)
+print('parent ', any_node.parent)
+print('nb ancestors ', len(any_node.ancestors))
+print('nb anchestors ', len(any_node.anchestors))
+print('siblings ', any_node.siblings)
+print('nb (subtree.leaves) ', len(any_node.leaves), '\n')
+'''
+'''
+print()
+for pre, fill, node in RenderTree(tree):
+ if node.path[len(node.path) - 1].is_leaf:
+ print('at depth', len(node.path),
+ 'is rule', node.path[len(node.path) - 1].parent_id,
+ 'whose path (tracked by conditions weights) is:', end=' ')
+ for i in range(0, len(node.path) - 1):
+ print(node.path[i].weight, ',', end='')
+ print(' transition is:', node.path[len(node.path) - 1].id)
+
+print('\nNext step: learn how to use the Newick format.')
+# http://etetoolkit.org/docs/2.3/tutorial/tutorial_trees.html
+'''
diff --git a/ui/#GLArea.glade# b/ui/#GLArea.glade#
new file mode 100644
index 0000000..cb1e5ed
--- /dev/null
+++ b/ui/#GLArea.glade#
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
diff --git a/ui/GLArea.glade b/ui/GLArea.glade
index f3e9190..548069e 100644
--- a/ui/GLArea.glade
+++ b/ui/GLArea.glade
@@ -6,10 +6,13 @@
True
True
+ False
+ False
center
- 800
- 600
+ 1860
+ 160
static
+ True
tout ce qui est sous la 'header bar'
@@ -24,21 +27,7 @@
True
vertical
-
- True
- False
-
-
- True
- False
- espace 1D projet.jpg
-
-
-
-
- True
- True
-
+
diff --git a/ui/GLArea.glade~ b/ui/GLArea.glade~
new file mode 100644
index 0000000..d781bc7
--- /dev/null
+++ b/ui/GLArea.glade~
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+ True
+ True
+ False
+ False
+ center
+ 1860
+ 160
+ static
+ True
+
+
+ tout ce qui est sous la 'header bar'
+ True
+ True
+ vertical
+
+
+ Image 1D + contrôles
+ 100
+ True
+ True
+ vertical
+
+
+ True
+ False
+ 3
+ 3
+ False
+ False
+ immediate
+ natural
+ natural
+ none
+
+
+ True
+ False
+ espace 1D projet.jpg
+
+
+
+
+ True
+ True
+
+
+
+
+ 18
+ True
+ False
+ center
+
+
+ Zoom
+ True
+ True
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ Filtres
+ True
+ True
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ Apparences
+ True
+ True
+ True
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ True
+
+
+
+
+ False
+ True
+
+
+
+
+ tout ce qui est sous l'image 1D et ses contrôles
+ True
+ True
+
+
+ transitions
+ 700
+ True
+ True
+ True
+
+
+ False
+ True
+
+
+
+
+ objets
+ True
+ True
+ True
+
+
+ True
+ True
+
+
+
+
+ True
+ True
+
+
+
+
+
+
+
+
+