x_all Posté(e) le 28 mai 2018 Partager Posté(e) le 28 mai 2018 Bonjourpar habitude, je regroupe les fonction que j'utilise en dehors du (defun c: ..). (defun toto (arg/ variables) .... )je lui passe donc des arguments et les variables y restent locale.Mais si la fonction est définie à l'intérieur du (defun c:doit on redéfinir des variables? peut on utiliser les variable du (defun c: qui portent lors sur les 2 fonctions sans pour autant être globale?Merci...:) quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 28 mai 2018 Partager Posté(e) le 28 mai 2018 Salut, Oui, une fonction locale peut utiliser et modifier les variables locales de la fonction parent. La portée d'une variable locale (ou d'un argument) est limitée à la fonction dans laquelle elle est déclarée, mais elle est "globale" pour toutes les fonctions locales. (defun main (x / sub1 sub2 a) (defun sub1 (x) (* 2 x) ) (defun sub2 () (setq a (sub1 a) x (+ a x) ) ) (setq a 12) (sub2) (list a x) ) _$ (setq x 5) => 5 _$ (main x) => (24 29) _$ x => 5 Tu peux voir aussi ce message. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 28 mai 2018 Auteur Partager Posté(e) le 28 mai 2018 Oki... reste a savoir quel est le choix le plus judicieux, et je reste indécis dans le cas qui m’occupe... au passage, autre question.si j'ai une fonction F1 définie dans (defun c: et F2 en dehors. F1 peut appeler F2 (?)mais si F1 et F2 sont définies en dehors, F1 peut encore appeler F2 ? Si oui, je fous tout le monde dehors !! quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 28 mai 2018 Partager Posté(e) le 28 mai 2018 si j'ai une fonction F1 définie dans (defun c: et F2 en dehors. F1 peut appeler F2 (?)Bien sûr, F2 définie à l'extérieur du (defun c: ...) est accessible pour F1 comme n'importe quelle autre fonction LISP (prédéfinie ou définie par l'utilisateur). En résumé, il y a trois raisons de déclarer localement des fonctions :- pour redéfinir localement une fonction (typiquement *error*)- pour utiliser/modifier des variables locales à une fonction parent- pour éviter les conflits de nom Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fraid Posté(e) le 28 mai 2018 Partager Posté(e) le 28 mai 2018 Yop J'ai eu beaucoup de mal aussi avec l'imbrication des fonctions. si j'ai une fonction F1 définie dans (defun c: et F2 en dehors. F1 peut appeler F2 (?) dans ce cas la, c'est F2 qui ne peut pas appeler F1. dans certain cas, c'est le passage en argument ou non de certaines variables qui est difficile pour moi encore.Mais en testant les différentes possibilités on finis par s'en sortir.Hélas, comme nous ne disposons pas d'un véritable IDE, cela fonctionne, même si on à pas fait le meilleur choix. Conclusion, il faut tester, et tester encore... https://github.com/Fraiddd Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 28 mai 2018 Auteur Partager Posté(e) le 28 mai 2018 :)la première question, je m'y attendais un peu, mais c'est surtout la 2eme qui me travaille. En y réfléchissant, si les 2ft sont définies en dehors, de toute façon comme c'est c: qui appelle F1 qui appelle F2, il devrai pas y avoir de soucis... au passage, un petit rappel svp, comment on sort d'une fonction récursive? je vais passer une liste en argument et la décrémenter à coup de cdr. Mais quand la liste est vide comment je sort? quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fraid Posté(e) le 28 mai 2018 Partager Posté(e) le 28 mai 2018 en englobant ta fonction avec (while ta-variable (ta fonction)) me semble t'il https://github.com/Fraiddd Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fraid Posté(e) le 28 mai 2018 Partager Posté(e) le 28 mai 2018 (modifié) comme à l'inverse, pour compter la profondeur de tes récursions par exemple, il faut déclarer la variable au dessus de ta fonction récursive.(pas en argument) (setq la-variable 0) (defun lafonction) mais Gile va certainement mieux t'expliquer :) Modifié le 28 mai 2018 par Fraid https://github.com/Fraiddd Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 28 mai 2018 Auteur Partager Posté(e) le 28 mai 2018 c'est pas fini, mais j'en suis là je vois pas trop pou je mettrai un while..plutot un exit si je peut pas décrémenter? pour la portée des variables, j'essaye d'être méfiant, mais de toute façon, je manipule plutôt des chaines de liste les vrai variables sont dans les blocs mais j'ai encore un blocage je débugue à la vitesse d'une limace... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 29 mai 2018 Partager Posté(e) le 29 mai 2018 au passage, un petit rappel svp, comment on sort d'une fonction récursive? je vais passer une liste en argument et la décrémenter à coup de cdr. Mais quand la liste est vide comment je sort? On sort d'une fonction récursive quand on atteint la condition d'arrêt (la liste est vide), les appels récursifs devant faire tendre vers cette condition. Un exemple simple, pour compter le nombre d'éléments d'une liste (ce que fait la fonction length). Algorithme récursif:Le nombre d'éléments d'une liste est égal à :- 0 si la liste est vide (condition d'arrêt)- 1 plus le nombre d'éléments de la liste sans le premier élément (appel récursif) Ce qui se traduit simplement en code par :(defun count (l) (if (null l) 0 (1+ (count (cdr l))) ) ) Comment ça marche.Jusqu'à atteindre la condition d'arrêt, c'est la phase d'"empilement" (on empile les appels récursif)(count '("a" "b" "c" "d")) (1+ (count '("b" "c" "d"))) (1+ (1+ (count '("c" "d")))) (1+ (1+ (1+ (count '("d"))))) (1+ (1+ (1+ (1+ (count '())))))Puis c'est la phase de "dépilement" (évaluation de chaque expression de la pile)(1+ (1+ (1+ (1+ 0)))) (1+ (1+ (1+ 1))) (1+ (1+ 2)) (1+ 3) 4 Excepté dans certains cas, comme le traitement des arborescences (un dossier peut contenir des fichiers et des dossiers), un algorithme récursif peut être remplacé par un algorithme impératif qui au lieu d'utiliser des appels de fonction, utilise des changements d'états.Là encore, il faut définir une condition d'arrêt pour sortir de la boucle et les changements d'état doivent faire tendre vers la condition d'arrêt. Algorithme impératif (itératif)Pour compter les éléments d'une liste :- on initalise un compteur à 0- et tant que la liste n'est pas vide (condition d'arrêt),- on ajoute 1 au compteur (changement d'état)- on supprime le premier élément de la liste (changement d'état)- on renvoie la valeur du compteur Ce qui se traduit en code par :(defun count (l / i) (setq i 0) (while l (setq i (1+ i) l (cdr l) ) ) i ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 29 mai 2018 Auteur Partager Posté(e) le 29 mai 2018 C'est un peu étrange que ça sorte tout seul, mais ok..dans mon cas, à la fin de ma fonction Explore, je lance une fonction de traitement, puis supprime l'élément je peut donc faire ça?... ;; Si Nok = 0 la branche est traitable ;; on traite, supprime cette branche de la collection et relance sur la nouvelle liste (TraiteBranche brl) (if (setq lsbrlocal (cdr lsbrlocal)) (explore lsbrlocal) ) (setq lsbrlocal nil) );; fin de explore Bon... je regarderai ce soir, à force de coder je vais me mettre à la bourre... j'ai un métier moi !merci pour les info... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
lecrabe Posté(e) le 29 mai 2018 Partager Posté(e) le 29 mai 2018 Hello Gilles 1) Tes explications sont limpides et magiques ! 2) Question: SVP dans quels cas, es t-on sur que la récursivité sera plus rapide / performante ?Et vice-versa ? Merci, Bye, lecrabe PS: mon lointain passe de développeur (1980-1999) a toujours ete itératif (Assembleur, Fortran, Cobol, RPG, Pascal, C, Lisp, Basic) Sauf 2/3 fois en Lisp sous AutoCAD, MAIS c'était juste pour m'amuser... Autodesk Expert Elite Team Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fraid Posté(e) le 29 mai 2018 Partager Posté(e) le 29 mai 2018 Suis pas doué du tout pour expliquer.. de plus, comme j'apprend le Java, m’emmêle un peux la gestion des variables, qui chez l'un on est obligé de rendre globale (Statique) la variable incrémentée à cause de l'encapsulation à l’intérieur d'une boucle et pas en Lisp. https://github.com/Fraiddd Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 29 mai 2018 Auteur Partager Posté(e) le 29 mai 2018 Bon.. je me suis encore mis à la bourre alors que je jetais juste un coup d’œil entre midi et 2...pfff c'est un bouffe temps ces programmes...Je comprend mieux les remarques sur le débogueur, quand on rentre dans une ft récursive, on a plus le pas à pas... bref pour trouver pourquoi ça coince je suis mal...j'ai fait un petit bout de code qui se lance directement, mais il faut avoir le dessin avec les bon bloc pour testSi qq1 pouvais jetter un coup d'oeil et me sortir de la panade je lui en serai très reconnaissant car c'est frustrant de pas comprendre ou est le caffard...le dessin se charge icihttp://joch04.free.f...bit-ventil3.dwg et le code c'est ça il manque la partie génération de la branche et la partie traitement à été réduite, mais j'aimerai bien qu'il affiche ""sortie normale de Tex"" apparemment je ne rentre jamais dans (traitebranche) j'y est mi un point d’arrêt et ça arrête pas...pourtant la branche qui part de 0,0 est bien valide, et au pire il devrai calculer les branches terminales mais nada on dirai qu'il ne passe jamais par le cdr ? (defun c:tex (/ ent i in j n lay der sspoly poly lsvtx vtx pt ssblocs lsbloc bloc nombloc hbloc lsbrrecur lsbranche branche tcourant ta QA qc v doc ) (vl-load-com) (setq doc (vla-get-activedocument (vlax-get-acad-object)) ) ;_ Fin de setq (setq lsbrrecur '((("Debit" (0.0 0.0) "3804") ("jonction" (1.0 0.0) "2514") ("Debit" (2.0 0.0) "3811") ("jonction" (3.0 0.0) "2522") ("jonction" (6.0 0.0) "253E") ("jonction" (10.0 0.0) "254C") ) (("Debit" (0.5 1.0) "2B6D") ("Debit" (1.0 1.0) "2B61") ("jonction" (1.0 0.0) "2514") ) (("Debit" (3.0 4.0) "2B55") ("Debit" (3.0 2.0) "2B49") ("jonction" (3.0 0.0) "2522") ) (("Debit" (5.0 2.0) "2B31") ("jonction" (6.0 2.0) "255A") ) (("Debit" (6.0 5.0) "2B3D") ("jonction" (6.0 4.0) "34DA") ("jonction" (6.0 0.0) "253E") ) (("Debit" (8.34004 4.0) "34FE") ("jonction" (6.0 4.0) "34DA") ) ) ) ;_ Fin de setq (explore lsbrrecur) ;; ;; Explore ;; (defun explore (lsbrrecur / brl bloc nok in) (setq brl (car lsbrrecur) in 0 bloc nil nok 0 ) ;_ Fin de setq ;;boucle pour test si un bloc à un QA /=0 (while (< in (length brl)) (setq bloc (nth in brl) hbloc (caddr bloc) ) ;_ Fin de setq (setq Qa (read (Vb-Val-att (handent hbloc) "Qa" ) ;_ Fin de Vb-Val-att ) ;_ Fin de read ) ;_ Fin de setq ;_ Fin de setq (if (and (= 0 Qa) (/= (+ 1 in) (length lsbloc))) ;; test du Qa d'un bloc qui n'est pas le dernier si oui Nok = 1 (setq nok 1) ) ;_ Fin de if (setq in (+ 1 )) ) ;_ Fin de while ;; on sais si la branche est traitable (nok=0) ;; Si Qa non rempli, on ne peut pas calculer la branche ;; on met donc ce bloc à la fin de celle ci et on rappelle explore ;; avec cette nouvelle liste en espérant que le 1er élément soit traitable (if (= nok 1) (progn (setq lsbrrecur (append (cdr lsbrrecur) (list (car lsbrrecur)) ) ;_ Fin de append ) ;_ Fin de setq ;; permutation à (gile) le 1er devient le dernier (explore lsbrrecur) ) ;_ Fin de progn ;;fp ) ;_ Fin de if ;;fi ;; ;; Si Nok = 0 la branche est traitable ;; on traite, suprime cette branche de la collection et relance sur la nouvelle liste (TraiteBranche brl) (if (setq lsbrrecur (cdr lsbrrecur)) (explore lsbrrecur) (print "ggrrrrr") ) ;_ Fin de if ) ;_ Fin de defun ;;;fd explore (print "sortie normale de Tex") ;;; Fin de l'undo (vla-endundomark doc) (princ) ) ;_ Fin de defun ;;fin Vsom ;; ;; Traiement d'une branche et maj Qa ;; (defun TraiteBranche (branche / i u bloc hbloc tcourant ta) (setq i 0 bloc nil ) ;_ Fin de setq (while (< i (length branche)) (setq bloc (nth branche i) hbloc (caddr bloc) ) ;_ Fin de setq (Vb-Mod-att (handent hbloc) "Qa" (rtos 100 )) (setq i (+ 1 i)) ) ;_ Fin de while ;;;fw ) ;fd ;; Vb-Val-att fonction Vlisp pour lire la valeur d'un attribut (defun Vb-Val-att (ent nomatt / att val) ; ent correspond au handel du bloc (codedxf 5) à utiliser comme ça (setq toto (read (Vb-Val-att (handent handle) "REF"))) (foreach att (vlax-invoke (vlax-ename->vla-object ent) 'getattributes ) ;_ Fin de vlax-invoke (and (eq (vla-get-tagstring att) nomatt) ;comme ils disent les fou du code "tournure élégante !" (setq val (vla-get-textstring att)) ; le ET est équivalent à un si dans ce cas là ) ;car on afffecte Val que si att= nom-att bravo Patrick_35 ) ;_ Fin de foreach val ;; retour de fonction ) ;_ Fin de defun ;; fin Vb-Val-att ;; Vb-Mod-att fonction Vlisp pour modifier la valeur d'un attribut ;; à utiliser comme ça (Vb-Mod-att (handent handle) "NIV" new-val) ;; new-val est une string (defun Vb-Mod-att (ent nom-att nval / att inc vblst-att) (setq inc 0 vblst-att (vlax-invoke (vlax-ename->vla-object ent) 'getattributes ) ;_ Fin de vlax-invoke ) ;_ Fin de setq (while (< inc (length vblst-att)) (if (eq (vla-get-tagstring (nth inc vblst-att)) nom-att ) ;_ Fin de eq (vla-put-textstring (nth inc vblst-att) nval) ) ;_ Fin de if (setq inc (+ 1 inc)) ) ;_ Fin de while ) ; ; fin Vb-Mod-att quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 29 mai 2018 Partager Posté(e) le 29 mai 2018 Ta question est confuse.As-tu une erreur ? Si oui où ? Sinon c'est quoi le problème ?De plus ton code n'est pas très bien présentation / formatage et ça ne donne pas très envie de se plonger dedans. Commence par ça : d'un côté tu soignes un peu la présentation code pour qu'il soit plus lisible, mieux organisé (si, si, ça compte) et d'un autre tu essaye de formuler clairement ton problème, en général quand on y arrive, on a pratiquement résolu le problème. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 29 mai 2018 Auteur Partager Posté(e) le 29 mai 2018 Re bonsoir, merci de consacrer du temps pour nous. Je croyais avoir été simple et concis.. peut être un peut trop simple pour être compréhensible. L’histoire est un peu longue je vais essayer d’être plus clair. Je cherche à calculer un réseau de ventilation. Sur une arborescence de polylignes il y a des blocs (dynamiques) avec des attributs. Le but premier est de ramener la somme des débits à la source en calculant à l’avancement le débit des bouches dans la canalisation pour en déduire les diamètres mini en fonction de la vitesse. Dans un autre post : http://cadxp.com/top...052#entry266052 j’ai résolu le problème d’une branche et définit une règle pour déterminer si une branche est calculable (car toutes les sous-branches sont déjà calculées). La règle pour la construction de cet arbre, c’est que le point 1 de la polyligne est le plus éloigné de la source, 2 types de bloc sont possible sur les vertex soit une Bouche soit un Tè. Chaque branche se termine par un Té. Le bloc T s’il n’est pas le dernier cumule de Q courant de la branche et un Q auxiliaire de la branche fille. Si le T est sur une extrémité, le champ à remplir est le Qa . La condition pour que la branche parent soit calculable c'est que tous les bloc T intermédiaire aient une valeur de Qa non nulle. Cette partie du code reste à peaufiner et mériterai peut être un long débat, mais bon on va dire que ça marche pour partir directement de la liste de branches moulinée en amont a partir du dessin chargeable ici (et nécessaire pour faire des tests) http://joch04.free.f...bit-ventil3.dwg Dans le présent post,je posais une question sur la sortie d’une fonction récursive indispensable au parcours de mon arbre. Dans le code que j’ai posté ici, j’ai éludé la partie ou je mouline mon arbre pour en sortir les listes ordonnées de chaque branche pour faire un setq Listedesbranches. J'ai limité la partie (traitement à sa plus simple expression je met tous les attributs Qa de la branche à 1 Donc l’algorithme que je cherche à faire pour la fonction (explore c’est : Partir d’une copie de la liste des branchesTester la 1ere Si Qa/=0 je passe le 1er éléments à la fin et je lance (explore sur cette nouvelle liste de branche. Si Qa=0 je calcule la branche (et rempli Qa à 1 avec (traitement branche Je supprime la branche de la liste de branche (cdr Et je relance (explore sur cette liste de branche tronquée Les symptômes dans le code que j’ai posté ? ça boucle et je suis obligé de passer par le menu débogage pour arrêter l’interprétation. Le soucis, c’est que je programme 1 ou 2 fois par an et que je suis donc plutôt nul. D’où le formatage peu orthodoxe même si je t’assure j’essaye de faire de mon mieux. J'ai peur de me prendre les pieds dans les portées de variable ou d'avoir oublier un truc énorme qui m'aurai péter à la gueule en mode pas à pas (j'en fait des grosses parfois) Je passe mon temps à interpréter ligne par ligne pour corriger mes bugs. Quand j’ai écrit (explore, je n’ai pas manqué d’en faire. Mais le mode ligne par ligne ne rentre pas dans une fonction récursive. D’où mon désarroi. A force de relecture, j’ai déjà viré quelques coquilles. Je mets un point d’interruption dans la fonction de lecture d’attribut et en poursuivant l’interprétation à coup de flèche verte, je regarde ce qui se passe dans la fenêtre espion. Donc, si tu as un peut de temps pour me décoincer, ce serai super sympa (une fois de plus) car calculer une branche c’est bien, mais si on arrive à faire l’arbre complet, on duplique l’intérêt de l’outil. Si on arrive à faire tourner (explore, j’ai déjà pas mal d’autres fonctions en tête, une numérotation des bouches, un peuplement automatique des blocs sur un arbre de poly vierge… Bref je suis coincé grave. On pourrait sans doute imaginer parcourir l’arbre directement avec les listes de point (sans se servir de Qa) déjà que je ne m’en sort pas je crois bien que s’eut été encore plus ambitieux. Merci encore si tu es arrivé au bout de ce roman, mais c’est vrai, comme avec monsieur Wolf de pulp fiction, il faut être précis et exhaustif quand on demande de l’aide désespérément à un spécialiste surbooké. quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 29 mai 2018 Partager Posté(e) le 29 mai 2018 J'ai un peu essayé de regarder la fonction 'explore', la première chose que je note c'est que tu mélanges dans la même fonction du code itératif (boucle while) et du code récursif.Comme j'ai essayé de l'expliquer, il s'agit là de deux façons de penser (algorithmie) fondamentalement différentes et vouloir mixer ces deux approches ne t'aide certainement pas à résoudre ton problème. Un bon point, tu scindes ton code ton code en plusieurs fonctions, ce qui permet de résoudre les problèmes séparément à condition d'éviter les effets de bord, pour ça il suffit d'utiliser des fonctions "pures" (fonctions qui prennent des arguments et retourne une valeur sans interférer sur les variables de la fonction parent). Ceci permet de construire et tester chaque sous fonction en dehors de l'environnement du programme (tests unitaires). Par exemple, dans ton cas la fonction 'explore' qui doit traiter une liste spécifique du programme devrait pouvoir être testée et déboguée séparément avec n'importe quelle liste similaire. Avant d'ouvrir la moindre parenthèses dans l'éditeur Visual LISP, essaye de poser par écrit ce que tu cherches à faire de la manière la plus simple et la plus explicite possible : ce dont tu dispose au départ et ce à quoi tu veux arriver.Parfois c'est suffisant pour être traduit directement en code, surtout quand on a compris le fonctionnements des fonctions d'ordre supérieur (apply, mapcar, vl-remove-if, etc.) qui permettent d'écrire du code déclaratif dans lequel on écrit ce qu'on veut faire (l'intention) plutôt que la façon dont il faut le faire (la manière).Sinon, il faut que tu envisages (toujours sans écrire la moindre ligne de code) comment tu peux y arriver au résultat souhaité à partir des données initiales en utilisant uniquement de la logique binaire (si..., ...alors, ...sinon), c'est ce qu'on appelle l'algorithme (souvent différents algorithmes permette de résoudre le même problème). our ce faire, tu peux t'aider à le formaliser en utilisant un logigramme. Quand tu as réussi à décrire ton algorithme de façon claire, le code coule de source. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 29 mai 2018 Auteur Partager Posté(e) le 29 mai 2018 l'algorithme, c'est celui la: Partir d’une copie de la liste des branches Tester la 1ere Si un seul des Qa des blocs "jonction" de la branche (sauf le dernier) =0 je passe le 1er éléments à la fin et je lance (explore sur cette nouvelle liste de branche. Si tous les Qa sauf le dernier /=0 on lance (traitement branche qui rempli le Qa du bloc extrémité à 1 si on en est pas à la dernière branche Je supprime la branche de la liste de branche (cdr Et je relance (explore sur cette liste de branche tronquée je pense pas que le problème soit là. l'environnement de test, c'est le doublet Tex.lisp posté icihttp://cadxp.com/top...post__p__266116avec le dessin à charger là.http://joch04.free.f...bit-ventil3.dwg si je mélange de l'itératif et du récursif, c'est que le récursif sort les branche traitées de la liste de branches et l’itératif c'est pour parcourir la branche car on doit tester tous les nœuds pour la valider ''''''''''.l’indentation pourrie, je bosse au taff et à la maison, l’indentation auto me joue des tours.pourtant j'y met toujours un coup d’équerre avant de poster. les fonctions d'ordre supérieur (apply, mapcar, vl-remove-if, etc.).... comment dire... j'en ai une vague notion, je vais potasser.... mais ça fait refaire un algorithme... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 29 mai 2018 Auteur Partager Posté(e) le 29 mai 2018 j'ai eu un doute sur la fin de (explore ou j'ai voulu me la jouer pour faire le (setq (cdr dans le test. et puis d'avoir posé l'algo ça m'a monté quelques lacunes je pose donc une v2mais ça tourne toujours pas. ;; Tex v2, à pour test avec http://joch04.free.fr/images/vrac/debit-ventil3.dwg (defun c:tex (/ ent i in j n lay der sspoly poly lsvtx vtx pt ssblocs lsbloc bloc nombloc hbloc lsbrrecur lsbranche branche tcourant ta QA qc v doc ) (vl-load-com) (setq doc (vla-get-activedocument (vlax-get-acad-object)) ) ;_ Fin de setq (setq lsbrrecur '((("Debit" (0.0 0.0) "3804") ("jonction" (1.0 0.0) "2514") ("Debit" (2.0 0.0) "3811") ("jonction" (3.0 0.0) "2522") ("jonction" (6.0 0.0) "253E") ("jonction" (10.0 0.0) "254C") ) (("Debit" (0.5 1.0) "2B6D") ("Debit" (1.0 1.0) "2B61") ("jonction" (1.0 0.0) "2514") ) (("Debit" (3.0 4.0) "2B55") ("Debit" (3.0 2.0) "2B49") ("jonction" (3.0 0.0) "2522") ) (("Debit" (5.0 2.0) "2B31") ("jonction" (6.0 2.0) "255A") ) (("Debit" (6.0 5.0) "2B3D") ("jonction" (6.0 4.0) "34DA") ("jonction" (6.0 0.0) "253E") ) (("Debit" (8.34004 4.0) "34FE") ("jonction" (6.0 4.0) "34DA") ) ) ) ;_ Fin de setq (explore lsbrrecur) ;; ;; Explore ;; (defun explore (lsbrrecur / brl bloc nombloc nok in) (setq brl (car lsbrrecur) in 0 bloc nil nok 0 ) ;_ Fin de setq ;;boucle pour test si un bloc "jonction" (sauf le dernier) de la branche à Qa =0 (while (< in (length brl)) (setq bloc (nth in brl) hbloc (caddr bloc) nombloc (car bloc) ) ;_ Fin de setq (setq Qa (read (Vb-Val-att (handent hbloc) "Qa" ) ;_ Fin de Vb-Val-att ) ;_ Fin de read ) ;_ Fin de setq ;_ Fin de setq ;; test du Qa d'un bloc qui n'est pas le dernier si oui Nok = 1 (if (and (= 0 Qa) (/= (+ 1 in) (length lsbloc) (= "jonction" nombloc)) ) (setq nok 1) ) ;_ Fin de if (setq in (+ 1)) ) ;_ Fin de while ;; Si nok modifié a 1, on ne peut pas calculer la branche ;; on met donc ce bloc à la fin de celle ci et on rappelle explore ;; avec cette nouvelle liste en espérant que le 1er élément soit traitable (if (= nok 1) (progn (setq lsbrrecur (append (cdr lsbrrecur) (list (car lsbrrecur)) ) ;_ Fin de append ) ;_ Fin de setq ;; permutation à (gile) le 1er devient le dernier (explore lsbrrecur) ) ;_ Fin de progn ;;fp ) ;_ Fin de if ;;fi ;; ;; Si Nok = 0 la branche est traitable ;; on traite, suprime cette branche de la collection et relance sur la nouvelle liste (TraiteBranche brl) (if (/= nil (cdr lsbrrecur)) (prog (setq lsbrrecur (cdr lsbrrecur)) (print "ggrrrrr") (explore lsbrrecur) ) ) ;_ Fin de if ;;;;;;; par ici la sortie !!!! ) ;_ Fin de defun ;;;fd explore ;;;fd explore ;;;fd explore (print "sortie normale de Tex") ;;; Fin de l'undo (vla-endundomark doc) (princ) ) ;_ Fin de defun ;;fin Vsom ;; ;; Traiement d'une branche et maj Qa ;; (defun TraiteBranche (branche / i u bloc hbloc tcourant ta) (setq i 0 bloc nil ) ;_ Fin de setq (while (< i (length branche)) (setq bloc (nth branche i) hbloc (caddr bloc) ) ;_ Fin de setq (Vb-Mod-att (handent hbloc) "Qa" (rtos 100)) (setq i (+ 1 i)) ) ;_ Fin de while ;;;fw ) ;fd ;; Vb-Val-att fonction Vlisp pour lire la valeur d'un attribut (defun Vb-Val-att (ent nomatt / att val) ; ent correspond au handel du bloc (codedxf 5) à utiliser comme ça (setq toto (read (Vb-Val-att (handent handle) "REF"))) (foreach att (vlax-invoke (vlax-ename->vla-object ent) 'getattributes ) ;_ Fin de vlax-invoke (and (eq (vla-get-tagstring att) nomatt) ;comme ils disent les fou du code "tournure élégante !" (setq val (vla-get-textstring att)) ; le ET est équivalent à un si dans ce cas là ) ;car on afffecte Val que si att= nom-att bravo Patrick_35 ) ;_ Fin de foreach val ;; retour de fonction ) ;_ Fin de defun ;; fin Vb-Val-att ;; Vb-Mod-att fonction Vlisp pour modifier la valeur d'un attribut ;; à utiliser comme ça (Vb-Mod-att (handent handle) "NIV" new-val) ;; new-val est une string (defun Vb-Mod-att (ent nom-att nval / att inc vblst-att) (setq inc 0 vblst-att (vlax-invoke (vlax-ename->vla-object ent) 'getattributes ) ;_ Fin de vlax-invoke ) ;_ Fin de setq (while (< inc (length vblst-att)) (if (eq (vla-get-tagstring (nth inc vblst-att)) nom-att ) ;_ Fin de eq (vla-put-textstring (nth inc vblst-att) nval) ) ;_ Fin de if (setq inc (+ 1 inc)) ) ;_ Fin de while ) ; ; fin Vb-Mod-att mais ça marche pas mieux. et ça boucle plus ça plante... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 30 mai 2018 Auteur Partager Posté(e) le 30 mai 2018 illumination nocturne...Si je veux plus être emmerdé par le fait que l’éditeur ne veux pas faire de pas à pas dans la boucle récursive, comme j'ai fait (traitebranche qui met à jour les blocs, il faut que je fasse (testebranche qui renvoie T ou nil dans mon test d'éligibilité au traitement.En faisant ça j'ai une chance de m'en sortir... mais pas le temps aujourd’hui...en plus dans l'idée de modularité ça perpétrai de changer le test si je veux traiter un cas différent...mes excuses pour cette répétition de post, mais les sujets sont différents. quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 30 mai 2018 Partager Posté(e) le 30 mai 2018 Tu décris l'algorithme (comment faire), mais personnellement je n'ai toujours pas compris l'énoncé du problème (quelles sont les données et à quoi aboutir). C'est à dire la première étape de l'élaboration d'une fonction (ou d'un programme). Si tu veux écrire une fonction récursive, il faut que tu commence par déterminer son (ou ses) argument(s) et sa valeur de retour (les données et l'objectif du problème).Il faut ensuite que tu détermines la condition d'arrêt, c'est à dire la valeur de l'argument pour laquelle la fonction s'arrête et retourne une valeur.Il faut aussi que la fonction modifie l'argument avant de le passer à l'appel récursif de façon à tendre vers la condition d'arrêt. fonction récursive : si l'argument rempli la condition d'arrêt alors on retourne la valeur sinon on appelle récursivement la fonction en lui passant l'argument modifié Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 30 mai 2018 Auteur Partager Posté(e) le 30 mai 2018 L'énoncé du problème?En ce qui concerne l’environnement de test je ne vois pas comment être plus clair, en ce qui concerne le programme qui calcule le réseau de ventil, j'ai envie de dire pour résoudre le problème de (explore on s'en fout.les donnée d'entrée c'est une liste de liste, qui est directement au début du code il faut la parcourir suivant les règles de l'algorithme pour sortir, il faut avoir traité toutes les branches en renseignant la valeur de Qa dans le dernier bloc à la racine de l'arbre.Au bout du compte, comme je disais précédemment, je vais externaliser le test et je devrai m'en sortir. Mais bon, un 3D compliqué à rendre pour ce soir.... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
Patrick_35 Posté(e) le 30 mai 2018 Partager Posté(e) le 30 mai 2018 Salut Je suis d'accord avec (gile). Pas simple de comprendre ton besoin.Le plus simple est de donner un exemple avec les données d'entrées et le résultat souhaité. @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824 Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 30 mai 2018 Partager Posté(e) le 30 mai 2018 les donnée d'entrée c'est une liste de liste, qui est directement au début du code il faut la parcourir suivant les règles de l'algorithme pour sortir, il faut avoir traité toutes les branches en renseignant la valeur de Qa dans le dernier bloc à la racine de l'arbre. On progresse, si "branche" veut bien dire sous-liste (élément de la liste principale "arbre"), il n'y a rien de récursif dans cet énoncé, juste un traitement pour chaque élément d'une liste.(foreach branche arbre (traitement branche) ) (defun traitement (branche / ...) ...) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
x_all Posté(e) le 30 mai 2018 Auteur Partager Posté(e) le 30 mai 2018 c'est vrai... il y a des branches sur un arbre. (et je vois pas trop comment le modéliser autrement qu'avec une liste de sous liste en lisp) mais comme je l'ai expliqué peut etre trop longuement, je ne peut calculer une branche parent si la branche fille (voire la fille de la fille..) n'a pas été calculéeSi tu as un algorithme itératif pour faire ça, je suis preneur... quelques trucs sur autocad Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant