diff --git a/huffman_py/gui/InputDialog.py b/huffman_py/gui/InputDialog.py index aead471..5fd759d 100644 --- a/huffman_py/gui/InputDialog.py +++ b/huffman_py/gui/InputDialog.py @@ -18,23 +18,23 @@ from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import * class InputDialog(QDialog): - def __init__(self, texte1, texte2, thirdBox = False, texte3=None, parent=None): + def __init__(self, text1, text2, thirdBox = False, text3=None, parent=None): super().__init__(parent) - self.setWindowTitle("données") + self.setWindowTitle("Input data") self.box1 = QLineEdit(self) self.box2 = QLineEdit(self) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self); layout = QFormLayout(self) - layout.addRow(texte1, self.box1) - layout.addRow(texte2, self.box2) + layout.addRow(text1, self.box1) + layout.addRow(text2, self.box2) self.thirdBox = thirdBox if self.thirdBox: self.box3 = QLineEdit(self) - layout.addRow(texte3, self.box3) + layout.addRow(text3, self.box3) layout.addWidget(buttonBox) diff --git a/huffman_py/gui/Ui_MainWindow.py b/huffman_py/gui/Ui_MainWindow.py index 88051d2..501d1b4 100644 --- a/huffman_py/gui/Ui_MainWindow.py +++ b/huffman_py/gui/Ui_MainWindow.py @@ -23,10 +23,10 @@ from PyQt5.QtCore import * import os, json, sys from huffman_py.gui.generate_graph import * -from huffman_py.fonctions.decode import * -from huffman_py.fonctions.encode import * +from huffman_py.functions.decode import * +from huffman_py.functions.encode import * from huffman_py.gui.InputDialog import * -from huffman_py.fonctions.ifFileGetContent import * +from huffman_py.functions.ifFileGetContent import * from huffman_py.gui.messageBox import * @@ -41,14 +41,14 @@ class Ui_MainWindow(QWidget): self.gridLayout = QGridLayout(self.centralwidget) self.gridLayout.setObjectName(u"gridLayout") - # widget pour attacher le graphe/texte + # widget to attach graph/text self.widget = QWidget(self.centralwidget) self.widget.setObjectName(u"widget") self.widget.setMinimumSize(QSize(10, 10)) self.gridLayout.addWidget(self.widget, 1, 0, 1, 1) - # widget_2 pour attacher les boutons + # widget_2 to attach buttons self.widget_2 = QWidget(self.centralwidget) self.widget_2.setObjectName(u"widget_2") self.widget_2.setMaximumSize(QSize(4000, 50)) @@ -61,57 +61,57 @@ class Ui_MainWindow(QWidget): self.retranslateUi(MainWindow) - # grille pour les widget texte ou svg + # text/svg widget grid self.gridLayout_main = QGridLayout(self.widget) self.gridLayout_main.setObjectName(u"gridLayout_main") - # les widgets en question + # text/svg widgets ##### - # graphe de l'arbre + # svg (tree graph) self.viewer = QtSvg.QSvgWidget() self.gridLayout_main.addWidget(self.viewer,0, 0, 1, 1) ##### - # texte - self.texte = QTextEdit() - self.texte.setReadOnly(True) - self.gridLayout_main.addWidget(self.texte,1, 0, 1, 1) + # text + self.text = QTextEdit() + self.text.setReadOnly(True) + self.gridLayout_main.addWidget(self.text,1, 0, 1, 1) - # on cache pour le moment les widget, on les affichera quand on en aura besoin + # hide widgets for now self.viewer.setVisible(False) - self.texte.setVisible(False) + self.text.setVisible(False) - # éléments de grid 2 - # boutons + # grid2 + # buttons ###################### self.gridLayout_2 = QGridLayout(self.widget_2) self.gridLayout_2.setObjectName(u"gridLayout_2") ##### - # push button encodage + # push button encoding self.pushButton_encode = QPushButton(self.widget_2) self.pushButton_encode.setObjectName(u"pushButton") self.gridLayout_2.addWidget(self.pushButton_encode, 1, 0, 1, 1) - self.pushButton_encode.setText(QCoreApplication.translate("MainWindow", u"encoder", None)) + self.pushButton_encode.setText(QCoreApplication.translate("MainWindow", u"encode", None)) - # fonction du bouton + # button function self.pushButton_encode.clicked.connect(self.showDialogEncoder) ##### - # push button décodage + # push button decoding self.pushButton_decode = QPushButton(self.widget_2) self.pushButton_decode.setObjectName(u"pushButton_decode") self.gridLayout_2.addWidget(self.pushButton_decode, 1, 1, 1, 1) - self.pushButton_decode.setText(QCoreApplication.translate("MainWindow", u"décoder", None)) + self.pushButton_decode.setText(QCoreApplication.translate("MainWindow", u"decode", None)) - # fonction du bouton - self.pushButton_decode.clicked.connect(self.showDialogDecoder) + # button function + self.pushButton_decode.clicked.connect(self.showDialogDecode) ##### @@ -121,10 +121,10 @@ class Ui_MainWindow(QWidget): self.gridLayout_2.addWidget(self.pushButton_encodeToFile, 1, 2, 1, 1) - self.pushButton_encodeToFile.setText(QCoreApplication.translate("MainWindow", u"encoder vers fichier", None)) + self.pushButton_encodeToFile.setText(QCoreApplication.translate("MainWindow", u"encode to file", None)) - # fonction du bouton - self.pushButton_encodeToFile.clicked.connect(self.showDialogEncoderFichier) + # button function + self.pushButton_encodeToFile.clicked.connect(self.showDialogEncodeToFile) ##### @@ -134,134 +134,133 @@ class Ui_MainWindow(QWidget): self.gridLayout_2.addWidget(self.pushButton_decodeToFile, 1, 3, 1, 1) - self.pushButton_decodeToFile.setText(QCoreApplication.translate("MainWindow", u"décoder vers fichier", None)) + self.pushButton_decodeToFile.setText(QCoreApplication.translate("MainWindow", u"decode to file", None)) - # fonction du bouton - self.pushButton_decodeToFile.clicked.connect(self.showDialogDecoderFichier) + # button function + self.pushButton_decodeToFile.clicked.connect(self.showDialogDecodeToFile) - ##### fin boutons + ##### end buttons - # lancement d'une fonction avant la fermeture + # function on exit qApp.aboutToQuit.connect(self.closeEvent) ###### - # fonctions des boutons + # button functions def showDialogEncoder(self): - '''affiche le dialogue pour encoder un texte (chemin vers fichier accepté) et affiche l'arbre correspondant''' - text, ok = QInputDialog.getText(self, 'données', 'entrez le texte') - text = ifFileGetContent(text) + '''dialog to encode a text, path to file allowed, will show a tree''' + text_input, ok = QInputDialog.getText(self, 'Input', 'Text to encode') + text = ifFileGetContent(text_input) if ok and len(text) > 0: the_data = (str(text)) print(the_data) - encoding, racine, _ = huffman_encode(the_data) + encoding, root, _ = huffman_encode(the_data) print("Encoded output", encoding) - print("Decoded Output", huffman_decode(encoding, racine)) + print("Decoded Output", huffman_decode(encoding, root)) - #générer l'arbre à afficher (le .svg) - generate_graph(racine) + # generate tree svg + generate_graph(root) - # rafraichir l'affichage de l'arbre + # refresh output self.viewer.load('tree.svg') self.viewer.update() - # on affiche le widget contenant l'arbre (et on affiche le texte encodé, dans un petit espace de préférence) + # show tree (and encoded text in a small box) self.viewer.setVisible(True) - self.texte.setText(encoding) - self.texte.setMaximumSize(QSize(4000, 50)) - self.texte.setVisible(True) + self.text.setText(encoding) + self.text.setMaximumSize(QSize(4000, 50)) + self.text.setVisible(True) - def showDialogDecoder(self): - '''affiche le dialogue pour décoder un texte encodé avec ses codes (chemins vers fichiers acceptés)''' - dialog = InputDialog("binaire","Dict {lettre:code} JSON-formatted") + def showDialogDecode(self): + '''dialog to decode a text with its dictionary, will show decoded text, path to files allowed''' + dialog = InputDialog("binary","Dict {char:code} JSON-formatted") if dialog.exec(): data = dialog.getInputs() - binaire = ifFileGetContent(data[0]) + binary = ifFileGetContent(data[0]) - if len(binaire)>0 and len(data[1])>0: + if len(binary)>0 and len(data[1])>0: try: - dico = json.loads(ifFileGetContent(data[1])) + dict = json.loads(ifFileGetContent(data[1])) except ValueError: - create_msg_box("Impossible de lire le dictionnaire fourni, est-ce bien un dictionnaire python formatté en JSON?","Dictionnaire invalide") + create_msg_box("Can't read dictionary, is it JSON-formatted?","Invalid dictionary") return 0 try: - text = decode_from_dico(binaire, dico) + text = decode_from_dict(binary, dict) except ValueError: - create_msg_box("Impossible de décoder le texte, est-ce bien le dictionnaire correspondant à ce texte encodé?","Erreur décodage") + create_msg_box("Can't decode text, is it the right dictionary?","decoding error") return 0 except TypeError: - create_msg_box("Impossible d'utiliser le texte fourni, est-ce bien un texte encodé en binaire?","Erreur entrée") + create_msg_box("Can't use text in input, is it a binary?","Input error") return 0 - # on remplace le contenu du widget texte par le texte obtenu en décodant - self.texte.setText(text) - self.texte.setMaximumSize(QSize(4000, 4000)) + # replace text widget content with decoded text + self.text.setText(text) + self.text.setMaximumSize(QSize(4000, 4000)) - # on affiche le widget contenant le texte (et on cache l'arbre) + # show text widget (and hide tree) self.viewer.setVisible(False) - self.texte.setVisible(True) + self.text.setVisible(True) - def showDialogEncoderFichier(self): - '''affiche le dialogue pour encoder un texte (chemin vers fichier accepté) et crée 2 fichiers au chemin spécifié (un raw avec le texte encode et un json avec le dictionnaire des codes)''' - dialog = InputDialog("texte","chemin vers fichier") + def showDialogEncodeToFile(self): + '''Dialog to encode a text (path allowed), create a path.raw file with encoded text and a path.json file with corresponding dictionary''' + dialog = InputDialog("text","path to file") if dialog.exec(): data = dialog.getInputs() - texte = ifFileGetContent(data[0]) - if len(data[1])>0 and len(texte)>0: + text = ifFileGetContent(data[0]) + if len(data[1])>0 and len(text)>0: try: with open(data[1]+'.raw','w') as fd_bin, open(data[1]+'.json','w') as fd_dic: - #encoding, _, dico = huffman_encode(data[0]) - encoding, _, dico = huffman_encode(texte) - json.dump(dico,fd_dic) + encoding, _, dict = huffman_encode(text) + json.dump(dict,fd_dic) fd_bin.write(encoding) except FileNotFoundError: - create_msg_box("Le chemin est invalide, est-ce que le dossier dans lequel créer le fichier existe?","Erreur entrée") + create_msg_box("Invalid path, does this directory exist?","Input error") - def showDialogDecoderFichier(self): - '''affiche le dialogue pour décoder un texte encodé avec ses codes (chemins vers fichiers acceptés), écrit le résultat dans le fichier donné en argument''' - dialog = InputDialog("texte","Dict {lettre:code} JSON-formatted", texte3 = "chemin vers fichier", thirdBox = True) + def showDialogDecodeToFile(self): + '''Dialog to decode a binary (paths accepted for both dictionary and binary) and create a file with decoded text''' + dialog = InputDialog("text","Dict {lettre:code} JSON-formatted", text3 = "path to file", thirdBox = True) if dialog.exec(): data = dialog.getInputs() - binaire = ifFileGetContent(data[0]) + binary = ifFileGetContent(data[0]) - if len(binaire)>0 and len(data[1])>0: + if len(binary)>0 and len(data[1])>0: try: - dico = json.loads(ifFileGetContent(data[1])) + dict = json.loads(ifFileGetContent(data[1])) except ValueError: - create_msg_box("Impossible de lire le dictionnaire fourni, est-ce bien un dictionnaire python formatté en JSON?","Dictionnaire invalide") + create_msg_box("Can't read dictionary, is it JSON-formatted?","Invalid dictionary") return 0 try: - texte = decode_from_dico(binaire, dico) + text = decode_from_dict(binary, dict) except ValueError: - create_msg_box("Impossible de décoder le texte, est-ce bien le dictionnaire correspondant à ce texte encodé?","Erreur décodage") + create_msg_box("Can't decode text, is it the right dictionary?","decoding error") return 0 except TypeError: - create_msg_box("Impossible d'utiliser le texte fourni, est-ce bien un texte encodé en binaire?","Erreur entrée") + create_msg_box("Can't use text in input, is it a binary?","Input error") return 0 try: with open(data[2],'w') as fd: - fd.write(texte) + fd.write(text) except FileNotFoundError: - create_msg_box("Le chemin est invalide, est-ce que le dossier dans lequel créer le fichier existe?","Erreur entrée") + create_msg_box("Invalid path, does this directory exist?","Input error") - ##### fin fonctions des boutons + ##### end button functions def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(QCoreApplication.translate("Huffman.py", u"Huffman.py", None)) def closeEvent(self): - # supprimer le fichier du graphe avant de fermer le programme + # delete graph files before exiting try: os.unlink('./tree.gv') os.unlink('./tree.svg') except: - # si l'utilisateur avait ouvert le programme mais pas généré d'arbre + # if user didn't generate a tree pass print('exit') sys.exit(0) diff --git a/huffman_py/gui/generate_graph.py b/huffman_py/gui/generate_graph.py index 6fb9ebe..e913281 100644 --- a/huffman_py/gui/generate_graph.py +++ b/huffman_py/gui/generate_graph.py @@ -16,10 +16,8 @@ # along with this program. If not, see . # from huffman_py.gui.generate_node import * -#le fichier generate_node.py -def generate_graph(racine): +def generate_graph(root): G = graphviz.Digraph(format='svg') - generate_node(G, racine) + generate_node(G, root) G.render(outfile="tree.svg",overwrite_source=True) - #on peut ensuite intégrer l'arbre dans QT diff --git a/huffman_py/gui/generate_node.py b/huffman_py/gui/generate_node.py index 0c52ef7..41deea9 100644 --- a/huffman_py/gui/generate_node.py +++ b/huffman_py/gui/generate_node.py @@ -17,20 +17,20 @@ # import graphviz -def generate_node(graph, sommet, father = None): - if sommet.left and sommet.right: - #pas une feuille - graph.node(str(sommet.identifiant), label = str(sommet.occurrence) , style = "filled", fillcolor = "red", shape="circle") +def generate_node(graph, node, father = None): + if node.left and node.right: + # not a leaf + graph.node(str(node.identifier), label = str(node.occurrence) , style = "filled", fillcolor = "red", shape="circle") else: - #une feuille - graph.node(str(sommet.identifiant), label = graphviz.escape(str(sommet.occurrence)+'\n'+str(sommet.lettres)), style = "filled", fillcolor = "green") + # a leaf + graph.node(str(node.identifier), label = graphviz.escape(str(node.occurrence)+'\n'+str(node.char)), style = "filled", fillcolor = "green") # https://graphviz.readthedocs.io/en/stable/api.html#graphviz.escape if father != None: - graph.edge(str(father), str(sommet.identifiant), label=str(sommet.code)) + graph.edge(str(father), str(node.identifier), label=str(node.code)) - if sommet.left: - generate_node(graph, sommet.left, sommet.identifiant) - if sommet.right: - generate_node(graph, sommet.right, sommet.identifiant) + if node.left: + generate_node(graph, node.left, node.identifier) + if node.right: + generate_node(graph, node.right, node.identifier) diff --git a/huffman_py/gui/messageBox.py b/huffman_py/gui/messageBox.py index f8348bd..a7cb510 100644 --- a/huffman_py/gui/messageBox.py +++ b/huffman_py/gui/messageBox.py @@ -18,10 +18,10 @@ from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import * -def create_msg_box(message,titre): +def create_msg_box(message,title): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Information) msgBox.setText(message) - msgBox.setWindowTitle(titre) + msgBox.setWindowTitle(title) msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec_()