Functions-diagram est un programme Python permettant de représenter graphiquement des fonctions en spécifiant les noms et les types d'entrée et de sortie.
Son objectif est d'aider les apprenants à faire leurs premiers pas avec les fonctions et à analyser le fonctionnement d'un programme.
Les éléments (nœuds et fonctions) peuvent être liés et connectés les uns aux autres.
La représentation graphique peut être exportée au format SVG.
- Description
- Format de sauvegarde
- Boutons
- Outil de rendu
- Auteur
- Avancement du projet
- Feuille de route
- Licence
Ce diagramme représente l'appel d'une fonction xor
:
cipher_text = xor(plain_text, key)
Nous pouvons constater que cette fonction prend deux paramètres et renvoie une valeur.
Autre exemple impliquant un deuxième appel à la fonction xor
.
Voici le code correspondant :
cipher_Text = xor(plain_text, key)
deciphered_text = xor(cipher_Text, key)
Le même schéma avec les indications de type et le code correspondant.
def xor(a: int, b: int) -> int:
"""
Return the bitwise operation xor on the two positive integers a and b.
>>> xor(8, 7)
15
>>> xor(7, 3)
4
"""
return a ^ b
cipher_Text = xor(plain_text, key)
deciphered_text = xor(cipher_Text, key)
Le code et le diagramme sont cohérents avec la signature de la fonction xor
.
>>> import inspect
>>> inspect.signature(xor)
<Signature (a: int, b: int) -> int>
Nous proposons ici une approche naïve pour résoudre le problème du voyageur de commerce.
Soit une liste de villes :
cities = ["Paris", "Lyon", "Marseille", ...]
Nous devons explorer toutes les combinaisons possibles et trouver l'itinéraire le plus court possible qui visite chaque ville exactement une fois et retourne à la ville d'origine.
Dans une première approche, on peut imaginer construire un tableau à deux entrées pour connaître le coût d'un itinéraire entre chaque ville.
Chaque cellule peut être remplie en appelant une API (OpenStreetMap, par exemple). Le résultat est implémenté dans un dictionnaire.
cost = {
"Paris": {"Paris": 0, "Lyon": 462.941, "Marseille": 772.335, ...},
"Lyon": {"Paris": 462.941, "Lyon": 0, "Marseille": 312.659, ...},
"Marseille": {"Paris": 772.335, "Lyon": 312.659, "Marseille": 0, ...},
...
}
À partir de cette même liste de villes, nous devons générer toutes les combinaisons d'itinéraires possibles rebouclant sur la ville d'origine.
Par exemple :
["Paris", "Lyon", "Marseille", ..., "Paris"]
...
["Paris", "Marseille", "Lyon" ..., "Paris"]
Maintenant que nous connaissons la table des coûts et tous les itinéraires possibles, il ne nous reste plus qu'à trouver l'itinéraire ayant le coût le plus bas.
Voici à quoi ressemblerait un schéma global du problème.
La dernière fonction sera chargée de calculer systématiquement le coût de chaque itinéraire.
Par la suite, il suffira de pousser plus loin cette approche descendante en spécifiant plus précisément chacune des sous-fonctions.
Suivez ce lien pour accéder à une proposition de résolution et les diagrammes associés.
Les diagrammes sont sauvegardés dans un fichier .DGM.
Voici à quoi ressemble la sauvegarde du diagramme précédent.
def create_cost_table(cities:list[str])->dict[str,dict[str,float|None]]
create_cost_table.position(257,236)
create_cost_table.dimension(258,39)
def all_routes(cities:list[str])->list[list[str]]
all_routes.position(291,320)
all_routes.dimension(190,39)
def search_minimum(cost:dict[str,dict[str,float]],permutations_routes:list[list[str]])->tuple[float|None,list[str]]
search_minimum.position(860,349)
search_minimum.dimension(380,58)
node(cost,(620,320)) # fixed
node(permutations_routes,(620,416))
node(cities:list[str],(123,235))
create_cost_table<0---cities
create_cost_table>---cost
all_routes<0---cities
all_routes>---permutations_routes
search_minimum<0---cost
search_minimum<1---permutations_routes
Les lignes commençant par def
sont utilisées pour créer des blocs de fonctions.
Ils suivent la syntaxe de définition de fonction Python (le ':'
final est facultatif).
Après chaque ligne def
, vous pouvez spécifier les attributs position
et/ou dimension
du bloc.
Les nœuds sont créés à partir d'une ligne commençant par node
. Les paramètres saisis définissent le nom du nœud et ses caractéristiques (indication de type, position).
Le commentaire # fixe
indique si cet élément ne peut pas être déplacé par placement automatique : 'Auto'.
A noter que le caractère '*'
dans le nom désigne un séparateur : les caractères précédant ce séparateur correspondent au libellé affiché. Cela permet d'avoir des fonctions ou des nœuds avec des étiquettes identiques mais des noms (identifiants) uniques.
Les liens entre les nœuds suivent la syntaxe ci-dessous :
node_name1---node_name2
Les nœuds de fonction sont désignés par : function_name>
pour la sortie, et function_name<id
pour les entrées avec id
commençant à 0.
Créer un nouveau fichier
Ouvrir un fichier
Sauvegarder un fichier
Exporter un diagramme en image (.SVG)
Déplacer une fonction, un noeud ou un groupe. Permet aussi de déplacer le coin inférieur droit des groupes en mode "Fixed"
Ajouter une fonction
Ajouter un noeud libre
Créer un groupe
Relier deux noeuds
Editer un élément (fonction, noeud ou groupe)
Supprimer un élément (noeud, fonction, groupe ou connexion). Remarque : Pour supprimer tous les éléments d'un groupe, il faut l'éditer.
Undo
Redo
Placer automatiquement les objets sur l'écran
Edition des paramètres
Visualiser les informations
Pour certaines opérations, vous devez d'abord sélectionner une destination. Vous pouvez quitter ce mode en cliquant avec le bouton droit de la souris ou en appuyant sur Enter ou Esc.
- CTRL + s : Sauvegarder
- CTRL + c : Copier/coller
- CTRL + z & CTRL + y : Annuler & Refaire
- CTRL + a : Création d'un groupe qui englobe tous les éléments du diagramme
- CTRL + q & CTRL + w : Zoom + et Zoom -
- CTRL + o : Retour au zoom et au décalage d'origine
- Molette : Zoom + et Zoom -
- Clic + Déplacement : Décalage du point de référence du dessin
render.py
est un outil de rendu qui permet de convertir des fichiers .DMG ou un répertoire de fichiers .DMG en .SVG.
Exemple d'utilisation :
python3 render.py ./diagrams -m 40 -o 0.9
Cette instruction convertit l'ensemble des fichiers .DMG du répertoire diagrams
avec une marge additionnelle de 40 pixels (option -m) et une transparence de 0.9 (option -o)
Aide :
usage: render.py [-h] [-d DESTINATION] [-m MARGIN] [-o OPACITY] [-p {None,dark,light}] [-a AUTOMODE] source
positional arguments:
source Source file
options:
-h, --help show this help message and exit
-d DESTINATION, --destination DESTINATION
Destination file
-m MARGIN, --margin MARGIN
Margin in pixels
-o OPACITY, --opacity OPACITY
Opacity from 0 (transparent) to 1 (opaque)
-p {None,dark,light}, --preferences {None,dark,light}
Preferences
-a AUTOMODE, --automode AUTOMODE
Runs automatic placement if True
Eric Buonocore
Le programme est opérationnel.
- Ajouter des éléments (nœuds, fonctions)
- Interconnecter des éléments
- Ouvrir et sauvegarder un diagramme
- Déplacer et modifier des éléments
- Undo/Redo
- Positionner automatiquement des éléments
- Paramétrer le programme et appeler l'aide
- Multiselection d'éléments pour les déplacements et les suppressions
- Définir l'espacement des éléments pour le placement automatique
- Permettre de justifier les noms des nœuds libres
- Permettre l'agrandissement et le déplacement de l'ensemble de la mise en page
- Un outil de rendu (render.py) pour convertir des fichiers (ou répertoire de fichiers) .dmg en fichiers .svg
- Tester et régler les bogs