Commit ca0b7423 authored by Francois Mares's avatar Francois Mares
Browse files

upgrade NewObject

parent 0bb248cb
0
\ No newline at end of file
1
\ No newline at end of file
1
\ No newline at end of file
1
\ No newline at end of file
1
\ No newline at end of file
1
\ No newline at end of file
import pandas as pd import pandas as pd
from enum import Enum, unique from enum import Enum, unique
from itertools import product
from concurrent.futures import ThreadPoolExecutor
from ModelCallable import ModelCallable from ModelCallable import ModelCallable
...@@ -16,6 +18,19 @@ class ModelObjects(Enum): ...@@ -16,6 +18,19 @@ class ModelObjects(Enum):
It="Intéraction" It="Intéraction"
CP="Champ Perceptif" CP="Champ Perceptif"
def get(obj):
t=type(obj)
if t==GrapheDeComposition:
return ModelObjects.GC
elif t==Categorie:
return ModelObjects.CI
elif t==Interaction:
return ModelObjects.It
elif t==ChampPerceptif:
return ModelObjects.CP
else:
return None
class Model: class Model:
""" """
Contient tous les objets construits. Contient tous les objets construits.
...@@ -45,11 +60,32 @@ class Model: ...@@ -45,11 +60,32 @@ class Model:
self._data=self._data.append(newData, ignore_index=True) self._data=self._data.append(newData, ignore_index=True)
self.informObjectsAdded(list(range(i, self._data.index[-1]+1))) self.informObjectsAdded(list(range(i, self._data.index[-1]+1)))
def createGrapheDeComposition(self, objets:set = set(), morphismes:set=set(), nom:str = None): def createGrapheDeComposition(self, objets:set = set(), morphismes:set=set(), identifications:set=set(), nom:str = None):
"""
From str
"""
gc=GC(objets=objets, nom=nom) gc=GC(objets=objets, nom=nom)
self.addObject(gc) self.addObject(gc)
gc|= objets
gc|= morphismes # morphismes
dic={str(x[2]):MGC(x[0],x[1],x[2]) for x in morphismes}
gc|= list(dic.values())
# identifications
# vérifier que les morphismes existent
for x in identifications:
x[0]=[dic.get(m) for m in x[0]]
x[1]=[dic.get(m) for m in x[1]]
if (None in x[0]) or (None in x[1]):
print(f"WARNING: {x} n'est pas une identification valide.")
else:
compoG=x[0][0]
for m in x[0][1:]:
compoG @=m
compoD=x[1][0]
for m in x[1][1:]:
compoD @=m
MGC.identifier_morphismes(compoG,compoD)
""" """
GETTERS GETTERS
...@@ -90,6 +126,97 @@ class Model: ...@@ -90,6 +126,97 @@ class Model:
for rdm in self._registeredModelCallable: for rdm in self._registeredModelCallable:
rdm.informObjectsDeleted(uids) rdm.informObjectsDeleted(uids)
"""
Graphviz
"""
def exporterGraphviz(self, uids):
data=self.getObject(uids)
with ThreadPoolExecutor(max_workers=len(data)) as executor:
for index, row in data.iterrows():
obj=row["object"]
if callable(getattr(obj,"transformer_graphviz",None)):
executor.submit(obj.transformer_graphviz())
class Description:
_obj:object=None
_str:str=""
def __init__(self, obj:object, *args, **kwargs):
self._obj=obj
with ThreadPoolExecutor(max_workers=1) as executor:
self._str = executor.submit(self.generer).result()
def __str__(self):
return self._str
def generer(self):
mo=ModelObjects.get(self._obj)
if mo==ModelObjects.GC:
return self._genererDescriptionCategorie()
else:
return str(self._obj)
def _genererDescriptionCategorie(self, afficher_identites:bool = True, complet:bool = True, limite_fleches:int = 30):
"""
`complet` indique s'il faut afficher toutes les flèches ou seulement les flèches élémentaires.
`limite_fleches` est le nombre maximal de flèches entre deux objets qu'on s'autorise à afficher.
"""
descr=""
if self._obj.nom:
descr+=self._obj.nom
# objets
descr+=" {"
print(self)
for o in self._obj.objets:
descr+=str(o)+","
descr=descr[:-1]+"}"
# flesches
fleches_elem = set(self._obj[self._obj.objets,self._obj.objets])
if complet:
func = lambda x,y : self._obj({x},{y})
else:
func = lambda x,y : self._obj[{x},{y}]
fleches_elementaires=[]
fleches_non_elementaires=[]
for source,cible in product(self._obj.objets,repeat=2):
nb_fleches = 0
for fleche in func(source,cible):
if afficher_identites or not fleche.is_identite:
if fleche.source not in self._obj.objets:
raise Exception("Source d'une fleche pas dans les objets de la categorie.")
if fleche.cible not in self._obj.objets:
raise Exception("Source d'une fleche pas dans les objets de la categorie.")
if len({obj for obj in self._obj.objets if obj == fleche.source}) > 1:
raise Exception("Plus d'un objet de la catégorie est source de la fleche.")
if len({obj for obj in self._obj.objets if obj == fleche.cible}) > 1:
raise Exception("Plus d'un objet de la catégorie est cible de la fleche.")
#permet d'avoir toujours un objet de la catégorie comme source
source = {obj for obj in self._obj.objets if obj == fleche.source}.pop()
#permet d'avoir toujours un objet de la catégorie comme cible
cible = {obj for obj in self._obj.objets if obj == fleche.cible}.pop()
# descriptions
if fleche in fleches_elem:
fleches_elementaires.append(f"({str(source)},{str(cible)},{str(fleche)})")
else:
fleches_non_elementaires.append(f"({str(source)},{str(cible)},{str(fleche)})")
nb_fleches += 1
if nb_fleches > limite_fleches:
if WARNING_LIMITE_FLECHES_ATTEINTE:
print("Warning : limite fleches entre "+str(source)+" et "+str(cible)+" atteinte.")
break
descr+=" flèches: "
for f in fleches_non_elementaires:
descr+=f
for f in fleches_elementaires:
descr+=f
return descr
......
...@@ -135,12 +135,7 @@ class MainWindow: ...@@ -135,12 +135,7 @@ class MainWindow:
def exporterGraphviz(self): def exporterGraphviz(self):
uids=self._objFrame.getSelectedObjects() uids=self._objFrame.getSelectedObjects()
data=self._controller.getModel().getObject(uids) self._controller.getModel().exporterGraphviz(uids)
for index, row in data.iterrows():
obj=row["object"]
if callable(getattr(obj,"transformer_graphviz",None)):
obj.transformer_graphviz()
class ExportAsDialog(Toplevel): class ExportAsDialog(Toplevel):
......
...@@ -65,6 +65,7 @@ class BuildObjectFrame(Frame): ...@@ -65,6 +65,7 @@ class BuildObjectFrame(Frame):
_validateButton=None _validateButton=None
_textObjects=None _textObjects=None
_textMorphismes=None _textMorphismes=None
_textIdentifications=None
def __init__(self, parent, model, obj:ModelObjects, *args, **kwargs): def __init__(self, parent, model, obj:ModelObjects, *args, **kwargs):
assert model and parent assert model and parent
...@@ -85,6 +86,7 @@ class BuildObjectFrame(Frame): ...@@ -85,6 +86,7 @@ class BuildObjectFrame(Frame):
self.rowconfigure(0, weight=1, minsize=20) self.rowconfigure(0, weight=1, minsize=20)
self.rowconfigure(1, weight=1, minsize=20) self.rowconfigure(1, weight=1, minsize=20)
self.rowconfigure(2, weight=1, minsize=20) self.rowconfigure(2, weight=1, minsize=20)
self.rowconfigure(3, weight=1, minsize=20)
# Objects # Objects
self._textObjects=ObjectLabelText(self) self._textObjects=ObjectLabelText(self)
...@@ -94,10 +96,15 @@ class BuildObjectFrame(Frame): ...@@ -94,10 +96,15 @@ class BuildObjectFrame(Frame):
self._textMorphismes=MorphismeLabelText(self) self._textMorphismes=MorphismeLabelText(self)
self._textMorphismes.grid(row=2, column=0) self._textMorphismes.grid(row=2, column=0)
# Identifications
self._textIdentifications=IdentificationLabelText(self)
self._textIdentifications.grid(row=3, column=0)
# Button # Button
def generate(): def generate():
self._model.createGrapheDeComposition(objets=self._textObjects.getObjectsList(), self._model.createGrapheDeComposition(objets=self._textObjects.getList(),
morphismes=self._textMorphismes.getMorphismesList(), morphismes=self._textMorphismes.getList(),
identifications=self._textIdentifications.getList(),
nom = None) nom = None)
self._validateButton=Button(self, text="Générer", command=generate) self._validateButton=Button(self, text="Générer", command=generate)
self._validateButton.grid(row=0, column=0, sticky="e") self._validateButton.grid(row=0, column=0, sticky="e")
...@@ -126,7 +133,7 @@ class LabelText(LabelFrame): ...@@ -126,7 +133,7 @@ class LabelText(LabelFrame):
if self._description: if self._description:
Label(self, text=self._description, anchor="w").grid(row=0, column=0, sticky="new") Label(self, text=self._description, anchor="w").grid(row=0, column=0, sticky="new")
self._text=Text(self) self._text=Text(self, height=3, width=20)
self._text.grid(row=1, column=0, sticky="nw") self._text.grid(row=1, column=0, sticky="nw")
self._scrollbarY=Scrollbar(self, orient =VERTICAL) self._scrollbarY=Scrollbar(self, orient =VERTICAL)
...@@ -143,7 +150,7 @@ class ObjectLabelText(LabelText): ...@@ -143,7 +150,7 @@ class ObjectLabelText(LabelText):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
LabelText .__init__(self, parent, name="Objets", description="ex: 1,2,3...", *args, **kwargs) LabelText .__init__(self, parent, name="Objets", description="ex: 1,2,3...", *args, **kwargs)
def getObjectsList(self): def getList(self):
return [x for x in split('[,\n]', self.getText()) if x] return [x for x in split('[,\n]', self.getText()) if x]
class MorphismeLabelText(LabelText): class MorphismeLabelText(LabelText):
...@@ -151,16 +158,30 @@ class MorphismeLabelText(LabelText): ...@@ -151,16 +158,30 @@ class MorphismeLabelText(LabelText):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
LabelText .__init__(self, parent, name="Morphismes", description="ex: (1,2,f)(2,3,g)...", *args, **kwargs) LabelText .__init__(self, parent, name="Morphismes", description="ex: (1,2,f)(2,3,g)...", *args, **kwargs)
def getMorphismesList(self): def getList(self):
# (...) # (...)
tuples=[x[1:-1] for x in findall("\([^\(\)]+\)", self.getText()) if x] tuples=[x[1:-1] for x in findall("\([^\(\)]+\)", self.getText()) if x]
# ,\n # ,\n
tuplesSplited=[[x for x in split('[,\n]', t) if x] for t in tuples] tuplesSplited=[[x for x in split('[,\n]', t) if x] for t in tuples]
# 3 chaînes # 3 éléments
morphismesDescription=[x for x in tuplesSplited if len(x)==3] morphismesDescription=[x for x in tuplesSplited if len(x)==3]
# Création des morphismes # Création des morphismes
return [MGC(x[0],x[1],x[2]) for x in morphismesDescription] return morphismesDescription
class IdentificationLabelText(LabelText):
def __init__(self, parent, *args, **kwargs):
LabelText .__init__(self, parent, name="Identifications", description="ex: (g@f,h)(h@h,h)...", *args, **kwargs)
def getList(self):
# (...)
tuples=[x[1:-1] for x in findall("\([^\(\)]+\)", self.getText()) if x]
# ,\n
tuplesSplited=[[x for x in split('[,\n]', t) if x] for t in tuples]
# 2 éléments
identifications=[[split('[@]', x[0]),split('[@]', x[1])] for x in tuplesSplited if len(x)==2]
# Création des identifications
return identifications
......
...@@ -2,15 +2,17 @@ ...@@ -2,15 +2,17 @@
Définition de l'espace de droite Définition de l'espace de droite
""" """
from pandas import DataFrame from pandas import DataFrame
from tkinter import TOP, X, NO, W, Y, YES, BOTH, RIGHT, VERTICAL, \
Frame, Label
from tkinter.ttk import Treeview, Style, Scrollbar
from ModelCallable import ModelCallable from ModelCallable import ModelCallable
from Model import Description
from tk.InformFrame import InformFrame from tk.InformFrame import InformFrame
from tk.Factory import * from tk.Factory import *
from tkinter import TOP, X, NO, W, Y, YES, BOTH, RIGHT, VERTICAL, \
Frame, Label
from tkinter.ttk import Treeview, Style, Scrollbar
class ObjetsFrame(Frame, ModelCallable): class ObjetsFrame(Frame, ModelCallable):
...@@ -52,8 +54,8 @@ class ObjetsFrame(Frame, ModelCallable): ...@@ -52,8 +54,8 @@ class ObjetsFrame(Frame, ModelCallable):
self._tree["columns"]=("class","description") self._tree["columns"]=("class","description")
self._tree.column("#0", width=100, minwidth=15, stretch=False) self._tree.column("#0", width=100, minwidth=15, stretch=False)
self._tree.column("class", width=100, minwidth=100, stretch=True) self._tree.column("class", width=50, stretch=False)
self._tree.column("description", width=100, minwidth=50, stretch=False) self._tree.column("description", width=200, minwidth=80, stretch=True)
self._tree.heading("#0",text="UID",anchor=W) self._tree.heading("#0",text="UID",anchor=W)
self._tree.heading("class", text="Classe",anchor=W) self._tree.heading("class", text="Classe",anchor=W)
...@@ -115,7 +117,7 @@ class ObjetsFrame(Frame, ModelCallable): ...@@ -115,7 +117,7 @@ class ObjetsFrame(Frame, ModelCallable):
self._folders[folder]=f self._folders[folder]=f
objects=(df['object'][df['class']==folder]).sort_index(ascending=True) objects=(df['object'][df['class']==folder]).sort_index(ascending=True)
for uid, obj in objects.items(): for uid, obj in objects.items():
self._tree.insert(parent=f, iid=uid, index="end", text=uid, values=(folder, obj)) self._tree.insert(parent=f, iid=uid, index="end", text=uid, values=(folder, Description(obj)))
def addObject(self, uid, obj:object): def addObject(self, uid, obj:object):
class_name=type(obj).__name__ class_name=type(obj).__name__
...@@ -123,11 +125,12 @@ class ObjetsFrame(Frame, ModelCallable): ...@@ -123,11 +125,12 @@ class ObjetsFrame(Frame, ModelCallable):
if not f: if not f:
f=self._tree.insert(parent="", index="end", text=class_name) f=self._tree.insert(parent="", index="end", text=class_name)
self._folders[class_name]=f self._folders[class_name]=f
self._tree.insert(parent=f, iid=uid, index="end", text=uid, values=(class_name, obj)) self._tree.insert(parent=f, iid=uid, index="end", text=uid, values=(class_name, Description(obj)))
def deleteObject(self, uid): def deleteObject(self, uid):
self._tree.delete(self._tree.item(uid)) self._tree.delete(self._tree.item(uid))
""" """
BIND FUNCTIONS BIND FUNCTIONS
""" """
...@@ -152,3 +155,4 @@ class ObjetsFrame(Frame, ModelCallable): ...@@ -152,3 +155,4 @@ class ObjetsFrame(Frame, ModelCallable):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment