Module mvc.views.view

La vue pour les différents algorithmes.

C'est la partie qui permet d'interagir avec l'utilisateur. Affichages et entrées utilisateur.

La vue représente les données contenues dans le modèle après traitement par le contrôleur.

Expand source code
#!/usr/bin/python3
# -*- coding: utf8 -*-

# @author : Sébastien LOZANO
"""La vue pour les différents algorithmes.

C'est la partie qui permet d'interagir avec l'utilisateur. Affichages et entrées utilisateur.

La vue représente les données contenues dans le modèle après traitement par le contrôleur.
"""  # noqa : E501

# Pour les copies
import copy # noqa : F401
# Pour les opérations sur les fichiers
import shutil  # noqa : F401
# Pour les calculs de coordonnées
from math import cos, sin, pi # noqa : F401
# Pour les tris alphanumériques nécessaire pour les affichages
# Recours aux expressions régulières
import re # noqa : F401

# Pour la gestion des imports relatifs
import sys
import os

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(SCRIPT_DIR))

from models.noeud import Noeud  # noqa : E402
from models.arc import Arc  # noqa : E402
from models.graphe import Graphe  # noqa : E402

GRAPHE_PSEUDO_REELS = ['zgen011Cycles', 'zgen100']


class Vue:
    """La vue pour les différents algorithmes.

    Algorithme1 : Une méthode heuristique de réduction de la dette
    --------------------------------------------------------------
    Affiche les états successifs du graphe par application de la méthode heuristique de réduction de la dette.

    Algorithme2 : Réduction partielle de dettes par élimination des cycles
    ----------------------------------------------------------------------
    Affiche les états successifs du graphe par application de la méthode de réduction partielles de dettes
    par élimination des cycles.

    Algorithme3 : Algorithme de Klein
    ---------------------------------
    Affiche les états successifs du graphe par application de la méthode de Klein.

    Attributs
    ---------
    - graphe : Graphe - Une instance de Graphe
    - etapes : list - La liste des états successifs du graphe générés par une instance de la classe Controleur.
    - algo : str - Un string permettant de distinguer les différents algorithmes.

    Remarques
    ---------
    - Si algo contient "heuristique", **etapes** est un tableau dont :

        - le premier élément est la premiere entreprise sélectionnée.
        - le deuxième élément est le don à cette entreprise.
        - le troisième élément est la baisse de la dette globale obtenue.
        - le quatrième élément est le graphe initial
        - les éléments suivants sont les états successifs du graphe.

    - Si algo contient "eliminationCycles", **etapes** est un tableau dont :

        - le premier élément est la baisse de la dette globale obtenue.
        - le deuxième élément est le graphe initial
        - le troisième élément est le graphe initial simplifié
        - les éléments suivants sont les états successifs du graphe.

    - Si algo contient "klein",  **etapes** est un tableau dont :

        - le premier élément est la baisse de la dette globale obtenue.
        - le deuxième élément est le graphe initial
        - le troisième élément est le graphe initial simplifié
        si le graphe n'était pas simplifié
        - les éléments suivants sont alternativement les états successifs du graphe et le cycle réduit.
    """  # noqa : E501

    def __init__(
        self,
        graphe: Graphe,
        etapes=None,
        algo=None
    ) -> None:
        """Constructeur

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3],"heuristique")
        >>> print(vue)
        Graphe de la vue          : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        Entreprise choisie        : Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
        Don de la banque des dons : 5
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        """  # noqa : E501
        pass
        assert isinstance(graphe, Graphe), "graphe doit être une instance de la classe Graphe."  # noqa : E501
        assert isinstance(etapes, list) or etapes is None, "etapes doit être une liste ou None."  # noqa : E501
        assert isinstance(algo, str) or algo is None, "algo doit être un string ou None."  # noqa : E501
        assert algo in ["heuristique","eliminationCycles","klein"] or algo is None, "algo doit être un string spécifique à l'algorithme utilisé ou None."  # noqa : E501
        self.graphe = graphe
        if etapes is None:
            self.etapes = []
        else:
            self.etapes = etapes
        if ((algo is not None) and
                (algo not in ["heuristique", "eliminationCycles", "klein"])):
            raise ValueError(
                "algo doit être un string spécifique à l'algorithme utilisé."
            )
        else:
            self.algo = algo

    def __str__(self) -> None:
        """Représentation en chaine de caractères d'une instance de la classe Vue

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3],"heuristique")
        >>> print(vue)
        Graphe de la vue          : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        Entreprise choisie        : Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
        Don de la banque des dons : 5
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        >>> vue2 = Vue(g,[5,g2,g3],"eliminationCycles")
        >>> print(vue2)
        Graphe de la vue            : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        Baisse de la dette globale  : 5
        Graphe étape                : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe étape                : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        >>> vue3 = Vue(g)
        >>> print(vue3)
        Pas d'algorithme appelé.
        """  # noqa : E501
        pass
        sortie = ""
        if self.algo is None:
            sortie = "Pas d'algorithme appelé."
        if self.algo == "heuristique":
            graphe = "Graphe de la vue          : {}\n".format(self.getGraphe())  # noqa : E501
            entreprise = "Entreprise choisie        : {}\n".format(self.getEtapes()[0])  # noqa : E501
            don = "Don de la banque des dons : {}\n".format(self.getEtapes()[1])  # noqa : E501
            index = 2
            graphesEtapes = ""
            for index in range(2, len(self.getEtapes())-1):
                graphesEtapes += "Graphe étape              : {}\n".format(self.getEtapes()[index])  # noqa : E501
                index += 1
            graphesEtapes += "Graphe étape              : {}".format(self.getEtapes()[len(self.getEtapes())-1])  # noqa : E501
            sortie = graphe + entreprise + don + graphesEtapes
        if self.algo == "eliminationCycles":
            graphe = "Graphe de la vue            : {}\n".format(self.getGraphe())  # noqa : E501
            index = 1
            graphesEtapes = ""
            for index in range(1, len(self.getEtapes())-1):
                graphesEtapes += "Graphe étape                : {}\n".format(self.getEtapes()[index])  # noqa : E501
                index += 1
            graphesEtapes += "Graphe étape                : {}".format(self.getEtapes()[len(self.getEtapes())-1])  # noqa : E501
            baisseDetteGlobaleObtenue = "Baisse de la dette globale  : {}\n".format(self.getEtapes()[0])  # noqa : E501
            sortie = graphe + baisseDetteGlobaleObtenue + graphesEtapes

        return sortie

# ================================================================
# =========== GETTERS ============================================
# ================================================================
    def getGraphe(self) -> Graphe:
        """Retourne l'instance du graphe de la Vue.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> vue = Vue(g)
        >>> print(vue.getGraphe())
        Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB1', 'AB2', 'AC', 'CA1', 'CA2', 'BC'])
        """  # noqa : E501
        pass
        return self.graphe

    def getEtapes(self) -> list:
        """Retourne le tableaux des etapes, états successifs du graphe, pour l'algorithme.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3])
        >>> for i in vue.getEtapes():
        ...     print(i)
        ...
        Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
        5
        Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        """  # noqa : E501
        pass
        return self.etapes

    def getAlgo(self) -> str:
        """Retourne le type d'algorithme utilisé.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3],"klein")
        >>> print(vue.getAlgo())
        klein
        """
        pass
        return self.algo

# ================================================================
# =========== OUTILS =============================================
# ================================================================

    def graphvizMakeDotAndJsFile(self, graphe: Graphe, baseName: str) -> None:
        """Crée deux fichiers :

        - un fichier *.dot correspondant à un graphe dans le dossier ./graphviz/baseName
        pour l'affichage sur graphviz online
        - un fichier *.js  correspondant à un graphe dans le dossier ./graphviz/baseName
        pour l'affichage directement dans la fenetre html

        Paramètres
        ----------
        - graphe   : Graphe - Une instance de la classe Graphe.
        - baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

        Remarque
        --------
        Ressources pour rendu graphviz dans le navigateur

        - https://github.com/mdaines/viz.js/wiki
        - https://github.com/mdaines/viz.js/wiki/Usage
        - https://github.com/mdaines/viz.js/releases
        - https://github.com/mdaines/viz.js

        """ # noqa : E501
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        # On crée le répertoire s'il n'existe pas
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+self.getAlgo()+'/'+baseName
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count_dot = 0
        initial_count_js = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                root, extension = os.path.splitext(path)
                if extension == ".dot":
                    initial_count_dot += 1
                if extension == ".js":
                    initial_count_js += 1
        filenameDot = 'graphe'+'{:02d}'.format(initial_count_dot+1)
        filenameJs = 'graphe'+'{:02d}'.format(initial_count_js+1)
        destFile = dir+'/'+filenameDot+'.dot'
        destFileJs = dir+'/'+filenameJs+'.js'

        # Une fonction auxiliaire pour fixer les positions des noeuds
        def position(label, baseName, k=0, n=1, module=3):
            position = ''
            if baseName in ['gch', 'gvelamena']:
                if label == 'A':
                    position = "0,4!"
                elif label == 'B':
                    position = "3,6!"
                elif label == 'C':
                    position = "6,4!"
            elif baseName == 'grousseau':
                if label == 'A':
                    position = "0,4!"
                elif label == 'B':
                    position = "3,6!"
                elif label == 'C':
                    position = "6,4!"
                elif label == 'D':
                    position = "6,2!"
                elif label == 'E':
                    position = "3,0!"
                elif label == 'F':
                    position = "0,2!"
            elif baseName == 'gmikhailiv':
                if label == 'A':
                    position = "0,4!"
                elif label == 'B':
                    position = "6,4!"
                elif label == 'C':
                    position = "3,0!"
                elif label == 'D':
                    position = "3,6!"
                elif label == 'E':
                    position = "3,3!"
            elif baseName in GRAPHE_PSEUDO_REELS:
                if algo == 'heuristique':
                    # position = str(module*cos(2*k*pi/n)) + "," + str(module*sin(2*k*pi/n)) + "!" # noqa : E501
                    position = ""
                else:
                    position = ""
            else:
                position = ""
            return position

        algo = self.getAlgo()
        etapes = self.getEtapes()
        titre = ""
        detteInitialeTxt = "Dette globale initiale : "
        baisseDettecouranteTxt = "Baisse courante de la dette : "
        if algo == 'heuristique':
            titre = "Méthode heuristique"
            detteInitiale = etapes[3].detteGlobale()
            detteInitialeTxt += str(detteInitiale)
            detteCourante = etapes[initial_count_js+1+2].detteGlobale()
            entrepriseChoisieHeuristique = etapes[0]
            donEntreprise = etapes[1]
            precisionHeuristique = f"Initialement, {entrepriseChoisieHeuristique.getNom()} reçoit {donEntreprise}" # noqa : E501
        elif algo == "eliminationCycles":
            titre = "Méthode par éliminations des cycles"
            detteInitiale = etapes[1].detteGlobale()
            detteInitialeTxt += str(detteInitiale)
            detteCourante = etapes[initial_count_js+1].detteGlobale()
            precisionHeuristique = ""
        elif algo == "klein":
            titre = "Algorithme de Klein"
            detteInitiale = etapes[1].detteGlobale()
            detteInitialeTxt += str(detteInitiale)
            detteCourante = etapes[initial_count_js+1].detteGlobale()
            precisionHeuristique = ""
        else:
            titre = "BUG TITRE"
            detteInitialeTxt = "BUG SOUS-TITRE"
            baisseDettecouranteTxt = "BUG BAISSE COURANTE"
            precisionHeuristique = "BUG PRECISION HEURISTIQUE"
        if algo in ['heuristique', 'eliminationCycles', 'klein']:
            baisseDettecouranteTxt += str(detteInitiale - detteCourante)

        # Une fonction auxiliaire pour factoriser l'écriture du code
        # du string au format *.dot
        if baseName in GRAPHE_PSEUDO_REELS:
            moteur = 'dot'
        else:
            moteur = 'neato'

        def makeStrDigraph(file, retour):
            file.write("digraph G {" + retour)
            file.write(retour)
            # file.write("# On force le moteur neato " + retour)
            # file.write("layout=neato " + retour)
            file.write("# On force le moteur " + moteur + " " + retour)
            file.write("layout=" + moteur + " " + retour)
            file.write(retour)
            file.write("# Le titre " + retour)
            file.write('labelloc = "t" ' + retour)
            file.write('label = <' + retour)
            file.write('<table border ="0">' + retour)
            file.write(f'<tr><td><FONT POINT-SIZE="30.0" color="red">{titre}</FONT></td></tr>' + retour) # noqa : E501
            file.write(f'<tr><td>{detteInitialeTxt}</td></tr>' + retour)
            file.write(f'<tr><td>{baisseDettecouranteTxt}</td></tr>' + retour)
            file.write(f'<tr><td>{precisionHeuristique}</td></tr>' + retour)
            file.write('</table>' + retour)
            file.write('>' + retour)
            file.write(retour)
            file.write("# Les noeuds " + retour)
            for i in range(len(noeuds)):
                # Un string pour factoriser
                node = '{} [label="{}"; shape="circle", pos="{}"] ' + retour
                if baseName in GRAPHE_PSEUDO_REELS:
                    nodePosition = position(
                        noeuds[i].getNom(),
                        baseName,
                        i,
                        len(noeuds),
                        4
                        )
                else:
                    nodePosition = position(noeuds[i].getNom(), baseName)
                if algo == "heuristique":
                    file.write(node.format(
                        noeuds[i].getNom(),
                        noeuds[i].getNom()+"\\n capital : "+str(noeuds[i].getCapital()), # noqa : E501
                        # noeuds[i].getNom(), # noqa : E501
                        nodePosition)
                    )
                else:
                    file.write(node.format(
                        noeuds[i].getNom(),
                        noeuds[i].getNom(),
                        nodePosition)
                    )
            file.write(retour)
            file.write("# Les arcs " + retour)
            strArc = "{} -> {} [headlabel = \"{}\"; labeldistance=2] " + retour
            strArcInverse = "{} -> {} [headlabel = \"{}\"; labeldistance=2; style=\"dashed\"; color=\"blue\"; fontcolor=\"blue\"] " + retour # noqa : E501
            for i in range(len(arcs)):
                if arcs[i].getEstInverse():
                    file.write(strArcInverse.format(
                        arcs[i].getNoeudDebut().getNom(),
                        arcs[i].getNoeudFin().getNom(),
                        arcs[i].getPoids())
                    )
                else:
                    file.write(strArc.format(
                        arcs[i].getNoeudDebut().getNom(),
                        arcs[i].getNoeudFin().getNom(),
                        arcs[i].getPoids())
                    )
            file.write("}" + retour)

        retour = ""
        noeuds = graphe.getNoeuds()
        arcs = graphe.getArcs()
        with open(destFile, 'w') as file:
            retour = "%0A%0A%20 "
            makeStrDigraph(file, retour)
            file.close()
        with open(destFileJs, 'w') as file:
            retour = " \n "
            file.write('function '+filenameJs+'() {')
            file.write('divGraph = document.getElementById("divGraph")' + retour) # noqa : E501
            file.write('var viz = new Viz();' + retour)
            file.write('viz.renderSVGElement(`' + retour)
            makeStrDigraph(file, retour)
            if baseName in GRAPHE_PSEUDO_REELS:
                coeffSvg = 2
            else:
                coeffSvg = 1.5

            file.write("""
            `).then(function(svg) {
                    txtObj = document.getElementById("txtGraph")
                    txtObj.data = ""
                    var w = svg.getAttribute("width")
                    w = parseInt(w.slice(0, -2))*""" + str(coeffSvg) + """
                    w = w.toString()
                    var h = svg.getAttribute("height")
                    h = parseInt(h.slice(0, -2))*""" + str(coeffSvg) + """
                    h = h.toString()
                    svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
                    svg.setAttribute('preserveAspectRatio', 'xMinYMin meet')
                    var s = new XMLSerializer();
                    var strSVG = s.serializeToString(svg)
                    divGraph.innerHTML = strSVG
                })
                .catch(error => {
                    // Create a new Viz instance
                    // (@see Caveats page for more info)
                    viz = new Viz();

                    // Possibly display the error
                    console.error(error);
                });
            """ + retour)
            file.write('}')
            file.close()

    def graphvizMakeDotAndJsFiles(self, baseName: str) -> None:
        """Crée tous les fichiers *.dot et *.js correspondants aux étapes d'une vue.

        - les fichiers *.dot pour l'affichage sur graphviz online
        - les fichiers *.js pour l'affichage directement dans la fenetre html

        Paramètres
        ----------
        - graphe   : Graphe - Une instance de la classe Graphe.
        - baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

        Remarques
        ---------
        - les fichiers sont stockés dans le répertoire ./graphviz_algo/baseName
        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        # On récupère le type d'algorithme
        algo = self.getAlgo()
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+algo+'/'+baseName
        # On supprime les répertoires s'ils existent
        if os.path.exists(dir):
            shutil.rmtree(dir)
        # On initialise l'index inital selon l'algorithme
        indexInitial = 0
        # On factorise le tableau des étapes
        etapes = self.getEtapes()
        if algo == "heuristique":
            indexInitial = 3
            for i in range(indexInitial, len(etapes) - 1):
                self.graphvizMakeDotAndJsFile(etapes[i], baseName)
        elif algo in ["eliminationCycles", "klein"]:
            indexInitial = 1
            for i in range(indexInitial, len(etapes)):
                self.graphvizMakeDotAndJsFile(etapes[i], baseName)

    def graphvizMakeHtml(self, baseName: str) -> None:
        """Crée une page html avec autant de liens que de graphes
        dans le dossier ./_graphviz_algo/baseName

        Paramètres
        ----------
        baseName : str - Le nom du dossier qui contient les fichiers *.dot
        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        #  Page vide
        title = {
            'title': '',
            'subtitle': ''
        }
        if baseName == 'gch':
            title["title"] = 'Cours heuristique'
            title["subtitle"] = 'GRAPHE DU COURS HEURISTIQUE'
        elif baseName == 'grousseau':
            title["title"] = 'Biblio Rousseau'
            title["subtitle"] = 'GRAPHE DE LA BIBLIO D\'ARTHUR ROUSSEAU'
        elif baseName == 'gmikhailiv':
            title["title"] = 'Rapport Mikhailiv'
            title["subtitle"] = 'GRAPHE DU RAPPORT DE YOSIP MIKHAILIV'
        elif baseName == 'gvelamena':
            title["title"] = 'Rapport VelaMena'
            title["subtitle"] = 'GRAPHE DU RAPPORT DE MARIE VELA-MENA'
        elif baseName in GRAPHE_PSEUDO_REELS:
            title["title"] = 'Données ' + baseName[1:].capitalize()
            title["subtitle"] = 'GRAPHE ' + baseName[1:].capitalize()
        else:
            title["title"] = "BUG CONDITION"
            title["subtitle"] = "BUG CONDITION"

        header = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
button {
cursor:pointer; margin: 4px 2px; padding: 5px 10px;
}
</style>
<title>""" + title['title'] + """</title>
<script src="../../js/viz.js"></script>
<script src="../../js/full.render.js"></script>
</head>
<body>\n"""
        footer = """</body></html>"""
        # On crée le répertoire s'il n'existe pas
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+self.getAlgo()+'/'+baseName
        htmlFile = dir+'/'+baseName+'.html'
        textDir = htmlDir+'/texte_'+self.getAlgo()+'/'+baseName
        textOnlineDir = '/texte_'+self.getAlgo()+'/'+baseName
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                initial_count += 1
        with open(htmlFile, 'w') as file:
            file.write(header)
            if initial_count == 0:
                file.write("<h1>PAGE VIDE</h1>\n")
            else:
                file.write("""<button><a href='../../index.html'> << Retour au
                menu Principal</a></button>""")
                # On adapte le texte
                algo = self.getAlgo()
                titreAlgo = ''
                if algo == 'heuristique':
                    titreAlgo = 'Méthode heuristique'
                elif algo == 'eliminationCycles':
                    titreAlgo = 'Méthode par élimination des Cycles'
                elif algo == 'klein':
                    titreAlgo = 'Algorithme de Klein'
                file.write("<h1>{} >> {}</h1>\n".format(
                    titreAlgo,
                    title["subtitle"].lower()
                ))
                file.write("""
<h3>Remarques :</h3>\n
<ul>\n
<li>Les liens permettent d'afficher les graphes étapes directement dans la page ou dans un nouvel onglet sur le site <a href="https://dreampuf.github.io/GraphvizOnline/" target="_blank">GraphvizOnline</a></li>\n
<li>On peut aussi afficher une version texte des étapes. <strong>Plusieurs simulations sont proposées.</strong> . Le <button style="color:red;">lien rouge</button> correspond à celle des graphes affichables.</li>\n
</ul>\n
                """) # noqa : E501
                file.write("""<div style="float: left; width: 15%">\n""")
                file.write('<ul>\n')
                file.write("<h4>Graphiques<br>Ci-contre</h4>\n")
                # for path in os.listdir(dir):
                for path in sorted(os.listdir(dir)):
                    if os.path.isfile(os.path.join(dir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == ".js":
                            file.write("<button onclick="+root+"()>Voir étape " + root[-2:] + " </button>\n") # noqa : E501
                            file.write("<script src=\"./"+path+"\"></script>\n") # noqa : E501
                file.write("<h4>GraphizOnline</h4>\n")
                # for path in os.listdir(dir):
                for path in sorted(os.listdir(dir)):
                    if os.path.isfile(os.path.join(dir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.dot':
                            currentDotFile = open(os.path.join(dir, path), "r")
                            currentStr = currentDotFile.readlines()[0]
                            file.write("<button><a href='https://dreampuf.github.io/GraphvizOnline/#"+currentStr+"' target='_blank'> Voir étape " + root[-2:]+ "</a></button>\n") # noqa : E501
                            currentDotFile.close()
                file.write('</ul>\n')
                file.write('</div>\n')
                file.write("""<div style="float: left; width: 15%">\n""")
                file.write('<ul>\n')
                file.write("<h4>Fichiers texte</h4>\n")
                # Un compteur pour l'affichage du style des étapes courantes
                cptMax = 0
                for path in os.listdir(textDir):
                    if os.path.isfile(os.path.join(textDir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.txt':
                            cptMax += 1
                cptMaxStr = '{:02d}'.format(cptMax)
                file.write("<button style=\"color:red;\" onclick=" + root + cptMaxStr + "txt()>Étapes correspondant aux graphes affichables</button>\n") # noqa : E501
                file.write("""
                <script>\n
                    function """ + root + cptMaxStr + """txt() {
                        divGraph = document.getElementById("divGraph")
                        divGraph.innerHTML = ""
                        txtObj = document.getElementById("txtGraph")
                        txtObj.data = \"../../.""" + os.path.join(textOnlineDir, "graphe"+cptMaxStr+".txt") + """ \"
                    }
                </script>\n
                """) # noqa : E501

                # for path in os.listdir(textDir):
                for path in sorted(os.listdir(textDir)):
                    if os.path.isfile(os.path.join(textDir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.txt' and root[-2:] != cptMaxStr:
                            file.write("<button onclick="+root+"txt()>Voir une autre simulation</button>\n") # noqa : E501
                            file.write("""
                            <script>\n
                                function """ + root + """txt() {
                                    divGraph = document.getElementById("divGraph")
                                    divGraph.innerHTML = ""
                                    txtObj = document.getElementById("txtGraph")
                                    txtObj.data = \"../../.""" + os.path.join(textOnlineDir, path) + """ \"
                                }
                            </script>\n
                            """) # noqa : E501
                file.write('</ul>\n')
                file.write("</div>\n")
                file.write("""
<div id="containerDivGraph" style="margin-left: 35%; height:600px; width:55%; border-left:1px solid black;" >\n
<div id="divGraph" style="margin-left: 20%; height:auto; width:90%"></div>\n
<object id="txtGraph" data="" type="text/plain" style="width: 100%; height: 100%;"></object>
</div>\n
                """) # noqa : E501
            file.write(footer)
            file.close()

    def texteMakeFile(self, baseName: str) -> None:
        """Crée un fichier texte avec les différents graphes étapes obtenus par
        application de l'algorithme appliqué.

        La propriété algo de la classe Vue, contient l'information sur
        l'algorithme utilisé.

        Paramètres
        ----------
        baseName : str - Le nom du dossier qui va contenir le fichier *.txt

        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        # On récupère le type d'algorithme
        algo = self.getAlgo()
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/texte_'+self.getAlgo()+'/'+baseName
        # On crée le répertoire s'il n'existe pas
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                initial_count += 1
        filename = 'graphe'+'{:02d}'.format(initial_count+1)
        destFile = dir+'/'+filename+'.txt'
        if algo == "heuristique":
            lines = self.consoleHeuristique().split("\\n")
        elif algo == "eliminationCycles":
            lines = self.consoleEliminationCycles().split("\\n")
        elif algo == "klein":
            lines = self.consoleAlgorithmeDeKlein().split("\\n")

        with open(destFile, 'w') as file:
            for line in lines:
                file.write(line)
            file.close()

# =========== ALGORITHME 1 : METHODE HEURISTIQUE =================

    def consoleHeuristique(self):
        """Renvoie les données après traitement par le controleur via l'algorithme
        de la méthode heuristique dans un string.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.simplification()
        >>> A_init = copy.deepcopy(A)
        >>> gInit = copy.deepcopy(g)
        >>> # On choisit fictivement A qui reçoit 7
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[1].setCapital(7)
        >>> g1 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[1])
        >>> g.getNoeuds()[1].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(5)
        >>> g2 = copy.deepcopy(g)
        >>> g.getArcs()[1].setPoids(4)
        >>> g.getArcs()[1].setNom("C-4->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g3 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[0].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(3)
        >>> g4 = copy.deepcopy(g)
        >>> g.getArcs()[0].setPoids(1)
        >>> g.getArcs()[0].setNom("C-1->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g5 = copy.deepcopy(g)
        >>> vue = Vue(gInit,[A_init, 7, 23, gInit, g1, g2, g3, g4, g5, g5],"heuristique")
        >>> print(vue.consoleHeuristique())
        =====================================================
        ======= ALGORITHME 1 : METHODE HEURISTIQUE ==========
        =====================================================
        Première entreprise choisie : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0)
        Cette entreprise reçoit     : 7
        =====================================================
        Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale initiale n°0 : 24
        =====================================================
        Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°1 : 17
        =====================================================
        Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°2 : 12
        =====================================================
        Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°3 : 7
        =====================================================
        Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°4 : 4
        =====================================================
        Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°5 : 1
        =====================================================
        Baisse de la dette globale obtenue : 23
        =====================================================
        """  # noqa : E501
        pass
        sortie = ''
        sortie += "=====================================================\n"
        sortie += "======= ALGORITHME 1 : METHODE HEURISTIQUE ==========\n"
        sortie += "=====================================================\n"
        sortie += f"Première entreprise choisie : {self.getEtapes()[0]}\n"
        sortie += f"Cette entreprise reçoit     : {self.getEtapes()[1]}\n"
        sortie += "=====================================================\n"
        sortie += f'Graphe initial n°0 : {self.getEtapes()[3]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[3].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[3].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[3].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        # Le dernier graphe est toujours en doublon avec la méthode heuristique
        for index in range(4, len(self.getEtapes())-1):
            sortie += f'Graphe intermediaire n°{index-3} : {self.getEtapes()[index]}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[index].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise,self.getEtapes()[0].getNom(),self.getEtapes()[1])}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            if self.getEtapes()[index].hasArc():
                sortie += f'Dette Globale n°{index-3} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
            else:
                sortie += f'Dette Globale n°{index-3} : 0\n'  # noqa : E501
            sortie += "=====================================================\n"
            index += 1
        sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[2]}\n' # noqa : E501
        sortie += "======================================================\n"

        return sortie[:-2]

# =========== ALGORITHME 2 : ÉLIMINATION DES CYCLES ==============

    def consoleEliminationCycles(self):
        """Renvoie les données après traitement par le controleur via l'algorithme
        par élimination des cycles dans un string.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.simplification()
        >>> A_init = copy.deepcopy(A)
        >>> gInit = copy.deepcopy(g)
        >>> # On choisit fictivement A qui reçoit 7
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[1].setCapital(7)
        >>> g1 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[1])
        >>> g.getNoeuds()[1].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(5)
        >>> g2 = copy.deepcopy(g)
        >>> g.getArcs()[1].setPoids(4)
        >>> g.getArcs()[1].setNom("C-4->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g3 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[0].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(3)
        >>> g4 = copy.deepcopy(g)
        >>> g.getArcs()[0].setPoids(1)
        >>> g.getArcs()[0].setNom("C-1->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g5 = copy.deepcopy(g)
        >>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
        >>> print(vue.consoleEliminationCycles())
        =====================================================
        ===== ALGORITHME 2 : ELIMINATION DES CYCLES =========
        =====================================================
        Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale initiale n°0 : 24
        =====================================================
        Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°1 : 17
        =====================================================
        Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°2 : 12
        =====================================================
        Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°3 : 7
        =====================================================
        Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°4 : 4
        =====================================================
        Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°5 : 1
        =====================================================
        Baisse de la dette globale obtenue : 23
        =====================================================
        """  # noqa : E501
        pass
        sortie = ''
        sortie += "=====================================================\n"
        sortie += "===== ALGORITHME 2 : ELIMINATION DES CYCLES =========\n"
        sortie += "=====================================================\n"
        sortie += f'Graphe initial n°0 : {self.getEtapes()[1]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[1].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[1].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[1].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        for index in range(2, len(self.getEtapes())):
            sortie += f'Graphe intermediaire n°{index-1} : {self.getEtapes()[index]}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[index].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise)}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            sortie += f'Dette Globale n°{index-1} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
            sortie += "=====================================================\n"
        sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[0]}\n' # noqa : E501
        sortie += "======================================================\n"

        return sortie[:-2]

# =========== ALGORITHME 3 : ALGORITHME DE KLEIN =================

    def consoleAlgorithmeDeKlein(self):
        """Renvoie les données après traitement par le controleur via l'algorithme de Klein
        dans un string.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.simplification()
        >>> A_init = copy.deepcopy(A)
        >>> gInit = copy.deepcopy(g)
        >>> # On choisit fictivement A qui reçoit 7
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[1].setCapital(7)
        >>> g1 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[1])
        >>> g.getNoeuds()[1].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(5)
        >>> g2 = copy.deepcopy(g)
        >>> g.getArcs()[1].setPoids(4)
        >>> g.getArcs()[1].setNom("C-4->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g3 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[0].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(3)
        >>> g4 = copy.deepcopy(g)
        >>> g.getArcs()[0].setPoids(1)
        >>> g.getArcs()[0].setNom("C-1->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g5 = copy.deepcopy(g)
        >>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
        >>> print(vue.consoleAlgorithmeDeKlein())
        =====================================================
        ===== ALGORITHME 3 : KLEIN ==========================
        =====================================================
        Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale initiale n°0 : 24
        =====================================================
        Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°1 : 17
        ====================================================
        Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°2 : 12
        ====================================================
        Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°3 : 7
        ====================================================
        Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°4 : 4
        ====================================================
        Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°5 : 1
        ====================================================
        Baisse de la dette globale obtenue : 23
        ====================================================
        """  # noqa : E501
        pass
        sortie = ''
        # On génère les graphes
        sortie += "=====================================================\n"
        sortie += "===== ALGORITHME 3 : KLEIN ==========================\n"
        sortie += "=====================================================\n"
        sortie += f'Graphe initial n°0 : {self.getEtapes()[1]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[1].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[1].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[1].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        if self.getEtapes()[1].estSimplifie():
            indexInitial = 2
        else:
            sortie += f'Graphe simplifié n°1 : {self.getEtapes()[2]}\n'
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[2].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[2].positionNette(entreprise) }\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            sortie += f'Dette Globale initiale n°1 : {self.getEtapes()[2].detteGlobale()}\n'  # noqa : E501
            sortie += "=====================================================\n"
            indexInitial = 3

        for index in range(indexInitial, len(self.getEtapes())):
            sortie += f'Graphe intermediaire n°{index-1} : {self.getEtapes()[index]}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[index].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise)}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            sortie += f'Dette Globale n°{index-1} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
            sortie += "====================================================\n"

        sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[0]}\n' # noqa : E501
        sortie += "=====================================================\n"

        return sortie[:-2]


if __name__ == "__main__":
    import doctest
    doctest.testmod()

Classes

class Vue (graphe: models.graphe.Graphe, etapes=None, algo=None)

La vue pour les différents algorithmes.

Algorithme1 : Une méthode heuristique de réduction de la dette

Affiche les états successifs du graphe par application de la méthode heuristique de réduction de la dette.

Algorithme2 : Réduction partielle de dettes par élimination des cycles

Affiche les états successifs du graphe par application de la méthode de réduction partielles de dettes par élimination des cycles.

Algorithme3 : Algorithme de Klein

Affiche les états successifs du graphe par application de la méthode de Klein.

Attributs

  • graphe : Graphe - Une instance de Graphe
  • etapes : list - La liste des états successifs du graphe générés par une instance de la classe Controleur.
  • algo : str - Un string permettant de distinguer les différents algorithmes.

Remarques

  • Si algo contient "heuristique", etapes est un tableau dont :

    • le premier élément est la premiere entreprise sélectionnée.
    • le deuxième élément est le don à cette entreprise.
    • le troisième élément est la baisse de la dette globale obtenue.
    • le quatrième élément est le graphe initial
    • les éléments suivants sont les états successifs du graphe.
  • Si algo contient "eliminationCycles", etapes est un tableau dont :

    • le premier élément est la baisse de la dette globale obtenue.
    • le deuxième élément est le graphe initial
    • le troisième élément est le graphe initial simplifié
    • les éléments suivants sont les états successifs du graphe.
  • Si algo contient "klein", etapes est un tableau dont :

    • le premier élément est la baisse de la dette globale obtenue.
    • le deuxième élément est le graphe initial
    • le troisième élément est le graphe initial simplifié si le graphe n'était pas simplifié
    • les éléments suivants sont alternativement les états successifs du graphe et le cycle réduit.

Constructeur

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> g.removeArc(AB1)
>>> g2 = copy.deepcopy(g)
>>> g.removeArc(BC)
>>> g3 = copy.deepcopy(g)
>>> vue = Vue(g,[A,5,g2,g3],"heuristique")
>>> print(vue)
Graphe de la vue          : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
Entreprise choisie        : Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
Don de la banque des dons : 5
Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
Expand source code
class Vue:
    """La vue pour les différents algorithmes.

    Algorithme1 : Une méthode heuristique de réduction de la dette
    --------------------------------------------------------------
    Affiche les états successifs du graphe par application de la méthode heuristique de réduction de la dette.

    Algorithme2 : Réduction partielle de dettes par élimination des cycles
    ----------------------------------------------------------------------
    Affiche les états successifs du graphe par application de la méthode de réduction partielles de dettes
    par élimination des cycles.

    Algorithme3 : Algorithme de Klein
    ---------------------------------
    Affiche les états successifs du graphe par application de la méthode de Klein.

    Attributs
    ---------
    - graphe : Graphe - Une instance de Graphe
    - etapes : list - La liste des états successifs du graphe générés par une instance de la classe Controleur.
    - algo : str - Un string permettant de distinguer les différents algorithmes.

    Remarques
    ---------
    - Si algo contient "heuristique", **etapes** est un tableau dont :

        - le premier élément est la premiere entreprise sélectionnée.
        - le deuxième élément est le don à cette entreprise.
        - le troisième élément est la baisse de la dette globale obtenue.
        - le quatrième élément est le graphe initial
        - les éléments suivants sont les états successifs du graphe.

    - Si algo contient "eliminationCycles", **etapes** est un tableau dont :

        - le premier élément est la baisse de la dette globale obtenue.
        - le deuxième élément est le graphe initial
        - le troisième élément est le graphe initial simplifié
        - les éléments suivants sont les états successifs du graphe.

    - Si algo contient "klein",  **etapes** est un tableau dont :

        - le premier élément est la baisse de la dette globale obtenue.
        - le deuxième élément est le graphe initial
        - le troisième élément est le graphe initial simplifié
        si le graphe n'était pas simplifié
        - les éléments suivants sont alternativement les états successifs du graphe et le cycle réduit.
    """  # noqa : E501

    def __init__(
        self,
        graphe: Graphe,
        etapes=None,
        algo=None
    ) -> None:
        """Constructeur

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3],"heuristique")
        >>> print(vue)
        Graphe de la vue          : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        Entreprise choisie        : Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
        Don de la banque des dons : 5
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        """  # noqa : E501
        pass
        assert isinstance(graphe, Graphe), "graphe doit être une instance de la classe Graphe."  # noqa : E501
        assert isinstance(etapes, list) or etapes is None, "etapes doit être une liste ou None."  # noqa : E501
        assert isinstance(algo, str) or algo is None, "algo doit être un string ou None."  # noqa : E501
        assert algo in ["heuristique","eliminationCycles","klein"] or algo is None, "algo doit être un string spécifique à l'algorithme utilisé ou None."  # noqa : E501
        self.graphe = graphe
        if etapes is None:
            self.etapes = []
        else:
            self.etapes = etapes
        if ((algo is not None) and
                (algo not in ["heuristique", "eliminationCycles", "klein"])):
            raise ValueError(
                "algo doit être un string spécifique à l'algorithme utilisé."
            )
        else:
            self.algo = algo

    def __str__(self) -> None:
        """Représentation en chaine de caractères d'une instance de la classe Vue

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3],"heuristique")
        >>> print(vue)
        Graphe de la vue          : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        Entreprise choisie        : Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
        Don de la banque des dons : 5
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe étape              : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        >>> vue2 = Vue(g,[5,g2,g3],"eliminationCycles")
        >>> print(vue2)
        Graphe de la vue            : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        Baisse de la dette globale  : 5
        Graphe étape                : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe étape                : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        >>> vue3 = Vue(g)
        >>> print(vue3)
        Pas d'algorithme appelé.
        """  # noqa : E501
        pass
        sortie = ""
        if self.algo is None:
            sortie = "Pas d'algorithme appelé."
        if self.algo == "heuristique":
            graphe = "Graphe de la vue          : {}\n".format(self.getGraphe())  # noqa : E501
            entreprise = "Entreprise choisie        : {}\n".format(self.getEtapes()[0])  # noqa : E501
            don = "Don de la banque des dons : {}\n".format(self.getEtapes()[1])  # noqa : E501
            index = 2
            graphesEtapes = ""
            for index in range(2, len(self.getEtapes())-1):
                graphesEtapes += "Graphe étape              : {}\n".format(self.getEtapes()[index])  # noqa : E501
                index += 1
            graphesEtapes += "Graphe étape              : {}".format(self.getEtapes()[len(self.getEtapes())-1])  # noqa : E501
            sortie = graphe + entreprise + don + graphesEtapes
        if self.algo == "eliminationCycles":
            graphe = "Graphe de la vue            : {}\n".format(self.getGraphe())  # noqa : E501
            index = 1
            graphesEtapes = ""
            for index in range(1, len(self.getEtapes())-1):
                graphesEtapes += "Graphe étape                : {}\n".format(self.getEtapes()[index])  # noqa : E501
                index += 1
            graphesEtapes += "Graphe étape                : {}".format(self.getEtapes()[len(self.getEtapes())-1])  # noqa : E501
            baisseDetteGlobaleObtenue = "Baisse de la dette globale  : {}\n".format(self.getEtapes()[0])  # noqa : E501
            sortie = graphe + baisseDetteGlobaleObtenue + graphesEtapes

        return sortie

# ================================================================
# =========== GETTERS ============================================
# ================================================================
    def getGraphe(self) -> Graphe:
        """Retourne l'instance du graphe de la Vue.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> vue = Vue(g)
        >>> print(vue.getGraphe())
        Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB1', 'AB2', 'AC', 'CA1', 'CA2', 'BC'])
        """  # noqa : E501
        pass
        return self.graphe

    def getEtapes(self) -> list:
        """Retourne le tableaux des etapes, états successifs du graphe, pour l'algorithme.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3])
        >>> for i in vue.getEtapes():
        ...     print(i)
        ...
        Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
        5
        Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
        Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
        """  # noqa : E501
        pass
        return self.etapes

    def getAlgo(self) -> str:
        """Retourne le type d'algorithme utilisé.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.removeArc(AB1)
        >>> g2 = copy.deepcopy(g)
        >>> g.removeArc(BC)
        >>> g3 = copy.deepcopy(g)
        >>> vue = Vue(g,[A,5,g2,g3],"klein")
        >>> print(vue.getAlgo())
        klein
        """
        pass
        return self.algo

# ================================================================
# =========== OUTILS =============================================
# ================================================================

    def graphvizMakeDotAndJsFile(self, graphe: Graphe, baseName: str) -> None:
        """Crée deux fichiers :

        - un fichier *.dot correspondant à un graphe dans le dossier ./graphviz/baseName
        pour l'affichage sur graphviz online
        - un fichier *.js  correspondant à un graphe dans le dossier ./graphviz/baseName
        pour l'affichage directement dans la fenetre html

        Paramètres
        ----------
        - graphe   : Graphe - Une instance de la classe Graphe.
        - baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

        Remarque
        --------
        Ressources pour rendu graphviz dans le navigateur

        - https://github.com/mdaines/viz.js/wiki
        - https://github.com/mdaines/viz.js/wiki/Usage
        - https://github.com/mdaines/viz.js/releases
        - https://github.com/mdaines/viz.js

        """ # noqa : E501
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        # On crée le répertoire s'il n'existe pas
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+self.getAlgo()+'/'+baseName
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count_dot = 0
        initial_count_js = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                root, extension = os.path.splitext(path)
                if extension == ".dot":
                    initial_count_dot += 1
                if extension == ".js":
                    initial_count_js += 1
        filenameDot = 'graphe'+'{:02d}'.format(initial_count_dot+1)
        filenameJs = 'graphe'+'{:02d}'.format(initial_count_js+1)
        destFile = dir+'/'+filenameDot+'.dot'
        destFileJs = dir+'/'+filenameJs+'.js'

        # Une fonction auxiliaire pour fixer les positions des noeuds
        def position(label, baseName, k=0, n=1, module=3):
            position = ''
            if baseName in ['gch', 'gvelamena']:
                if label == 'A':
                    position = "0,4!"
                elif label == 'B':
                    position = "3,6!"
                elif label == 'C':
                    position = "6,4!"
            elif baseName == 'grousseau':
                if label == 'A':
                    position = "0,4!"
                elif label == 'B':
                    position = "3,6!"
                elif label == 'C':
                    position = "6,4!"
                elif label == 'D':
                    position = "6,2!"
                elif label == 'E':
                    position = "3,0!"
                elif label == 'F':
                    position = "0,2!"
            elif baseName == 'gmikhailiv':
                if label == 'A':
                    position = "0,4!"
                elif label == 'B':
                    position = "6,4!"
                elif label == 'C':
                    position = "3,0!"
                elif label == 'D':
                    position = "3,6!"
                elif label == 'E':
                    position = "3,3!"
            elif baseName in GRAPHE_PSEUDO_REELS:
                if algo == 'heuristique':
                    # position = str(module*cos(2*k*pi/n)) + "," + str(module*sin(2*k*pi/n)) + "!" # noqa : E501
                    position = ""
                else:
                    position = ""
            else:
                position = ""
            return position

        algo = self.getAlgo()
        etapes = self.getEtapes()
        titre = ""
        detteInitialeTxt = "Dette globale initiale : "
        baisseDettecouranteTxt = "Baisse courante de la dette : "
        if algo == 'heuristique':
            titre = "Méthode heuristique"
            detteInitiale = etapes[3].detteGlobale()
            detteInitialeTxt += str(detteInitiale)
            detteCourante = etapes[initial_count_js+1+2].detteGlobale()
            entrepriseChoisieHeuristique = etapes[0]
            donEntreprise = etapes[1]
            precisionHeuristique = f"Initialement, {entrepriseChoisieHeuristique.getNom()} reçoit {donEntreprise}" # noqa : E501
        elif algo == "eliminationCycles":
            titre = "Méthode par éliminations des cycles"
            detteInitiale = etapes[1].detteGlobale()
            detteInitialeTxt += str(detteInitiale)
            detteCourante = etapes[initial_count_js+1].detteGlobale()
            precisionHeuristique = ""
        elif algo == "klein":
            titre = "Algorithme de Klein"
            detteInitiale = etapes[1].detteGlobale()
            detteInitialeTxt += str(detteInitiale)
            detteCourante = etapes[initial_count_js+1].detteGlobale()
            precisionHeuristique = ""
        else:
            titre = "BUG TITRE"
            detteInitialeTxt = "BUG SOUS-TITRE"
            baisseDettecouranteTxt = "BUG BAISSE COURANTE"
            precisionHeuristique = "BUG PRECISION HEURISTIQUE"
        if algo in ['heuristique', 'eliminationCycles', 'klein']:
            baisseDettecouranteTxt += str(detteInitiale - detteCourante)

        # Une fonction auxiliaire pour factoriser l'écriture du code
        # du string au format *.dot
        if baseName in GRAPHE_PSEUDO_REELS:
            moteur = 'dot'
        else:
            moteur = 'neato'

        def makeStrDigraph(file, retour):
            file.write("digraph G {" + retour)
            file.write(retour)
            # file.write("# On force le moteur neato " + retour)
            # file.write("layout=neato " + retour)
            file.write("# On force le moteur " + moteur + " " + retour)
            file.write("layout=" + moteur + " " + retour)
            file.write(retour)
            file.write("# Le titre " + retour)
            file.write('labelloc = "t" ' + retour)
            file.write('label = <' + retour)
            file.write('<table border ="0">' + retour)
            file.write(f'<tr><td><FONT POINT-SIZE="30.0" color="red">{titre}</FONT></td></tr>' + retour) # noqa : E501
            file.write(f'<tr><td>{detteInitialeTxt}</td></tr>' + retour)
            file.write(f'<tr><td>{baisseDettecouranteTxt}</td></tr>' + retour)
            file.write(f'<tr><td>{precisionHeuristique}</td></tr>' + retour)
            file.write('</table>' + retour)
            file.write('>' + retour)
            file.write(retour)
            file.write("# Les noeuds " + retour)
            for i in range(len(noeuds)):
                # Un string pour factoriser
                node = '{} [label="{}"; shape="circle", pos="{}"] ' + retour
                if baseName in GRAPHE_PSEUDO_REELS:
                    nodePosition = position(
                        noeuds[i].getNom(),
                        baseName,
                        i,
                        len(noeuds),
                        4
                        )
                else:
                    nodePosition = position(noeuds[i].getNom(), baseName)
                if algo == "heuristique":
                    file.write(node.format(
                        noeuds[i].getNom(),
                        noeuds[i].getNom()+"\\n capital : "+str(noeuds[i].getCapital()), # noqa : E501
                        # noeuds[i].getNom(), # noqa : E501
                        nodePosition)
                    )
                else:
                    file.write(node.format(
                        noeuds[i].getNom(),
                        noeuds[i].getNom(),
                        nodePosition)
                    )
            file.write(retour)
            file.write("# Les arcs " + retour)
            strArc = "{} -> {} [headlabel = \"{}\"; labeldistance=2] " + retour
            strArcInverse = "{} -> {} [headlabel = \"{}\"; labeldistance=2; style=\"dashed\"; color=\"blue\"; fontcolor=\"blue\"] " + retour # noqa : E501
            for i in range(len(arcs)):
                if arcs[i].getEstInverse():
                    file.write(strArcInverse.format(
                        arcs[i].getNoeudDebut().getNom(),
                        arcs[i].getNoeudFin().getNom(),
                        arcs[i].getPoids())
                    )
                else:
                    file.write(strArc.format(
                        arcs[i].getNoeudDebut().getNom(),
                        arcs[i].getNoeudFin().getNom(),
                        arcs[i].getPoids())
                    )
            file.write("}" + retour)

        retour = ""
        noeuds = graphe.getNoeuds()
        arcs = graphe.getArcs()
        with open(destFile, 'w') as file:
            retour = "%0A%0A%20 "
            makeStrDigraph(file, retour)
            file.close()
        with open(destFileJs, 'w') as file:
            retour = " \n "
            file.write('function '+filenameJs+'() {')
            file.write('divGraph = document.getElementById("divGraph")' + retour) # noqa : E501
            file.write('var viz = new Viz();' + retour)
            file.write('viz.renderSVGElement(`' + retour)
            makeStrDigraph(file, retour)
            if baseName in GRAPHE_PSEUDO_REELS:
                coeffSvg = 2
            else:
                coeffSvg = 1.5

            file.write("""
            `).then(function(svg) {
                    txtObj = document.getElementById("txtGraph")
                    txtObj.data = ""
                    var w = svg.getAttribute("width")
                    w = parseInt(w.slice(0, -2))*""" + str(coeffSvg) + """
                    w = w.toString()
                    var h = svg.getAttribute("height")
                    h = parseInt(h.slice(0, -2))*""" + str(coeffSvg) + """
                    h = h.toString()
                    svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
                    svg.setAttribute('preserveAspectRatio', 'xMinYMin meet')
                    var s = new XMLSerializer();
                    var strSVG = s.serializeToString(svg)
                    divGraph.innerHTML = strSVG
                })
                .catch(error => {
                    // Create a new Viz instance
                    // (@see Caveats page for more info)
                    viz = new Viz();

                    // Possibly display the error
                    console.error(error);
                });
            """ + retour)
            file.write('}')
            file.close()

    def graphvizMakeDotAndJsFiles(self, baseName: str) -> None:
        """Crée tous les fichiers *.dot et *.js correspondants aux étapes d'une vue.

        - les fichiers *.dot pour l'affichage sur graphviz online
        - les fichiers *.js pour l'affichage directement dans la fenetre html

        Paramètres
        ----------
        - graphe   : Graphe - Une instance de la classe Graphe.
        - baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

        Remarques
        ---------
        - les fichiers sont stockés dans le répertoire ./graphviz_algo/baseName
        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        # On récupère le type d'algorithme
        algo = self.getAlgo()
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+algo+'/'+baseName
        # On supprime les répertoires s'ils existent
        if os.path.exists(dir):
            shutil.rmtree(dir)
        # On initialise l'index inital selon l'algorithme
        indexInitial = 0
        # On factorise le tableau des étapes
        etapes = self.getEtapes()
        if algo == "heuristique":
            indexInitial = 3
            for i in range(indexInitial, len(etapes) - 1):
                self.graphvizMakeDotAndJsFile(etapes[i], baseName)
        elif algo in ["eliminationCycles", "klein"]:
            indexInitial = 1
            for i in range(indexInitial, len(etapes)):
                self.graphvizMakeDotAndJsFile(etapes[i], baseName)

    def graphvizMakeHtml(self, baseName: str) -> None:
        """Crée une page html avec autant de liens que de graphes
        dans le dossier ./_graphviz_algo/baseName

        Paramètres
        ----------
        baseName : str - Le nom du dossier qui contient les fichiers *.dot
        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        #  Page vide
        title = {
            'title': '',
            'subtitle': ''
        }
        if baseName == 'gch':
            title["title"] = 'Cours heuristique'
            title["subtitle"] = 'GRAPHE DU COURS HEURISTIQUE'
        elif baseName == 'grousseau':
            title["title"] = 'Biblio Rousseau'
            title["subtitle"] = 'GRAPHE DE LA BIBLIO D\'ARTHUR ROUSSEAU'
        elif baseName == 'gmikhailiv':
            title["title"] = 'Rapport Mikhailiv'
            title["subtitle"] = 'GRAPHE DU RAPPORT DE YOSIP MIKHAILIV'
        elif baseName == 'gvelamena':
            title["title"] = 'Rapport VelaMena'
            title["subtitle"] = 'GRAPHE DU RAPPORT DE MARIE VELA-MENA'
        elif baseName in GRAPHE_PSEUDO_REELS:
            title["title"] = 'Données ' + baseName[1:].capitalize()
            title["subtitle"] = 'GRAPHE ' + baseName[1:].capitalize()
        else:
            title["title"] = "BUG CONDITION"
            title["subtitle"] = "BUG CONDITION"

        header = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
button {
cursor:pointer; margin: 4px 2px; padding: 5px 10px;
}
</style>
<title>""" + title['title'] + """</title>
<script src="../../js/viz.js"></script>
<script src="../../js/full.render.js"></script>
</head>
<body>\n"""
        footer = """</body></html>"""
        # On crée le répertoire s'il n'existe pas
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+self.getAlgo()+'/'+baseName
        htmlFile = dir+'/'+baseName+'.html'
        textDir = htmlDir+'/texte_'+self.getAlgo()+'/'+baseName
        textOnlineDir = '/texte_'+self.getAlgo()+'/'+baseName
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                initial_count += 1
        with open(htmlFile, 'w') as file:
            file.write(header)
            if initial_count == 0:
                file.write("<h1>PAGE VIDE</h1>\n")
            else:
                file.write("""<button><a href='../../index.html'> << Retour au
                menu Principal</a></button>""")
                # On adapte le texte
                algo = self.getAlgo()
                titreAlgo = ''
                if algo == 'heuristique':
                    titreAlgo = 'Méthode heuristique'
                elif algo == 'eliminationCycles':
                    titreAlgo = 'Méthode par élimination des Cycles'
                elif algo == 'klein':
                    titreAlgo = 'Algorithme de Klein'
                file.write("<h1>{} >> {}</h1>\n".format(
                    titreAlgo,
                    title["subtitle"].lower()
                ))
                file.write("""
<h3>Remarques :</h3>\n
<ul>\n
<li>Les liens permettent d'afficher les graphes étapes directement dans la page ou dans un nouvel onglet sur le site <a href="https://dreampuf.github.io/GraphvizOnline/" target="_blank">GraphvizOnline</a></li>\n
<li>On peut aussi afficher une version texte des étapes. <strong>Plusieurs simulations sont proposées.</strong> . Le <button style="color:red;">lien rouge</button> correspond à celle des graphes affichables.</li>\n
</ul>\n
                """) # noqa : E501
                file.write("""<div style="float: left; width: 15%">\n""")
                file.write('<ul>\n')
                file.write("<h4>Graphiques<br>Ci-contre</h4>\n")
                # for path in os.listdir(dir):
                for path in sorted(os.listdir(dir)):
                    if os.path.isfile(os.path.join(dir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == ".js":
                            file.write("<button onclick="+root+"()>Voir étape " + root[-2:] + " </button>\n") # noqa : E501
                            file.write("<script src=\"./"+path+"\"></script>\n") # noqa : E501
                file.write("<h4>GraphizOnline</h4>\n")
                # for path in os.listdir(dir):
                for path in sorted(os.listdir(dir)):
                    if os.path.isfile(os.path.join(dir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.dot':
                            currentDotFile = open(os.path.join(dir, path), "r")
                            currentStr = currentDotFile.readlines()[0]
                            file.write("<button><a href='https://dreampuf.github.io/GraphvizOnline/#"+currentStr+"' target='_blank'> Voir étape " + root[-2:]+ "</a></button>\n") # noqa : E501
                            currentDotFile.close()
                file.write('</ul>\n')
                file.write('</div>\n')
                file.write("""<div style="float: left; width: 15%">\n""")
                file.write('<ul>\n')
                file.write("<h4>Fichiers texte</h4>\n")
                # Un compteur pour l'affichage du style des étapes courantes
                cptMax = 0
                for path in os.listdir(textDir):
                    if os.path.isfile(os.path.join(textDir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.txt':
                            cptMax += 1
                cptMaxStr = '{:02d}'.format(cptMax)
                file.write("<button style=\"color:red;\" onclick=" + root + cptMaxStr + "txt()>Étapes correspondant aux graphes affichables</button>\n") # noqa : E501
                file.write("""
                <script>\n
                    function """ + root + cptMaxStr + """txt() {
                        divGraph = document.getElementById("divGraph")
                        divGraph.innerHTML = ""
                        txtObj = document.getElementById("txtGraph")
                        txtObj.data = \"../../.""" + os.path.join(textOnlineDir, "graphe"+cptMaxStr+".txt") + """ \"
                    }
                </script>\n
                """) # noqa : E501

                # for path in os.listdir(textDir):
                for path in sorted(os.listdir(textDir)):
                    if os.path.isfile(os.path.join(textDir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.txt' and root[-2:] != cptMaxStr:
                            file.write("<button onclick="+root+"txt()>Voir une autre simulation</button>\n") # noqa : E501
                            file.write("""
                            <script>\n
                                function """ + root + """txt() {
                                    divGraph = document.getElementById("divGraph")
                                    divGraph.innerHTML = ""
                                    txtObj = document.getElementById("txtGraph")
                                    txtObj.data = \"../../.""" + os.path.join(textOnlineDir, path) + """ \"
                                }
                            </script>\n
                            """) # noqa : E501
                file.write('</ul>\n')
                file.write("</div>\n")
                file.write("""
<div id="containerDivGraph" style="margin-left: 35%; height:600px; width:55%; border-left:1px solid black;" >\n
<div id="divGraph" style="margin-left: 20%; height:auto; width:90%"></div>\n
<object id="txtGraph" data="" type="text/plain" style="width: 100%; height: 100%;"></object>
</div>\n
                """) # noqa : E501
            file.write(footer)
            file.close()

    def texteMakeFile(self, baseName: str) -> None:
        """Crée un fichier texte avec les différents graphes étapes obtenus par
        application de l'algorithme appliqué.

        La propriété algo de la classe Vue, contient l'information sur
        l'algorithme utilisé.

        Paramètres
        ----------
        baseName : str - Le nom du dossier qui va contenir le fichier *.txt

        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        # On récupère le type d'algorithme
        algo = self.getAlgo()
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/texte_'+self.getAlgo()+'/'+baseName
        # On crée le répertoire s'il n'existe pas
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                initial_count += 1
        filename = 'graphe'+'{:02d}'.format(initial_count+1)
        destFile = dir+'/'+filename+'.txt'
        if algo == "heuristique":
            lines = self.consoleHeuristique().split("\\n")
        elif algo == "eliminationCycles":
            lines = self.consoleEliminationCycles().split("\\n")
        elif algo == "klein":
            lines = self.consoleAlgorithmeDeKlein().split("\\n")

        with open(destFile, 'w') as file:
            for line in lines:
                file.write(line)
            file.close()

# =========== ALGORITHME 1 : METHODE HEURISTIQUE =================

    def consoleHeuristique(self):
        """Renvoie les données après traitement par le controleur via l'algorithme
        de la méthode heuristique dans un string.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.simplification()
        >>> A_init = copy.deepcopy(A)
        >>> gInit = copy.deepcopy(g)
        >>> # On choisit fictivement A qui reçoit 7
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[1].setCapital(7)
        >>> g1 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[1])
        >>> g.getNoeuds()[1].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(5)
        >>> g2 = copy.deepcopy(g)
        >>> g.getArcs()[1].setPoids(4)
        >>> g.getArcs()[1].setNom("C-4->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g3 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[0].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(3)
        >>> g4 = copy.deepcopy(g)
        >>> g.getArcs()[0].setPoids(1)
        >>> g.getArcs()[0].setNom("C-1->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g5 = copy.deepcopy(g)
        >>> vue = Vue(gInit,[A_init, 7, 23, gInit, g1, g2, g3, g4, g5, g5],"heuristique")
        >>> print(vue.consoleHeuristique())
        =====================================================
        ======= ALGORITHME 1 : METHODE HEURISTIQUE ==========
        =====================================================
        Première entreprise choisie : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0)
        Cette entreprise reçoit     : 7
        =====================================================
        Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale initiale n°0 : 24
        =====================================================
        Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°1 : 17
        =====================================================
        Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°2 : 12
        =====================================================
        Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°3 : 7
        =====================================================
        Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°4 : 4
        =====================================================
        Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°5 : 1
        =====================================================
        Baisse de la dette globale obtenue : 23
        =====================================================
        """  # noqa : E501
        pass
        sortie = ''
        sortie += "=====================================================\n"
        sortie += "======= ALGORITHME 1 : METHODE HEURISTIQUE ==========\n"
        sortie += "=====================================================\n"
        sortie += f"Première entreprise choisie : {self.getEtapes()[0]}\n"
        sortie += f"Cette entreprise reçoit     : {self.getEtapes()[1]}\n"
        sortie += "=====================================================\n"
        sortie += f'Graphe initial n°0 : {self.getEtapes()[3]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[3].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[3].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[3].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        # Le dernier graphe est toujours en doublon avec la méthode heuristique
        for index in range(4, len(self.getEtapes())-1):
            sortie += f'Graphe intermediaire n°{index-3} : {self.getEtapes()[index]}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[index].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise,self.getEtapes()[0].getNom(),self.getEtapes()[1])}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            if self.getEtapes()[index].hasArc():
                sortie += f'Dette Globale n°{index-3} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
            else:
                sortie += f'Dette Globale n°{index-3} : 0\n'  # noqa : E501
            sortie += "=====================================================\n"
            index += 1
        sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[2]}\n' # noqa : E501
        sortie += "======================================================\n"

        return sortie[:-2]

# =========== ALGORITHME 2 : ÉLIMINATION DES CYCLES ==============

    def consoleEliminationCycles(self):
        """Renvoie les données après traitement par le controleur via l'algorithme
        par élimination des cycles dans un string.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.simplification()
        >>> A_init = copy.deepcopy(A)
        >>> gInit = copy.deepcopy(g)
        >>> # On choisit fictivement A qui reçoit 7
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[1].setCapital(7)
        >>> g1 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[1])
        >>> g.getNoeuds()[1].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(5)
        >>> g2 = copy.deepcopy(g)
        >>> g.getArcs()[1].setPoids(4)
        >>> g.getArcs()[1].setNom("C-4->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g3 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[0].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(3)
        >>> g4 = copy.deepcopy(g)
        >>> g.getArcs()[0].setPoids(1)
        >>> g.getArcs()[0].setNom("C-1->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g5 = copy.deepcopy(g)
        >>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
        >>> print(vue.consoleEliminationCycles())
        =====================================================
        ===== ALGORITHME 2 : ELIMINATION DES CYCLES =========
        =====================================================
        Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale initiale n°0 : 24
        =====================================================
        Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°1 : 17
        =====================================================
        Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°2 : 12
        =====================================================
        Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°3 : 7
        =====================================================
        Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°4 : 4
        =====================================================
        Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°5 : 1
        =====================================================
        Baisse de la dette globale obtenue : 23
        =====================================================
        """  # noqa : E501
        pass
        sortie = ''
        sortie += "=====================================================\n"
        sortie += "===== ALGORITHME 2 : ELIMINATION DES CYCLES =========\n"
        sortie += "=====================================================\n"
        sortie += f'Graphe initial n°0 : {self.getEtapes()[1]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[1].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[1].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[1].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        for index in range(2, len(self.getEtapes())):
            sortie += f'Graphe intermediaire n°{index-1} : {self.getEtapes()[index]}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[index].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise)}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            sortie += f'Dette Globale n°{index-1} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
            sortie += "=====================================================\n"
        sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[0]}\n' # noqa : E501
        sortie += "======================================================\n"

        return sortie[:-2]

# =========== ALGORITHME 3 : ALGORITHME DE KLEIN =================

    def consoleAlgorithmeDeKlein(self):
        """Renvoie les données après traitement par le controleur via l'algorithme de Klein
        dans un string.

        Tests
        -----
        >>> g = Graphe('graphe')
        >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
        >>> # arcs partant de A
        >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
        >>> # arcs arrivant sur A
        >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
        >>> # arc entre B et C
        >>> BC = Arc('BC',B,C,5)
        >>> g.setNoeuds([A,B,C])
        >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
        >>> g.simplification()
        >>> A_init = copy.deepcopy(A)
        >>> gInit = copy.deepcopy(g)
        >>> # On choisit fictivement A qui reçoit 7
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[1].setCapital(7)
        >>> g1 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[1])
        >>> g.getNoeuds()[1].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(5)
        >>> g2 = copy.deepcopy(g)
        >>> g.getArcs()[1].setPoids(4)
        >>> g.getArcs()[1].setNom("C-4->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g3 = copy.deepcopy(g)
        >>> g.removeArc(g.getArcs()[0])
        >>> g.getNoeuds()[0].setCapital(2)
        >>> g.getNoeuds()[2].setCapital(3)
        >>> g4 = copy.deepcopy(g)
        >>> g.getArcs()[0].setPoids(1)
        >>> g.getArcs()[0].setNom("C-1->A")
        >>> g.getNoeuds()[0].setCapital(5)
        >>> g.getNoeuds()[2].setCapital(0)
        >>> g5 = copy.deepcopy(g)
        >>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
        >>> print(vue.consoleAlgorithmeDeKlein())
        =====================================================
        ===== ALGORITHME 3 : KLEIN ==========================
        =====================================================
        Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
        Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale initiale n°0 : 24
        =====================================================
        Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°1 : 17
        ====================================================
        Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°2 : 12
        ====================================================
        Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°3 : 7
        ====================================================
        Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°4 : 4
        ====================================================
        Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
        -----------------------------------------------------
        Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
        Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
        Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
        -----------------------------------------------------
        Dette Globale n°5 : 1
        ====================================================
        Baisse de la dette globale obtenue : 23
        ====================================================
        """  # noqa : E501
        pass
        sortie = ''
        # On génère les graphes
        sortie += "=====================================================\n"
        sortie += "===== ALGORITHME 3 : KLEIN ==========================\n"
        sortie += "=====================================================\n"
        sortie += f'Graphe initial n°0 : {self.getEtapes()[1]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[1].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[1].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[1].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        if self.getEtapes()[1].estSimplifie():
            indexInitial = 2
        else:
            sortie += f'Graphe simplifié n°1 : {self.getEtapes()[2]}\n'
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[2].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[2].positionNette(entreprise) }\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            sortie += f'Dette Globale initiale n°1 : {self.getEtapes()[2].detteGlobale()}\n'  # noqa : E501
            sortie += "=====================================================\n"
            indexInitial = 3

        for index in range(indexInitial, len(self.getEtapes())):
            sortie += f'Graphe intermediaire n°{index-1} : {self.getEtapes()[index]}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            for entreprise in self.getEtapes()[index].getEntreprises():
                sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise)}\n'  # noqa : E501
            sortie += "-----------------------------------------------------\n"
            sortie += f'Dette Globale n°{index-1} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
            sortie += "====================================================\n"

        sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[0]}\n' # noqa : E501
        sortie += "=====================================================\n"

        return sortie[:-2]

Methods

def consoleAlgorithmeDeKlein(self)

Renvoie les données après traitement par le controleur via l'algorithme de Klein dans un string.

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> g.simplification()
>>> A_init = copy.deepcopy(A)
>>> gInit = copy.deepcopy(g)
>>> # On choisit fictivement A qui reçoit 7
>>> g.removeArc(g.getArcs()[0])
>>> g.getNoeuds()[1].setCapital(7)
>>> g1 = copy.deepcopy(g)
>>> g.removeArc(g.getArcs()[1])
>>> g.getNoeuds()[1].setCapital(2)
>>> g.getNoeuds()[2].setCapital(5)
>>> g2 = copy.deepcopy(g)
>>> g.getArcs()[1].setPoids(4)
>>> g.getArcs()[1].setNom("C-4->A")
>>> g.getNoeuds()[0].setCapital(5)
>>> g.getNoeuds()[2].setCapital(0)
>>> g3 = copy.deepcopy(g)
>>> g.removeArc(g.getArcs()[0])
>>> g.getNoeuds()[0].setCapital(2)
>>> g.getNoeuds()[2].setCapital(3)
>>> g4 = copy.deepcopy(g)
>>> g.getArcs()[0].setPoids(1)
>>> g.getArcs()[0].setNom("C-1->A")
>>> g.getNoeuds()[0].setCapital(5)
>>> g.getNoeuds()[2].setCapital(0)
>>> g5 = copy.deepcopy(g)
>>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
>>> print(vue.consoleAlgorithmeDeKlein())
=====================================================
===== ALGORITHME 3 : KLEIN ==========================
=====================================================
Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale initiale n°0 : 24
=====================================================
Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°1 : 17
====================================================
Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
-----------------------------------------------------
Dette Globale n°2 : 12
====================================================
Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°3 : 7
====================================================
Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
-----------------------------------------------------
Dette Globale n°4 : 4
====================================================
Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°5 : 1
====================================================
Baisse de la dette globale obtenue : 23
====================================================
Expand source code
def consoleAlgorithmeDeKlein(self):
    """Renvoie les données après traitement par le controleur via l'algorithme de Klein
    dans un string.

    Tests
    -----
    >>> g = Graphe('graphe')
    >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
    >>> # arcs partant de A
    >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
    >>> # arcs arrivant sur A
    >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
    >>> # arc entre B et C
    >>> BC = Arc('BC',B,C,5)
    >>> g.setNoeuds([A,B,C])
    >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
    >>> g.simplification()
    >>> A_init = copy.deepcopy(A)
    >>> gInit = copy.deepcopy(g)
    >>> # On choisit fictivement A qui reçoit 7
    >>> g.removeArc(g.getArcs()[0])
    >>> g.getNoeuds()[1].setCapital(7)
    >>> g1 = copy.deepcopy(g)
    >>> g.removeArc(g.getArcs()[1])
    >>> g.getNoeuds()[1].setCapital(2)
    >>> g.getNoeuds()[2].setCapital(5)
    >>> g2 = copy.deepcopy(g)
    >>> g.getArcs()[1].setPoids(4)
    >>> g.getArcs()[1].setNom("C-4->A")
    >>> g.getNoeuds()[0].setCapital(5)
    >>> g.getNoeuds()[2].setCapital(0)
    >>> g3 = copy.deepcopy(g)
    >>> g.removeArc(g.getArcs()[0])
    >>> g.getNoeuds()[0].setCapital(2)
    >>> g.getNoeuds()[2].setCapital(3)
    >>> g4 = copy.deepcopy(g)
    >>> g.getArcs()[0].setPoids(1)
    >>> g.getArcs()[0].setNom("C-1->A")
    >>> g.getNoeuds()[0].setCapital(5)
    >>> g.getNoeuds()[2].setCapital(0)
    >>> g5 = copy.deepcopy(g)
    >>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
    >>> print(vue.consoleAlgorithmeDeKlein())
    =====================================================
    ===== ALGORITHME 3 : KLEIN ==========================
    =====================================================
    Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale initiale n°0 : 24
    =====================================================
    Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°1 : 17
    ====================================================
    Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°2 : 12
    ====================================================
    Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°3 : 7
    ====================================================
    Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°4 : 4
    ====================================================
    Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°5 : 1
    ====================================================
    Baisse de la dette globale obtenue : 23
    ====================================================
    """  # noqa : E501
    pass
    sortie = ''
    # On génère les graphes
    sortie += "=====================================================\n"
    sortie += "===== ALGORITHME 3 : KLEIN ==========================\n"
    sortie += "=====================================================\n"
    sortie += f'Graphe initial n°0 : {self.getEtapes()[1]}\n'
    sortie += "-----------------------------------------------------\n"
    for entreprise in self.getEtapes()[1].getEntreprises():
        sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[1].positionNette(entreprise) }\n'  # noqa : E501
    sortie += "-----------------------------------------------------\n"
    sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[1].detteGlobale()}\n'  # noqa : E501
    sortie += "=====================================================\n"
    if self.getEtapes()[1].estSimplifie():
        indexInitial = 2
    else:
        sortie += f'Graphe simplifié n°1 : {self.getEtapes()[2]}\n'
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[2].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[2].positionNette(entreprise) }\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale initiale n°1 : {self.getEtapes()[2].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
        indexInitial = 3

    for index in range(indexInitial, len(self.getEtapes())):
        sortie += f'Graphe intermediaire n°{index-1} : {self.getEtapes()[index]}\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[index].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise)}\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale n°{index-1} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
        sortie += "====================================================\n"

    sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[0]}\n' # noqa : E501
    sortie += "=====================================================\n"

    return sortie[:-2]
def consoleEliminationCycles(self)

Renvoie les données après traitement par le controleur via l'algorithme par élimination des cycles dans un string.

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> g.simplification()
>>> A_init = copy.deepcopy(A)
>>> gInit = copy.deepcopy(g)
>>> # On choisit fictivement A qui reçoit 7
>>> g.removeArc(g.getArcs()[0])
>>> g.getNoeuds()[1].setCapital(7)
>>> g1 = copy.deepcopy(g)
>>> g.removeArc(g.getArcs()[1])
>>> g.getNoeuds()[1].setCapital(2)
>>> g.getNoeuds()[2].setCapital(5)
>>> g2 = copy.deepcopy(g)
>>> g.getArcs()[1].setPoids(4)
>>> g.getArcs()[1].setNom("C-4->A")
>>> g.getNoeuds()[0].setCapital(5)
>>> g.getNoeuds()[2].setCapital(0)
>>> g3 = copy.deepcopy(g)
>>> g.removeArc(g.getArcs()[0])
>>> g.getNoeuds()[0].setCapital(2)
>>> g.getNoeuds()[2].setCapital(3)
>>> g4 = copy.deepcopy(g)
>>> g.getArcs()[0].setPoids(1)
>>> g.getArcs()[0].setNom("C-1->A")
>>> g.getNoeuds()[0].setCapital(5)
>>> g.getNoeuds()[2].setCapital(0)
>>> g5 = copy.deepcopy(g)
>>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
>>> print(vue.consoleEliminationCycles())
=====================================================
===== ALGORITHME 2 : ELIMINATION DES CYCLES =========
=====================================================
Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale initiale n°0 : 24
=====================================================
Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°1 : 17
=====================================================
Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
-----------------------------------------------------
Dette Globale n°2 : 12
=====================================================
Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°3 : 7
=====================================================
Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
-----------------------------------------------------
Dette Globale n°4 : 4
=====================================================
Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°5 : 1
=====================================================
Baisse de la dette globale obtenue : 23
=====================================================
Expand source code
def consoleEliminationCycles(self):
    """Renvoie les données après traitement par le controleur via l'algorithme
    par élimination des cycles dans un string.

    Tests
    -----
    >>> g = Graphe('graphe')
    >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
    >>> # arcs partant de A
    >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
    >>> # arcs arrivant sur A
    >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
    >>> # arc entre B et C
    >>> BC = Arc('BC',B,C,5)
    >>> g.setNoeuds([A,B,C])
    >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
    >>> g.simplification()
    >>> A_init = copy.deepcopy(A)
    >>> gInit = copy.deepcopy(g)
    >>> # On choisit fictivement A qui reçoit 7
    >>> g.removeArc(g.getArcs()[0])
    >>> g.getNoeuds()[1].setCapital(7)
    >>> g1 = copy.deepcopy(g)
    >>> g.removeArc(g.getArcs()[1])
    >>> g.getNoeuds()[1].setCapital(2)
    >>> g.getNoeuds()[2].setCapital(5)
    >>> g2 = copy.deepcopy(g)
    >>> g.getArcs()[1].setPoids(4)
    >>> g.getArcs()[1].setNom("C-4->A")
    >>> g.getNoeuds()[0].setCapital(5)
    >>> g.getNoeuds()[2].setCapital(0)
    >>> g3 = copy.deepcopy(g)
    >>> g.removeArc(g.getArcs()[0])
    >>> g.getNoeuds()[0].setCapital(2)
    >>> g.getNoeuds()[2].setCapital(3)
    >>> g4 = copy.deepcopy(g)
    >>> g.getArcs()[0].setPoids(1)
    >>> g.getArcs()[0].setNom("C-1->A")
    >>> g.getNoeuds()[0].setCapital(5)
    >>> g.getNoeuds()[2].setCapital(0)
    >>> g5 = copy.deepcopy(g)
    >>> vue = Vue(gInit,[23, gInit, g1, g2, g3, g4, g5],"heuristique")
    >>> print(vue.consoleEliminationCycles())
    =====================================================
    ===== ALGORITHME 2 : ELIMINATION DES CYCLES =========
    =====================================================
    Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale initiale n°0 : 24
    =====================================================
    Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°1 : 17
    =====================================================
    Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°2 : 12
    =====================================================
    Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°3 : 7
    =====================================================
    Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°4 : 4
    =====================================================
    Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : 6
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°5 : 1
    =====================================================
    Baisse de la dette globale obtenue : 23
    =====================================================
    """  # noqa : E501
    pass
    sortie = ''
    sortie += "=====================================================\n"
    sortie += "===== ALGORITHME 2 : ELIMINATION DES CYCLES =========\n"
    sortie += "=====================================================\n"
    sortie += f'Graphe initial n°0 : {self.getEtapes()[1]}\n'
    sortie += "-----------------------------------------------------\n"
    for entreprise in self.getEtapes()[1].getEntreprises():
        sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[1].positionNette(entreprise) }\n'  # noqa : E501
    sortie += "-----------------------------------------------------\n"
    sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[1].detteGlobale()}\n'  # noqa : E501
    sortie += "=====================================================\n"
    for index in range(2, len(self.getEtapes())):
        sortie += f'Graphe intermediaire n°{index-1} : {self.getEtapes()[index]}\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[index].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise)}\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        sortie += f'Dette Globale n°{index-1} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
        sortie += "=====================================================\n"
    sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[0]}\n' # noqa : E501
    sortie += "======================================================\n"

    return sortie[:-2]
def consoleHeuristique(self)

Renvoie les données après traitement par le controleur via l'algorithme de la méthode heuristique dans un string.

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> g.simplification()
>>> A_init = copy.deepcopy(A)
>>> gInit = copy.deepcopy(g)
>>> # On choisit fictivement A qui reçoit 7
>>> g.removeArc(g.getArcs()[0])
>>> g.getNoeuds()[1].setCapital(7)
>>> g1 = copy.deepcopy(g)
>>> g.removeArc(g.getArcs()[1])
>>> g.getNoeuds()[1].setCapital(2)
>>> g.getNoeuds()[2].setCapital(5)
>>> g2 = copy.deepcopy(g)
>>> g.getArcs()[1].setPoids(4)
>>> g.getArcs()[1].setNom("C-4->A")
>>> g.getNoeuds()[0].setCapital(5)
>>> g.getNoeuds()[2].setCapital(0)
>>> g3 = copy.deepcopy(g)
>>> g.removeArc(g.getArcs()[0])
>>> g.getNoeuds()[0].setCapital(2)
>>> g.getNoeuds()[2].setCapital(3)
>>> g4 = copy.deepcopy(g)
>>> g.getArcs()[0].setPoids(1)
>>> g.getArcs()[0].setNom("C-1->A")
>>> g.getNoeuds()[0].setCapital(5)
>>> g.getNoeuds()[2].setCapital(0)
>>> g5 = copy.deepcopy(g)
>>> vue = Vue(gInit,[A_init, 7, 23, gInit, g1, g2, g3, g4, g5, g5],"heuristique")
>>> print(vue.consoleHeuristique())
=====================================================
======= ALGORITHME 1 : METHODE HEURISTIQUE ==========
=====================================================
Première entreprise choisie : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0)
Cette entreprise reçoit     : 7
=====================================================
Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale initiale n°0 : 24
=====================================================
Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°1 : 17
=====================================================
Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
-----------------------------------------------------
Dette Globale n°2 : 12
=====================================================
Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°3 : 7
=====================================================
Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
-----------------------------------------------------
Dette Globale n°4 : 4
=====================================================
Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
-----------------------------------------------------
Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : -1
Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
-----------------------------------------------------
Dette Globale n°5 : 1
=====================================================
Baisse de la dette globale obtenue : 23
=====================================================
Expand source code
def consoleHeuristique(self):
    """Renvoie les données après traitement par le controleur via l'algorithme
    de la méthode heuristique dans un string.

    Tests
    -----
    >>> g = Graphe('graphe')
    >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
    >>> # arcs partant de A
    >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
    >>> # arcs arrivant sur A
    >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
    >>> # arc entre B et C
    >>> BC = Arc('BC',B,C,5)
    >>> g.setNoeuds([A,B,C])
    >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
    >>> g.simplification()
    >>> A_init = copy.deepcopy(A)
    >>> gInit = copy.deepcopy(g)
    >>> # On choisit fictivement A qui reçoit 7
    >>> g.removeArc(g.getArcs()[0])
    >>> g.getNoeuds()[1].setCapital(7)
    >>> g1 = copy.deepcopy(g)
    >>> g.removeArc(g.getArcs()[1])
    >>> g.getNoeuds()[1].setCapital(2)
    >>> g.getNoeuds()[2].setCapital(5)
    >>> g2 = copy.deepcopy(g)
    >>> g.getArcs()[1].setPoids(4)
    >>> g.getArcs()[1].setNom("C-4->A")
    >>> g.getNoeuds()[0].setCapital(5)
    >>> g.getNoeuds()[2].setCapital(0)
    >>> g3 = copy.deepcopy(g)
    >>> g.removeArc(g.getArcs()[0])
    >>> g.getNoeuds()[0].setCapital(2)
    >>> g.getNoeuds()[2].setCapital(3)
    >>> g4 = copy.deepcopy(g)
    >>> g.getArcs()[0].setPoids(1)
    >>> g.getArcs()[0].setNom("C-1->A")
    >>> g.getNoeuds()[0].setCapital(5)
    >>> g.getNoeuds()[2].setCapital(0)
    >>> g5 = copy.deepcopy(g)
    >>> vue = Vue(gInit,[A_init, 7, 23, gInit, g1, g2, g3, g4, g5, g5],"heuristique")
    >>> print(vue.consoleHeuristique())
    =====================================================
    ======= ALGORITHME 1 : METHODE HEURISTIQUE ==========
    =====================================================
    Première entreprise choisie : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0)
    Cette entreprise reçoit     : 7
    =====================================================
    Graphe initial n°0 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-7->B', 'A-3->C', 'B-5->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['B', 'C'], nbArcs=3, capital=0) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=['A', 'C'], nbArcs=2, capital=0) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale initiale n°0 : 24
    =====================================================
    Graphe intermediaire n°1 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'B-5->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=['C'], nbArcs=1, capital=7) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A', 'B'], nbArcs=3, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°1 : 17
    =====================================================
    Graphe intermediaire n°2 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-9->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=0) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=5) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°2 : 12
    =====================================================
    Graphe intermediaire n°3 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['A-3->C', 'C-4->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=2, capital=5) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=2, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°3 : 7
    =====================================================
    Graphe intermediaire n°4 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-4->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=2) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=3) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°4 : 4
    =====================================================
    Graphe intermediaire n°5 : Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['C-1->A'])
    -----------------------------------------------------
    Etat entreprise A : Noeud(nom=A, voisins=['C'], nbArcs=1, capital=5) - position Nette : -1
    Etat entreprise B : Noeud(nom=B, voisins=[], nbArcs=0, capital=2) - position Nette : 2
    Etat entreprise C : Noeud(nom=C, voisins=['A'], nbArcs=1, capital=0) - position Nette : -1
    -----------------------------------------------------
    Dette Globale n°5 : 1
    =====================================================
    Baisse de la dette globale obtenue : 23
    =====================================================
    """  # noqa : E501
    pass
    sortie = ''
    sortie += "=====================================================\n"
    sortie += "======= ALGORITHME 1 : METHODE HEURISTIQUE ==========\n"
    sortie += "=====================================================\n"
    sortie += f"Première entreprise choisie : {self.getEtapes()[0]}\n"
    sortie += f"Cette entreprise reçoit     : {self.getEtapes()[1]}\n"
    sortie += "=====================================================\n"
    sortie += f'Graphe initial n°0 : {self.getEtapes()[3]}\n'
    sortie += "-----------------------------------------------------\n"
    for entreprise in self.getEtapes()[3].getEntreprises():
        sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[3].positionNette(entreprise) }\n'  # noqa : E501
    sortie += "-----------------------------------------------------\n"
    sortie += f'Dette Globale initiale n°0 : {self.getEtapes()[3].detteGlobale()}\n'  # noqa : E501
    sortie += "=====================================================\n"
    # Le dernier graphe est toujours en doublon avec la méthode heuristique
    for index in range(4, len(self.getEtapes())-1):
        sortie += f'Graphe intermediaire n°{index-3} : {self.getEtapes()[index]}\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        for entreprise in self.getEtapes()[index].getEntreprises():
            sortie += f'Etat entreprise {entreprise.getNom()} : {entreprise} - position Nette : {self.getEtapes()[index].positionNette(entreprise,self.getEtapes()[0].getNom(),self.getEtapes()[1])}\n'  # noqa : E501
        sortie += "-----------------------------------------------------\n"
        if self.getEtapes()[index].hasArc():
            sortie += f'Dette Globale n°{index-3} : {self.getEtapes()[index].detteGlobale()}\n'  # noqa : E501
        else:
            sortie += f'Dette Globale n°{index-3} : 0\n'  # noqa : E501
        sortie += "=====================================================\n"
        index += 1
    sortie += f'Baisse de la dette globale obtenue : {self.getEtapes()[2]}\n' # noqa : E501
    sortie += "======================================================\n"

    return sortie[:-2]
def getAlgo(self) ‑> str

Retourne le type d'algorithme utilisé.

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> g.removeArc(AB1)
>>> g2 = copy.deepcopy(g)
>>> g.removeArc(BC)
>>> g3 = copy.deepcopy(g)
>>> vue = Vue(g,[A,5,g2,g3],"klein")
>>> print(vue.getAlgo())
klein
Expand source code
def getAlgo(self) -> str:
    """Retourne le type d'algorithme utilisé.

    Tests
    -----
    >>> g = Graphe('graphe')
    >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
    >>> # arcs partant de A
    >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
    >>> # arcs arrivant sur A
    >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
    >>> # arc entre B et C
    >>> BC = Arc('BC',B,C,5)
    >>> g.setNoeuds([A,B,C])
    >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
    >>> g.removeArc(AB1)
    >>> g2 = copy.deepcopy(g)
    >>> g.removeArc(BC)
    >>> g3 = copy.deepcopy(g)
    >>> vue = Vue(g,[A,5,g2,g3],"klein")
    >>> print(vue.getAlgo())
    klein
    """
    pass
    return self.algo
def getEtapes(self) ‑> list

Retourne le tableaux des etapes, états successifs du graphe, pour l'algorithme.

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> g.removeArc(AB1)
>>> g2 = copy.deepcopy(g)
>>> g.removeArc(BC)
>>> g3 = copy.deepcopy(g)
>>> vue = Vue(g,[A,5,g2,g3])
>>> for i in vue.getEtapes():
...     print(i)
...
Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
5
Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
Expand source code
def getEtapes(self) -> list:
    """Retourne le tableaux des etapes, états successifs du graphe, pour l'algorithme.

    Tests
    -----
    >>> g = Graphe('graphe')
    >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
    >>> # arcs partant de A
    >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
    >>> # arcs arrivant sur A
    >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
    >>> # arc entre B et C
    >>> BC = Arc('BC',B,C,5)
    >>> g.setNoeuds([A,B,C])
    >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
    >>> g.removeArc(AB1)
    >>> g2 = copy.deepcopy(g)
    >>> g.removeArc(BC)
    >>> g3 = copy.deepcopy(g)
    >>> vue = Vue(g,[A,5,g2,g3])
    >>> for i in vue.getEtapes():
    ...     print(i)
    ...
    Noeud(nom=A, voisins=['B', 'C'], nbArcs=4, capital=0)
    5
    Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2', 'BC'])
    Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB2', 'AC', 'CA1', 'CA2'])
    """  # noqa : E501
    pass
    return self.etapes
def getGraphe(self) ‑> models.graphe.Graphe

Retourne l'instance du graphe de la Vue.

Tests

>>> g = Graphe('graphe')
>>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
>>> # arcs partant de A
>>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
>>> # arcs arrivant sur A
>>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
>>> # arc entre B et C
>>> BC = Arc('BC',B,C,5)
>>> g.setNoeuds([A,B,C])
>>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
>>> vue = Vue(g)
>>> print(vue.getGraphe())
Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB1', 'AB2', 'AC', 'CA1', 'CA2', 'BC'])
Expand source code
def getGraphe(self) -> Graphe:
    """Retourne l'instance du graphe de la Vue.

    Tests
    -----
    >>> g = Graphe('graphe')
    >>> A,B,C = Noeud('A'),Noeud('B'),Noeud('C')
    >>> # arcs partant de A
    >>> AB1,AB2,AC = Arc('AB1',A,B,5),Arc('AB2',A,B,2),Arc('AC',A,C,3)
    >>> # arcs arrivant sur A
    >>> CA1,CA2 = Arc('CA1',C,A,8),Arc('CA2',C,A,1)
    >>> # arc entre B et C
    >>> BC = Arc('BC',B,C,5)
    >>> g.setNoeuds([A,B,C])
    >>> g.setArcs([AB1,AB2,AC,CA1,CA2,BC])
    >>> vue = Vue(g)
    >>> print(vue.getGraphe())
    Graphe(nom=graphe, noeuds=['A', 'B', 'C'], arcs=['AB1', 'AB2', 'AC', 'CA1', 'CA2', 'BC'])
    """  # noqa : E501
    pass
    return self.graphe
def graphvizMakeDotAndJsFile(self, graphe: models.graphe.Graphe, baseName: str) ‑> None

Crée deux fichiers :

  • un fichier *.dot correspondant à un graphe dans le dossier ./graphviz/baseName pour l'affichage sur graphviz online
  • un fichier *.js correspondant à un graphe dans le dossier ./graphviz/baseName pour l'affichage directement dans la fenetre html

Paramètres

  • graphe : Graphe - Une instance de la classe Graphe.
  • baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

Remarque

Ressources pour rendu graphviz dans le navigateur

Expand source code
def graphvizMakeDotAndJsFile(self, graphe: Graphe, baseName: str) -> None:
    """Crée deux fichiers :

    - un fichier *.dot correspondant à un graphe dans le dossier ./graphviz/baseName
    pour l'affichage sur graphviz online
    - un fichier *.js  correspondant à un graphe dans le dossier ./graphviz/baseName
    pour l'affichage directement dans la fenetre html

    Paramètres
    ----------
    - graphe   : Graphe - Une instance de la classe Graphe.
    - baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

    Remarque
    --------
    Ressources pour rendu graphviz dans le navigateur

    - https://github.com/mdaines/viz.js/wiki
    - https://github.com/mdaines/viz.js/wiki/Usage
    - https://github.com/mdaines/viz.js/releases
    - https://github.com/mdaines/viz.js

    """ # noqa : E501
    pass
    assert isinstance(baseName, str), "baseName doit être un string"
    assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

    # On crée le répertoire s'il n'existe pas
    htmlDir = './vuesTexteEtHtml'
    dir = htmlDir+'/graphviz_'+self.getAlgo()+'/'+baseName
    if not os.path.exists(dir):
        os.makedirs(dir)
    initial_count_dot = 0
    initial_count_js = 0
    for path in os.listdir(dir):
        if os.path.isfile(os.path.join(dir, path)):
            root, extension = os.path.splitext(path)
            if extension == ".dot":
                initial_count_dot += 1
            if extension == ".js":
                initial_count_js += 1
    filenameDot = 'graphe'+'{:02d}'.format(initial_count_dot+1)
    filenameJs = 'graphe'+'{:02d}'.format(initial_count_js+1)
    destFile = dir+'/'+filenameDot+'.dot'
    destFileJs = dir+'/'+filenameJs+'.js'

    # Une fonction auxiliaire pour fixer les positions des noeuds
    def position(label, baseName, k=0, n=1, module=3):
        position = ''
        if baseName in ['gch', 'gvelamena']:
            if label == 'A':
                position = "0,4!"
            elif label == 'B':
                position = "3,6!"
            elif label == 'C':
                position = "6,4!"
        elif baseName == 'grousseau':
            if label == 'A':
                position = "0,4!"
            elif label == 'B':
                position = "3,6!"
            elif label == 'C':
                position = "6,4!"
            elif label == 'D':
                position = "6,2!"
            elif label == 'E':
                position = "3,0!"
            elif label == 'F':
                position = "0,2!"
        elif baseName == 'gmikhailiv':
            if label == 'A':
                position = "0,4!"
            elif label == 'B':
                position = "6,4!"
            elif label == 'C':
                position = "3,0!"
            elif label == 'D':
                position = "3,6!"
            elif label == 'E':
                position = "3,3!"
        elif baseName in GRAPHE_PSEUDO_REELS:
            if algo == 'heuristique':
                # position = str(module*cos(2*k*pi/n)) + "," + str(module*sin(2*k*pi/n)) + "!" # noqa : E501
                position = ""
            else:
                position = ""
        else:
            position = ""
        return position

    algo = self.getAlgo()
    etapes = self.getEtapes()
    titre = ""
    detteInitialeTxt = "Dette globale initiale : "
    baisseDettecouranteTxt = "Baisse courante de la dette : "
    if algo == 'heuristique':
        titre = "Méthode heuristique"
        detteInitiale = etapes[3].detteGlobale()
        detteInitialeTxt += str(detteInitiale)
        detteCourante = etapes[initial_count_js+1+2].detteGlobale()
        entrepriseChoisieHeuristique = etapes[0]
        donEntreprise = etapes[1]
        precisionHeuristique = f"Initialement, {entrepriseChoisieHeuristique.getNom()} reçoit {donEntreprise}" # noqa : E501
    elif algo == "eliminationCycles":
        titre = "Méthode par éliminations des cycles"
        detteInitiale = etapes[1].detteGlobale()
        detteInitialeTxt += str(detteInitiale)
        detteCourante = etapes[initial_count_js+1].detteGlobale()
        precisionHeuristique = ""
    elif algo == "klein":
        titre = "Algorithme de Klein"
        detteInitiale = etapes[1].detteGlobale()
        detteInitialeTxt += str(detteInitiale)
        detteCourante = etapes[initial_count_js+1].detteGlobale()
        precisionHeuristique = ""
    else:
        titre = "BUG TITRE"
        detteInitialeTxt = "BUG SOUS-TITRE"
        baisseDettecouranteTxt = "BUG BAISSE COURANTE"
        precisionHeuristique = "BUG PRECISION HEURISTIQUE"
    if algo in ['heuristique', 'eliminationCycles', 'klein']:
        baisseDettecouranteTxt += str(detteInitiale - detteCourante)

    # Une fonction auxiliaire pour factoriser l'écriture du code
    # du string au format *.dot
    if baseName in GRAPHE_PSEUDO_REELS:
        moteur = 'dot'
    else:
        moteur = 'neato'

    def makeStrDigraph(file, retour):
        file.write("digraph G {" + retour)
        file.write(retour)
        # file.write("# On force le moteur neato " + retour)
        # file.write("layout=neato " + retour)
        file.write("# On force le moteur " + moteur + " " + retour)
        file.write("layout=" + moteur + " " + retour)
        file.write(retour)
        file.write("# Le titre " + retour)
        file.write('labelloc = "t" ' + retour)
        file.write('label = <' + retour)
        file.write('<table border ="0">' + retour)
        file.write(f'<tr><td><FONT POINT-SIZE="30.0" color="red">{titre}</FONT></td></tr>' + retour) # noqa : E501
        file.write(f'<tr><td>{detteInitialeTxt}</td></tr>' + retour)
        file.write(f'<tr><td>{baisseDettecouranteTxt}</td></tr>' + retour)
        file.write(f'<tr><td>{precisionHeuristique}</td></tr>' + retour)
        file.write('</table>' + retour)
        file.write('>' + retour)
        file.write(retour)
        file.write("# Les noeuds " + retour)
        for i in range(len(noeuds)):
            # Un string pour factoriser
            node = '{} [label="{}"; shape="circle", pos="{}"] ' + retour
            if baseName in GRAPHE_PSEUDO_REELS:
                nodePosition = position(
                    noeuds[i].getNom(),
                    baseName,
                    i,
                    len(noeuds),
                    4
                    )
            else:
                nodePosition = position(noeuds[i].getNom(), baseName)
            if algo == "heuristique":
                file.write(node.format(
                    noeuds[i].getNom(),
                    noeuds[i].getNom()+"\\n capital : "+str(noeuds[i].getCapital()), # noqa : E501
                    # noeuds[i].getNom(), # noqa : E501
                    nodePosition)
                )
            else:
                file.write(node.format(
                    noeuds[i].getNom(),
                    noeuds[i].getNom(),
                    nodePosition)
                )
        file.write(retour)
        file.write("# Les arcs " + retour)
        strArc = "{} -> {} [headlabel = \"{}\"; labeldistance=2] " + retour
        strArcInverse = "{} -> {} [headlabel = \"{}\"; labeldistance=2; style=\"dashed\"; color=\"blue\"; fontcolor=\"blue\"] " + retour # noqa : E501
        for i in range(len(arcs)):
            if arcs[i].getEstInverse():
                file.write(strArcInverse.format(
                    arcs[i].getNoeudDebut().getNom(),
                    arcs[i].getNoeudFin().getNom(),
                    arcs[i].getPoids())
                )
            else:
                file.write(strArc.format(
                    arcs[i].getNoeudDebut().getNom(),
                    arcs[i].getNoeudFin().getNom(),
                    arcs[i].getPoids())
                )
        file.write("}" + retour)

    retour = ""
    noeuds = graphe.getNoeuds()
    arcs = graphe.getArcs()
    with open(destFile, 'w') as file:
        retour = "%0A%0A%20 "
        makeStrDigraph(file, retour)
        file.close()
    with open(destFileJs, 'w') as file:
        retour = " \n "
        file.write('function '+filenameJs+'() {')
        file.write('divGraph = document.getElementById("divGraph")' + retour) # noqa : E501
        file.write('var viz = new Viz();' + retour)
        file.write('viz.renderSVGElement(`' + retour)
        makeStrDigraph(file, retour)
        if baseName in GRAPHE_PSEUDO_REELS:
            coeffSvg = 2
        else:
            coeffSvg = 1.5

        file.write("""
        `).then(function(svg) {
                txtObj = document.getElementById("txtGraph")
                txtObj.data = ""
                var w = svg.getAttribute("width")
                w = parseInt(w.slice(0, -2))*""" + str(coeffSvg) + """
                w = w.toString()
                var h = svg.getAttribute("height")
                h = parseInt(h.slice(0, -2))*""" + str(coeffSvg) + """
                h = h.toString()
                svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
                svg.setAttribute('preserveAspectRatio', 'xMinYMin meet')
                var s = new XMLSerializer();
                var strSVG = s.serializeToString(svg)
                divGraph.innerHTML = strSVG
            })
            .catch(error => {
                // Create a new Viz instance
                // (@see Caveats page for more info)
                viz = new Viz();

                // Possibly display the error
                console.error(error);
            });
        """ + retour)
        file.write('}')
        file.close()
def graphvizMakeDotAndJsFiles(self, baseName: str) ‑> None

Crée tous les fichiers .dot et .js correspondants aux étapes d'une vue.

  • les fichiers *.dot pour l'affichage sur graphviz online
  • les fichiers *.js pour l'affichage directement dans la fenetre html

Paramètres

  • graphe : Graphe - Une instance de la classe Graphe.
  • baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

Remarques

  • les fichiers sont stockés dans le répertoire ./graphviz_algo/baseName
Expand source code
def graphvizMakeDotAndJsFiles(self, baseName: str) -> None:
    """Crée tous les fichiers *.dot et *.js correspondants aux étapes d'une vue.

    - les fichiers *.dot pour l'affichage sur graphviz online
    - les fichiers *.js pour l'affichage directement dans la fenetre html

    Paramètres
    ----------
    - graphe   : Graphe - Une instance de la classe Graphe.
    - baseName : str - Le nom du dossier qui va contenir les fichiers *.dot

    Remarques
    ---------
    - les fichiers sont stockés dans le répertoire ./graphviz_algo/baseName
    """
    pass
    assert isinstance(baseName, str), "baseName doit être un string"
    assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

    # On récupère le type d'algorithme
    algo = self.getAlgo()
    htmlDir = './vuesTexteEtHtml'
    dir = htmlDir+'/graphviz_'+algo+'/'+baseName
    # On supprime les répertoires s'ils existent
    if os.path.exists(dir):
        shutil.rmtree(dir)
    # On initialise l'index inital selon l'algorithme
    indexInitial = 0
    # On factorise le tableau des étapes
    etapes = self.getEtapes()
    if algo == "heuristique":
        indexInitial = 3
        for i in range(indexInitial, len(etapes) - 1):
            self.graphvizMakeDotAndJsFile(etapes[i], baseName)
    elif algo in ["eliminationCycles", "klein"]:
        indexInitial = 1
        for i in range(indexInitial, len(etapes)):
            self.graphvizMakeDotAndJsFile(etapes[i], baseName)
def graphvizMakeHtml(self, baseName: str) ‑> None

Crée une page html avec autant de liens que de graphes dans le dossier ./_graphviz_algo/baseName

Paramètres

baseName : str - Le nom du dossier qui contient les fichiers *.dot

Expand source code
    def graphvizMakeHtml(self, baseName: str) -> None:
        """Crée une page html avec autant de liens que de graphes
        dans le dossier ./_graphviz_algo/baseName

        Paramètres
        ----------
        baseName : str - Le nom du dossier qui contient les fichiers *.dot
        """
        pass
        assert isinstance(baseName, str), "baseName doit être un string"
        assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

        #  Page vide
        title = {
            'title': '',
            'subtitle': ''
        }
        if baseName == 'gch':
            title["title"] = 'Cours heuristique'
            title["subtitle"] = 'GRAPHE DU COURS HEURISTIQUE'
        elif baseName == 'grousseau':
            title["title"] = 'Biblio Rousseau'
            title["subtitle"] = 'GRAPHE DE LA BIBLIO D\'ARTHUR ROUSSEAU'
        elif baseName == 'gmikhailiv':
            title["title"] = 'Rapport Mikhailiv'
            title["subtitle"] = 'GRAPHE DU RAPPORT DE YOSIP MIKHAILIV'
        elif baseName == 'gvelamena':
            title["title"] = 'Rapport VelaMena'
            title["subtitle"] = 'GRAPHE DU RAPPORT DE MARIE VELA-MENA'
        elif baseName in GRAPHE_PSEUDO_REELS:
            title["title"] = 'Données ' + baseName[1:].capitalize()
            title["subtitle"] = 'GRAPHE ' + baseName[1:].capitalize()
        else:
            title["title"] = "BUG CONDITION"
            title["subtitle"] = "BUG CONDITION"

        header = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
button {
cursor:pointer; margin: 4px 2px; padding: 5px 10px;
}
</style>
<title>""" + title['title'] + """</title>
<script src="../../js/viz.js"></script>
<script src="../../js/full.render.js"></script>
</head>
<body>\n"""
        footer = """</body></html>"""
        # On crée le répertoire s'il n'existe pas
        htmlDir = './vuesTexteEtHtml'
        dir = htmlDir+'/graphviz_'+self.getAlgo()+'/'+baseName
        htmlFile = dir+'/'+baseName+'.html'
        textDir = htmlDir+'/texte_'+self.getAlgo()+'/'+baseName
        textOnlineDir = '/texte_'+self.getAlgo()+'/'+baseName
        if not os.path.exists(dir):
            os.makedirs(dir)
        initial_count = 0
        for path in os.listdir(dir):
            if os.path.isfile(os.path.join(dir, path)):
                initial_count += 1
        with open(htmlFile, 'w') as file:
            file.write(header)
            if initial_count == 0:
                file.write("<h1>PAGE VIDE</h1>\n")
            else:
                file.write("""<button><a href='../../index.html'> << Retour au
                menu Principal</a></button>""")
                # On adapte le texte
                algo = self.getAlgo()
                titreAlgo = ''
                if algo == 'heuristique':
                    titreAlgo = 'Méthode heuristique'
                elif algo == 'eliminationCycles':
                    titreAlgo = 'Méthode par élimination des Cycles'
                elif algo == 'klein':
                    titreAlgo = 'Algorithme de Klein'
                file.write("<h1>{} >> {}</h1>\n".format(
                    titreAlgo,
                    title["subtitle"].lower()
                ))
                file.write("""
<h3>Remarques :</h3>\n
<ul>\n
<li>Les liens permettent d'afficher les graphes étapes directement dans la page ou dans un nouvel onglet sur le site <a href="https://dreampuf.github.io/GraphvizOnline/" target="_blank">GraphvizOnline</a></li>\n
<li>On peut aussi afficher une version texte des étapes. <strong>Plusieurs simulations sont proposées.</strong> . Le <button style="color:red;">lien rouge</button> correspond à celle des graphes affichables.</li>\n
</ul>\n
                """) # noqa : E501
                file.write("""<div style="float: left; width: 15%">\n""")
                file.write('<ul>\n')
                file.write("<h4>Graphiques<br>Ci-contre</h4>\n")
                # for path in os.listdir(dir):
                for path in sorted(os.listdir(dir)):
                    if os.path.isfile(os.path.join(dir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == ".js":
                            file.write("<button onclick="+root+"()>Voir étape " + root[-2:] + " </button>\n") # noqa : E501
                            file.write("<script src=\"./"+path+"\"></script>\n") # noqa : E501
                file.write("<h4>GraphizOnline</h4>\n")
                # for path in os.listdir(dir):
                for path in sorted(os.listdir(dir)):
                    if os.path.isfile(os.path.join(dir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.dot':
                            currentDotFile = open(os.path.join(dir, path), "r")
                            currentStr = currentDotFile.readlines()[0]
                            file.write("<button><a href='https://dreampuf.github.io/GraphvizOnline/#"+currentStr+"' target='_blank'> Voir étape " + root[-2:]+ "</a></button>\n") # noqa : E501
                            currentDotFile.close()
                file.write('</ul>\n')
                file.write('</div>\n')
                file.write("""<div style="float: left; width: 15%">\n""")
                file.write('<ul>\n')
                file.write("<h4>Fichiers texte</h4>\n")
                # Un compteur pour l'affichage du style des étapes courantes
                cptMax = 0
                for path in os.listdir(textDir):
                    if os.path.isfile(os.path.join(textDir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.txt':
                            cptMax += 1
                cptMaxStr = '{:02d}'.format(cptMax)
                file.write("<button style=\"color:red;\" onclick=" + root + cptMaxStr + "txt()>Étapes correspondant aux graphes affichables</button>\n") # noqa : E501
                file.write("""
                <script>\n
                    function """ + root + cptMaxStr + """txt() {
                        divGraph = document.getElementById("divGraph")
                        divGraph.innerHTML = ""
                        txtObj = document.getElementById("txtGraph")
                        txtObj.data = \"../../.""" + os.path.join(textOnlineDir, "graphe"+cptMaxStr+".txt") + """ \"
                    }
                </script>\n
                """) # noqa : E501

                # for path in os.listdir(textDir):
                for path in sorted(os.listdir(textDir)):
                    if os.path.isfile(os.path.join(textDir, path)):
                        root, extension = os.path.splitext(path)
                        if extension == '.txt' and root[-2:] != cptMaxStr:
                            file.write("<button onclick="+root+"txt()>Voir une autre simulation</button>\n") # noqa : E501
                            file.write("""
                            <script>\n
                                function """ + root + """txt() {
                                    divGraph = document.getElementById("divGraph")
                                    divGraph.innerHTML = ""
                                    txtObj = document.getElementById("txtGraph")
                                    txtObj.data = \"../../.""" + os.path.join(textOnlineDir, path) + """ \"
                                }
                            </script>\n
                            """) # noqa : E501
                file.write('</ul>\n')
                file.write("</div>\n")
                file.write("""
<div id="containerDivGraph" style="margin-left: 35%; height:600px; width:55%; border-left:1px solid black;" >\n
<div id="divGraph" style="margin-left: 20%; height:auto; width:90%"></div>\n
<object id="txtGraph" data="" type="text/plain" style="width: 100%; height: 100%;"></object>
</div>\n
                """) # noqa : E501
            file.write(footer)
            file.close()
def texteMakeFile(self, baseName: str) ‑> None

Crée un fichier texte avec les différents graphes étapes obtenus par application de l'algorithme appliqué.

La propriété algo de la classe Vue, contient l'information sur l'algorithme utilisé.

Paramètres

baseName : str - Le nom du dossier qui va contenir le fichier *.txt

Expand source code
def texteMakeFile(self, baseName: str) -> None:
    """Crée un fichier texte avec les différents graphes étapes obtenus par
    application de l'algorithme appliqué.

    La propriété algo de la classe Vue, contient l'information sur
    l'algorithme utilisé.

    Paramètres
    ----------
    baseName : str - Le nom du dossier qui va contenir le fichier *.txt

    """
    pass
    assert isinstance(baseName, str), "baseName doit être un string"
    assert self.getAlgo() is not None, "le type d'algorithme ne doit pas être None" # noqa : E501

    # On récupère le type d'algorithme
    algo = self.getAlgo()
    htmlDir = './vuesTexteEtHtml'
    dir = htmlDir+'/texte_'+self.getAlgo()+'/'+baseName
    # On crée le répertoire s'il n'existe pas
    if not os.path.exists(dir):
        os.makedirs(dir)
    initial_count = 0
    for path in os.listdir(dir):
        if os.path.isfile(os.path.join(dir, path)):
            initial_count += 1
    filename = 'graphe'+'{:02d}'.format(initial_count+1)
    destFile = dir+'/'+filename+'.txt'
    if algo == "heuristique":
        lines = self.consoleHeuristique().split("\\n")
    elif algo == "eliminationCycles":
        lines = self.consoleEliminationCycles().split("\\n")
    elif algo == "klein":
        lines = self.consoleAlgorithmeDeKlein().split("\\n")

    with open(destFile, 'w') as file:
        for line in lines:
            file.write(line)
        file.close()