Aller au contenu

Passer une fonction dans une fonction ?


stephan35

Messages recommandés

Bonjour à tous,

 

Mon problème est le suivant:

 

Je crée des fonctions:

(defun @R1 ( $a / )

...

)

 

(defun @R2 ( $a / )

...

)

 

(defun @R3 ($a / )

...

)

 

Je créé une fonction principale dans laquelle je veux appeler une fonction secondaire en parametre variable :

 

(defun @Princ ( @macro $a / )

(@macro $a)

)

 

Si je tape :

(@princ @R1 "po")

 

je cherche à appliquer (@macro $a) = (@R1 $a) !!! :casstet:

 

Est-ce possible ???

 

Merci !

 

 

Lien vers le commentaire
Partager sur d’autres sites

Je ne comprends pas, ça marche (même si ta logique me dépasse)

(defun @R1 ($a)
 (princ (strcat "\nFonction @R1, argument " $a))
)

(defun @R2 ($a)
 (princ (strcat "\nFonction @R2, argument " $a))
)

(defun @R3 ($a)
 (princ (strcat "\nFonction @R3, argument " $a))
)

(defun @Princ (@macro $a)
 (@macro $a)
 (princ)
)

 

(@princ @R1 "po") --> Retourne Fonction @R1, argument po

 

@+

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

Lien vers le commentaire
Partager sur d’autres sites

Et oui çà marche !

En écrivant l'énoncée du problème j'avais corrigé mon erreur ... :casstet:

 

(@princ @R1 "po") et non (@princ (@R1) "po") , milles excuses !!!!!! :(

 

 

 

Je ne comprends pas, ça marche (même si ta logique me dépasse)

 

Je ne sais pas si je dois le prendre comme un compliment ? ;)

 

En fait, je remprends l'ensemble de mes listings en compilant les lignes d'écritures, soit au bas mot 250 lisp à revoir,et je me suis apperçu que dans 60% des cas je réécrivais ce que j'avais déjà écrit ailleur avec une ou deux variantes ....

Comme tout le monde j'avais quelques fonctions définient dans le AutoCAD.lsp mais j'en ai créé une ribambelle à droite à gauche etc., Mon objectif est de réduire au minima les lignes de codes en créant des tronc commun, les variantes seront passées en paramètres dans les fonctions, y compris les fonctions appelées dans les fonctions .... :casstet:

on y vient : tous mes ssget seront par exemple réduit à une fonction, idem pour l'exploration du résultat du ssget, exemple :

 

 (setq $nom_bloc (@R2 (setq &e (entget (setq #e (car(entsel)))))))
 ; Selectionne dans le document tous les blocs portant ce nom
 (@SS_@R0_@R2 (@R0 &e)(@R2 &e))

 

@R0 = assoc 0 &e

@R2 = assoc 2 &e

 

   (defun @R2 ( &entget / tmp )
   (if (not &entget)(progn (alert (strcat "@R2 \nValeur nil pour &entget"))(exit)))
   (cdr(assoc 2 &entget))
   )

 

Puis une macro qui explore le jeu de selection :

 

 (defun @X_SS (#SS @macro/ #C)
   ;(if (not #SS)(progn (alert (strcat "@X_SS \nValeur nil pour #SS"))(exit)))
   (if (not @MX_SS)(progn (alert (strcat "@X_SS \nMacro nil pour @MX_SS"))(exit)))
   (setq #C 0)
   (if #SS
     (repeat (sslength #SS)
(setq #SSN (ssname #SS #C))
(@Macro #SSN)
(setq #C (1+ #C))
)
     )
 )

 

Une macro de traitement dans le jeu de selection

 

 (defun @MX_SS ( #SSN / )
  (print (@S_AE #SSN "ATTRIB" "L3" 1 nil))

  (@S_AE #SSN "ATTRIB" "L3" 1
  (strcat ":"
    (@S_AE #SSN "ATTRIB" "L3" 8 nil)
	  ":"
	  (@S_AE #SSN "ATTRIB" "L3" 1 nil)
	  )
  )		  
   )

 

Et enfin on l'utilise

(@X_SS #SS @MX_SS)

 

 

 

Etc.

 

Bref, sur un test comparatif , répétérif (repeat 500) sur une routine développé de la sorte et une autre développé en linéaire ,le temps gagné est divisé par 20 ;) (et je ne sais pas pourquoi !) ... :casstet:

 

Voilà !

 

[Edité le 5/3/2007 par stephan35]

Lien vers le commentaire
Partager sur d’autres sites

Je veux bien te croire, mais il faut être très rigoureux

Le problème avec ce type de logique, c'est la compréhension du lisp qui devient vite du chinois si on ne met pas un minimum de commentaires

Il faut être ingénieur pour te suivre ;)

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

Lien vers le commentaire
Partager sur d’autres sites

Il est vrai qu'il faut laissé une floppée de commentaire, pour le cas ou on y revient 6 mois après .... ;)

 

Mais aussi, avec une simple convention de repère que l'on s'impose, les choses vont toutes seules ... (en téhorie ...) ;)

 

Exemple: pour les variables :

$tmp = chaine

#tmp = valeur

&tmp = liste niveau 0

&&tmp = liste imbriquée

&&&tmp = etc

@tmp = fonction

(@tmp $tmp) = fonction avec 1 chaine en entrée

 

et l'on peut tout imaginer ....

 

d'ailleurs pourquoi ne pas proposer à autodesk de faire de la déclaration de variable pour le lisp ......... (ça va mettre le bazar ? :casstet: )

 

A+

Lien vers le commentaire
Partager sur d’autres sites

Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe !!!!!!!

 

Bon ça ne marche pas ? :cool:

 

Si ici :

 

 (defun @R1 ($b / )
(princ (strcat "\nFonction @R1, argument " $b))
)

(defun @R2 ($b / )
(princ (strcat "\nFonction @R2, argument " $b))
)

(defun @R3 ($b / )
(princ (strcat "\nFonction @R3, argument " $b))
)

(defun @Princ (@macro $a / )
(@macro $a)
(princ)
)

(@Princ @R1 "opop")
(@Princ @R2 "opop")
(@Princ @R3 "opop")

 

 

Fonction @R1, argument opop

Fonction @R2, argument opop

Fonction @R3, argument opop

 

Alors :

 

 (defun @X_SS (@Macro #SS / #C)
   (if (not #SS)(progn (alert (strcat "@X_SS \nValeur nil pour #SS"))(exit)))
   (if (not @Macro)(progn (alert (strcat "@X_SS \nMacro nil pour @MX_SS"))(exit)))
   (setq #C 0)
   (if #SS
     (repeat (sslength #SS)
(@Macro (setq #SSN (ssname #SS #C)))
(setq #C (1+ #C))
)
     )
 )


 (defun @MX_SS ( #SSN / )
   (setq &Liste_Globale(@S_AL_@R-1_@R2_@R1 #SSN "ATTRIB" (list "RA""RB""RC""RD""RE""RF""RG""RH""RI""RJ""RK""RL""RM""RN""RO""RP""RQ""RR""RS""RT""RU""RV""RW""RX""RY""RZ""DATEA""DATEB""DATEC""DATED""DATEE""DATEF""DATEG""DATEH""DATEI""DATEJ""DATEK""DATEL""DATEM""DATEN""DATEO""DATEP""DATEQ""DATER""DATES""DATET""DATEU""DATEV""DATEW""DATEX""DATEY""DATEZ""DESIGNATIONA""DESIGNATIONB""DESIGNATIONC""DESIGNATIOND""DESIGNATIONE""DESIGNATIONF""DESIGNATIONG""DESIGNATIONH""DESIGNATIONI""DESIGNATIONJ""DESIGNATIONK""DESIGNATIONL""DESIGNATIONM""DESIGNATIONN""DESIGNATIONO""DESIGNATIONP""DESIGNATIONQ""DESIGNATIONR""DESIGNATIONS""DESIGNATIONT""DESIGNATIONU""DESIGNATIONV""DESIGNATIONW""DESIGNATIONX""DESIGNATIONY""DESIGNATIONZ""PREPA""PREPB""PREPC""PREPD""PREPE""PREPF""PREPG""PREPH""PREPI""PREPJ""PREPK""PREPL""PREPM""PREPN""PREPO""PREPP""PREPQ""PREPR""PREPS""PREPT""PREPU""PREPV""PREPW""PREPX""PREPY""PREPZ""VERIFA""VERIFB""VERIFC""VERIFD""VERIFE""VERIFF""VERIFG""VERIFH""VERIFI""VERIFJ""VERIFK""VERIFL""VERIFM""VERIFN""VERIFO""VERIFP""VERIFQ""VERIFR""VERIFS""VERIFT""VERIFU""VERIFV""VERIFW""VERIFX""VERIFY""VERIFZ""APPA""APPB""APPC""APPD""APPE""APPF""APPG""APPH""APPI""APPJ""APPK""APPL""APPM""APPN""APPO""APPP""APPQ""APPR""APPS""APPT""APPU""APPV""APPW""APPX""APPY""APPZ")))
   )

(@X_SS @MX_SS #SS)

 

devrait fonctionner ?????? :casstet:

 

Hum Hum ....

Lien vers le commentaire
Partager sur d’autres sites

Oui sauf qu'il manque la définition de @S_AL_@R-1_@R2_@R1 et de #SS

 

@+

 

ps : en te servant de l'éditeur vlisp puis ctrl+alt+f pour ton code, tu remarqueras que tuu as des espaces qui ne sont pas au bon endroit dans ta liste

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

Lien vers le commentaire
Partager sur d’autres sites

e temps gagné est divisé par 20

 

Quand j'ai commencé le lisp, une recommandation de coder les variables sur 6 caractères maxi était conseillé pour la rapidité d'éxecution.

 

Bien que les machines soit devenues de plus en plus rapide, je pense (mais cela est à vérifier) que cela reste d'actualité. En effet (setq var_1 987.654) prendrait moins de place en mémoire que (setq ma-variable_numéro1 987.654).

 

Personnellement sans savoir si ceci est encore d'actualité, j'essaie d'appliquer encore cette règle, pour ne pas pénaliser le temps d'exécution (peut être que de 6 caractère cela est passé à 12?)

 

Donc ta technique de condenser tes noms de variables et/ou fonction, bien que vite illisible améliore le temps d'exécution.

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Pour aller plus vite ....... :

 

J'ai un bloc avec une série d'attributs :

(list "RA""RB""RC""RD""RE""RF""RG""RH" ....... etc

d'ailleurs mon bug viendrait de la longueur de cette liste :casstet:

 

Imaginons une fonction qui permette d'explorer un bloc pour en extraite le contenu d'un attribut :

 

;#SSN nom de l'entité d'un jeu de selection
;$T Type = "ATTRIB"
;$E Etiquette
$Valeur si nil , on lit, si = "***" on écrit la valeur
(defun @S_AE ( #SSN $T $E #t $valeur / &Be $Be0 R)
   (if (not #SSN)(progn (alert (strcat "@S_AE \nValeur nil pour #SSN"))(exit)))
   (if (not $T)(progn (alert (strcat "@S_AE \nValeur nil pour $R"))(exit)))
   (if (not $E)(progn (alert (strcat "@S_AE \nValeur nil pour $V"))(exit)))
   (if (not #t)(progn (alert (strcat "@S_AE \nValeur nil pour #t"))(exit)))
   (setq &Be (entget #SSN))
   (setq $Be0 (@R0 &Be))
   (while (and (/= $Be0 "SEQEND") (/= (entnext #SSN) nil))
     (setq &Be (entget (setq #SSN (entnext #SSN))))
     (setq $Be0 (@R0 &Be))
     (if (= $Be0 $T) ;Attribut
    (if (= $E (@R2 &Be)) ; Si Etiquette ok
	(if (not $valeur)
	  (progn
	    (cond
	      ((= #t 8)(setq R (@R8 &Be)))
	      ((= #t 1)(setq R (@R1 &Be)))
	      ((= #t 2)(setq R (@R2 &Be)))
	      )
	    )
	  (progn
	    (cond
	      ((= #t 8)(setq R (@W8 &Be $valeur)))
	      ((= #t 1)(setq R (@W1 &Be $valeur)))
	      ((= #t 2)(setq R (@W2 &Be $valeur)))
	      )
	    )
	  )
      )
)
     )
   R
   )

 

Mon problème est que dans certains cas, j'ai 25 attributs dans un bloc, donc je vais le scruté 25 fois pour en extraire les valeurs !!!

 

Donc j'ai développé une fonction qui construit une liste en une seul passe de bloc, qui pour chaque attribut regarde si celui-ci est à extraire, puis l'ajoute a la liste résultante .... :casstet:

 

(+ Rapide)

 

[surligneur] N'y aurait-il pas une solution qui permet rapidement d'extraire la valeur d'un attribut ou de tout autre élément d'un bloc dans devoir passer le bloc en revue ????? (sans handle et sans n° entité bien surrrr !)[/surligneur]

 

à vos clavier .... ;)

 

:casstet: :casstet: :casstet: :casstet: :casstet: :casstet: :casstet:

 

Merci

Lien vers le commentaire
Partager sur d’autres sites

Comme ceci

 

(setq bl (vlax-ename->vla-object (car (entsel))))
(foreach att (vlax-invoke bl 'getattributes)
 (princ (strcat "\nEtiquette : " (vla-get-tagstring att) ", Valeur : " (vla-get-textstring att)))
)

 

@+

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

Lien vers le commentaire
Partager sur d’autres sites

Ok merci,

 

Cependant, malgré tout, tu scrutes la totalité de la séquence bloc ! :cool: , Donc perte de temps !

 

Si je veux juste extraire la valeur contenue dans l'étiquette "L1" je suis obligé de faire un teste pour chaque att du foreach ???? N'est-ce pas ?

 

Et avec le SSGET, on ne peut toujours pas, non plus, accèder directement à un attribut spécifique !

 

[surligneur] as-tu une solution ???[/surligneur]

 

Je vais quand même comparer les 2 versions (Lisp <> Vlisp) ! avec le test sur chaque att

 

Merci, a+

 

Ps: je viens de me rendre compte que le sujet vient de changer ???

 

[Edité le 6/3/2007 par stephan35]

Lien vers le commentaire
Partager sur d’autres sites

Et non, je ne scrute pas tout le bloc mais uniquement les attributs que je récupère dans une liste.

 

Si tu sais que l'étiquette L1 est le 3em Attribut, tu peux faire

(setq bl (vlax-ename->vla-object (car (entsel)))
     at (nth 2 (vlax-invoke bl 'getattributes)))

 

Si tu ne connais pas sa position, mais que tu veux quand même la récupérer

(setq bl (vlax-ename->vla-object (car (entsel))))
(vl-remove-if-not '(lambda (x) (eq (vla-get-tagstring x) "L1")) (vlax-invoke bl 'getattributes))

 

@+

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

Lien vers le commentaire
Partager sur d’autres sites

Voici une partie des résultats :

 

[surligneur] FRAPPADINGUE ![/surligneur]

 

Donc sur une boucle de 500 (répété 3 fois)

La méthode Linéaire est de 32 Sec

Le méthode fonction imbriquées 38 sec

:(

 

J'ai raccourcis mes noms de fonctions et de variables

 

Même teste:

La méthode Linéaire est de 27 Sec

Le méthode fonction imbriquées 20 sec

 

Conclusion proposée :

Raccourcir les noms de variable à 6 char max, idem pour les fonctions !

 

si quelqu'un pouvais confirmer !

 

Je continue avec le méthode de patrick_35 .... ;)

 

Lien vers le commentaire
Partager sur d’autres sites

Voici la seconde partie des résultats :

 

[surligneur] DINGUE !!! [/surligneur]

 

La méthode vlax-*** est à proscrire pour des traitements répétitifs , c'est trop long ...

2min 18 pour 280 / 500 , bref, j'ai coupé en cours de route ... :(

 

Cette méthode est cependant plus simple à écrire, c'est vrai !

 

à revérifier ....

 

 

Lien vers le commentaire
Partager sur d’autres sites

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é