Qqs trucs sur Autocad et d'autres logiciels DAO...
Accueil Initiation Méthodologie Variables Comment faire ? Lisps Sommaire
Soft & liens Revit 2020 CVC sur autocad Linux CloudCompare Initiation à Autolisp Blog

Le Débugage avec l'éditeur Vlisp

Si c'est votre 1ere expérience avec la programmation, les explications de (gile) sur l'éditeur Autolisp d'Autocad (page 11) sont peut etre un peu courtes. Les fonctions de débugage de cet éditeur sont classique, mais vous ne connaissez peut etre pas les classiques... Au programme pas à pas espions, inspection et console.

Présentation de l'éditeur

Je ne vais pas paraphraser la présentation de Gilles Chanteau, elle est synthétique et va à l'essentiel. On va juste approfondir les fonctions de débugage.
je met tout de même un copie d'écran qui va nous servir à nous repérer dans ma disposition. Cliquez sur la vignette et une image s'ouvrira dans une nouvelle fenêtre pour y revenir plus tard.

Deux trois petites choses à savoir

L'éditeur est une extension d'Autocad et pas un programme indépendant. Cela induit certain comportements. Par exemple, si un lisp à été chargé depuis l'éditeur, ou qu'Autocad attend une information (une réponse de l'utilisateur ou une sélection) si on retourne dans l'éditeur, on a plus la main, le curseur prend une forme différente il faut revenir à Autocad et répondre aux questions...ou spamer échappe...
Dans le menu débugage, tout en bas il y a une entrée pour arrêter l'interprétation qui sauve la mise en cas de boucle infinie...

Mais bon, on va pas débugger dans le vide, on va commencer par un petit exercice

Savez vous compter les lignes..

Voici un petit dessin bug.dwg. Dans ce dessin, on a plusieurs lignes dans différent calques. Je vous propose de faire la somme des longueurs de ces ligne par calques.
pour vérification, j'ai tracé des longueur de 1, 2 et 3, dans 3 calques. en calculant de tête, j'obtiens:

Lay 0 :14
Lay 1 : 7
Lay 2 : 9

Algorithme

On est sur un programme un peu cossu. Pour clarifier les choses je vous proposerai de dessiner le logigrame avant de commencer à coder. Avec un papier et un crayon, ou dans votre tête, mais coder sans savoir ou on va est pas très judicieux quand on débute. Je supose qu'il y en a pour qui il est plus facile de coder directement car leur conaissance du language est tél qu'il devient naturel. Mais quand on fait ses premiers pas, mieux vaut poser ses idées sur le papier. On commence par discuter de l'idée, puis on dessine le logigramme en détaillant les étapes. A la fin il n'y a plus qu'a écrire. Pour aider j'ai fini par faire qqs blocs ici.

Avant de lire la suite, essayer de voir par quel bout vous auriez pris le problème...On a déja vue quasiement tous les outils nécéssaire

Voici ma solution, mais bien d'autres serai fonctionelles...

On a déjà comment faire un jeu de sélection et calculer la longueur d'une ligne avec (distance. Le (assoc 8 va nous permettre de sortir le calque....
On va commencer par créer une liste une liste de travail dans la quelle on va regrouper des couples pour chaque entité ou on aura le longueur et le calque. Cette liste aura cette forme:

( (longueur1 calque1) (longueur2 calque1) ... (longueur1 calque2) ... ... ... )
c'est donc un (cons (list ....

Il est d'usage pour parcourir les listes de les dé construire en dans une boucle. Il existe bien une commande similaire à (ssname qui retourne le Nième élément d'un jeu de sélection, mais elle est réputé un peu lente. On teste donc le 1er élément, puis on le surprime avec (cdr... au prochain tour de boucle, quand on testera le 1er terme ce sera en fait le 2eme terme de la liste originelle, ect... jusqu'a la fin de la liste

Pour sortir la valeur des éléments de cette liste, on va se servir de (car et de (cadr (attention, la liste est une liste de sous liste, il faudra donc appliquer ces 2 fonctions sur le 1er éléments de la liste). Voir ici pour raccourcir la commande...

La difficulté, c'est qu'il va falloir construire une nouvelle liste ou on regroupe le total par calque donc tester si le calque existe dans cette liste de total. Si oui il faut ajouter la longueur au total du claque si non créer une nouvelle entrée à la liste des totaux. Creusez vous un peu les méninges... on commence à faire des choses compliquées. Si le lisp est utilisé en intelligence artificielle c'est parce que les valeur de retour de commande peuvent etre utilisée dans des test. Et que les constructions de commandes imbriquées sont des outils puissants...

Il va falloir utiliser des valeurs de retour des fonctions (assoc dans un test. Car si (assoc ne trouve rien, il retourne nil qui rend le test faux
Donc si le test n'est pas faux (un calque existe dans la liste), on va faire une modification de cette liste avec (subst
Par contre, si le test de (assoc renvoie nil, il n'y a pas de calque de ce nom dans la liste qui fait le total donc il faut rajouter un terme avec une sous liste pour ce nouveau calque et la longueur de la ligne.

 

En 1er jet, j'ai sorti ça...
Ouvrez le dessin bug.dwg qui doit etre la fenêtre active. puis Outil / Autolisp / Éditeur Vlisp (ou _vlide), puis ouvrez ce dans l'éditeur Vlisp.
Bouton (1) on charge la fenêtre active dans le dessin actif, bouton 2 on passe la main à Autocad.
Le Lisp est chargé, on peu le lancer. avec LGL comme c'est écrit après le defun...

Résultat? boom!

Débugons...

Le programme s'étant arrêter inopinément, on est de retour dans l'éditeur. Vous remarquez que les 2 boutons en (5) ne sont plus grisés. On à donc la main sur"ré initialiser" ou "quitter" pour sortir de là. Mais celui qui nous importe est celui en (7) qui invite à voir la source de la dernière interruption (à condition que l'arrêt sur erreur soit activé)

C'est la fonction (subst qui pose problème... un tour dans le guide de ref pour s'apercevoir que j'ai oublier de placer la liste à substituer ... grrr je le savais pourtant !!

Allez on l'ajoute... Mais on est toujours bloqué. Il faut cette fois ré initialiser avec un des 2 bouton en (5).

Cette manoeuvre nous renvoie sur Autocad... nous voila bien avancé... On retourne dans l'éditeur et re (1) (2) pour charger le code modifié et re tourné sur Autocad. (On se demande bien pourquoi l'arrêt nous renvoie sur Autocad, mais bon...)

On relance... on sélectionne toute les lignes... youpi!! ça marche...

Lay 1 :7.000
Lay 0 :14.000
Lay 2 :12.000

Ha ? diable ! ce n'ai pas le même résultat que celui obtenu avec ma super capacité de calcul mental!!
Du coup je vérifié avec une calculette mois sujette à la la défaillance humaine, mais non... y a pas d'erreur il y a une erreur....

Lay 2 aurai bien dû afficher 9.00

Redébugons...

Les deux résultats Lay 1 et 0 étant correct, je suppose que l'erreur viens de la routine qui fait les totaux. On va essayer de l'analyser....

C'est une boucle. on va rajouter une mémoire qui va nous servie à compter les tours histoire de se repérer. La ligne sous le (while ajoutez

(setq i (1+ i))

(j'avais prévu le coup car i est initialisé juste avant... )
Pour que ce soit plus joli, on va identer la boucle c'est un des deux bouton en (4). il y en à un pour re mettre en forme la feuille complète. Si vous double cliquez sur la 1ere parenthèse du (repeat toute la boucle complète est sélectionnée. Le 2eme bouton " formater la sélection" ne remet alors en forme que la boucle.

Si on laisse le programme tourner, on verra pas grand chose. On va donc poser des point d'arrêt. et des espions.

Pour poser un point d'arrêt sous le curseur, c'est le bouton (6) en forme de main. On va le mettre après l'incrément du "i".
Pour ajouter un espion, on sélectionne une variable ou une expression et c'est le bouton en dessous avec les lunettes.

Chargez la fenêtre des espions avec les variables de l'image au dessus puis... (1) (2) et on relance LGL dans Autocad.
on reprend les lignes et quand on valide, on retourne dans l'éditeur mais cette foi, c'est volontaire. L'arrêt à été provoqué par le point d'arrêt qu'on vient d'ajouter. Vous devriez avoir un truc comme ça:

La fenêtre des espions affiche la valeur à l'instant t, j'ai double cliquer sur une expression, puis clic droit inspecter pour voir sa valeur. Cette fenêtre "Inspecter LIST" ne se mettra pas à jour au prochain tour contrairement à celle des espions. Cliquez le bouton vert en (5) pour vous en convaincre.

Voila... en faisant le tour complet, on peu suivre le déroulement de tout le programme. On peu voir "alist" se décrémenter, et les valeurs successives de "lst-totcalq" qui augmentent.

 

Bon... il faut quand même utiliser sa cervelle pour comprendre ou est la boulette.
En fait, la 1ere valeur est entrée 2 fois... je propose une correction en changeant le (repeat par un (while.
On va faire un While sur une attribution de la décrémentation de "alist" de cette manière:

(while (setq alist (cdr alist))

comme ça, au 1er tour de boucle, on passera avec "alist" sans sa 1ere valeur et le résultat final devrai être correct
Quand le (cdr alist) va arriver au bout, le (setq ne pourra pas se faire et retournera "nil", ce qui va nous sortir de la boucle.

testons...

RE grrr harf sacrebleu !

On sort au 7eme tour, et on décrémente 2 fois... ben oui, j'ai oublier d'effacer le "alist (cdr alist)" dans l'affectation des variables.... on le vire.

Re test...

Youpiii!! yabon !!!

Lay 1 :7.000
Lay 0 :14.000
Lay 2 :9.000

Pour mémo, le code fini lgl.lsp

Conclusion

On a appri les rudiments du debugage. On a vu plusieurs façons de parcourir une boucle, et les fonctions cdr et car qui sont les bases de l'exploitations des listes. On a appris à dessiner son programe avant de commencer à coder.
C'était un peu téléphoné, mais j'ai essayer de vous faire sentir le processus d'aller retour, de doutes et de victoires sur nos propres erreurs qu'on peu ressentir. Car je dois bien l'avouer, si je vous passe des corrigé qui tournent mais ils sont le fruit de pas mal de vicissitudes. Et si on ne connais pas les fonctions et les processus de débugage, faire une conception qui tourne c'est vraiment pas facile...

Compléments

j'ai apprivoisé 2 autres petits trucs utiles depuis la rédaction de cette page. suffisament utile pour vous en parler.

D'une part, quand on à dfini un point d'arret, essayez de jouer avec les icones situées au dessus.

Cest 3 icones sont 3 modes pas à pas ou le débuggeur interprète les instructions soit une après l'autre, soit par groupe... bien utile..
surtout si on à mis dans la fenetre éspion, la dernière interprétation car ce "LAST-VALUE" se met à jour à chaque instructions.

On peut suivre en temps réel tout ce qui se passe dans la tête de notre dévoué petit interpréteur.
Et voir pourquoi il nous plante :)

Evaluations


On peut dans les (setq grouper les variables. Mais si on veux tester  des expressions, il vaux mieux laisser nos (setq  avec une seule variable. Dans cette exemple, on a un (setq sur une liste, puis un (setq avec un appel dans cette lsite.
De cette manière, sans lancer le programme on peu évaluer directement  l'expression 1 puis à la 2eme il y a des valeurs à tester

 

 

 

 

 

 

 

lien vers cadXP