Aller au contenu

Messages recommandés

Posté(e)

Bonjour

par 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...

:)

 

Posté(e)

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

Posté(e)

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 !!

Posté(e)
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

Posté(e)

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...

Posté(e)

:)

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?

Posté(e) (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é par Fraid
Posté(e)

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...

 

 

Posté(e)

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

Posté(e)

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...

 

Posté(e)

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

Posté(e)

Suis pas doué du tout pour expliquer.. :rolleyes:

 

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.

Posté(e)

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 test

Si 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 ici

http://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 


Posté(e)

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

Posté(e)

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 branches

Tester 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é.

 

 

Posté(e)

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

Posté(e)

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é ici

http://cadxp.com/top...post__p__266116

avec 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...

Posté(e)

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 v2

mais ç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...

Posté(e)

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.

 

 

 

Posté(e)

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

Posté(e)

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....

Posté(e)

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 Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)
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

Posté(e)

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ée

Si tu as un algorithme itératif pour faire ça, je suis preneur...

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité