Classement
Contenu populaire
Affichage du contenu avec la meilleure réputation le 01/10/2012 dans Messages
-
Ouhaaaaaaaa...... :o Je ne regrette pas d'avoir poser la question je me doutais bien qu'il se cachait pas pas mal de chose derriere ses parenthese je n'ai plus qu'a experimenter tout cela Merci ;)1 point
-
Les arguments Dans les fonctions prédéfinies On appelle arguments (ou paramètres) d'une fonction les données passées à cette fonction pour permettre son exécution. Ces données doivent correspondre au(x) type(s) requis par la fonction. Les fonctions LISP natives (prédéfinies) requièrent, suivant les cas, 0, 1 ou plusieurs arguments. Pour certaines fonctions ces arguments peuvent être optionnels ou de nombre indéfini. Exemples : layoutlist ne requiert aucun argument : (layoutlist) => retourne la liste des onglets de présentation sqrt requiert un seul argument de type nombre : (sqrt 4) retourne 2.0 qui est la la racine carrée de l'argument de la fonction : 4 strcase requiert au moins un argument de type chaîne et, optionnellement, un second argument (T) : (strcase "Toto") retourne "TOTO" l'argument "Toto" mis en majuscules (strcase "Toto" T) retourne "toto" l'argument "Toto" mis en minuscules l'opérateur + requiert un ou plusieurs arguments de type nombre : (+ 1 5 8) retourne 14 qui est la somme des arguments 1, 5 et 8 passés à la fonction. Dans les fonctions définies par l'utilisateur La programmation AutoLISP (langage fonctionnel) consiste essentiellement en la définition de fonctions (avec la fonction defun). On peut classer ces fonctions en deux catégories : - les commandes définies en LISP, dont le nom est préfixé avec c: qui peuvent être appelées directement en ligne de commande, et, de ce fait, elles ne peuvent pas utiliser d'argument. - les fonctions définies en LISP (souvent appelées sous-routines) qui sont de nouvelles fonctions LISP utilisables exactement comme les fonctions prédéfinies. Ces 'sous-routines' peuvent donc utiliser des arguments mais ceux-ci ne peuvent pas être optionnels et leur nombre est défini dans le defun. Il est donc possible de se constituer une (ou des) bibliothèque de routines pour compléter les fonctions prédéfinies (avant l'arrivée de Visual LISP, AutoLISP ne fournissait qu'environ 250 fonctions avec lesquelles on pouvait en définir une infinité*). Un premier exemple simple pour illustrer ce propos. AutoLISP ne fournit pas de fonction qui retourne le carré d'un nombre, il est (très) facile de définir une sous-routine pour ce faire. Il faudra passer à cette sous-routine un argument : le nombre dont on veut avoir le carré en retour. (defun sqr (num) ; num est l'argument de la fonction sqr (* num num) ; l'évaluation de cette expression est le retour de la fonction sqr ) On peut, si la fonction est chargée, l'appeler depuis une autre fonction ou commande définie en LISP : (defun c:test5 (/ n) (if (setq n (getint "\nEntrez un nombre entier: ")) (princ (strcat (itoa (sqr n)) " est le carré de " (itoa n)) ) ) (princ) ) La sous routine peut, comme toute fonction avoir une ou des variables locales. Un autre exemple (un peu plus avancé et peut-être plus utile) : une fonction qui serait la complémentaire de la fonction prédéfinie member. member requiert comme argument une expression et une liste et retourne la liste à partir de la première occurrence de l'expression. (member 4 '(1 2 3 4 5 6)) retourne (4 5 6) Pour définir une fonction qui retourne la liste complémentaire (1 2 3), il faudra lui passer les mêmes arguments : l'expression 4 et la liste '(1 2 3 4 5 6) : (defun trunc (expr lst / result) ; expr et lst sont les arguments, result est une variable locale (while (and lst (not (equal expr (car lst)))) (setq result (cons (car lst) result) lst (cdr lst) ) ) (reverse result) ; le retour de la fonction ) Il est a noter que les arguments se comportent comme des variables locales. Dans la routine ci dessus, la liste lst est tronquée de son premier élément à chaque itération dans la boucle while, ces modifications n'affectent en rien la liste originelle. (defun test5 (/ lst) (setq lst '(1 2 3 4 5 6)) (princ (trunc 4 lst)) (terpri) (princ lst) (princ) ) Factoriser le code La factorisation d'un code ressemble un peu à la factorisation d'une expression mathématique. Il peut être intéressant d'extraire du code d'une fonction principale un groupe d'expressions soit parce qu'il revient plusieurs fois dans le code, soit parce qu'on pense réutiliser la fonction dans d'autres codes, soit pour des raisons de lisibilité (le tutoriel Visual LISP fournit avec l'aide d'AutoCAD, que je ne recommande absolument pas aux débutants, abuse de ce procédé et finit par rendre le code plus difficilement lisible). Un exemple avec une commande qui met les entités sélectionnées sur le calque "0" : (defun c:ssTo0 (/ ss n) (if (setq ss (ssget)) (progn (setq n 0) (while (setq ent (ssname ss n)) (setq elst (entget ent) n (1+ n) ) (entmod (subst (cons 8 "0") (assoc 8 elst) elst)) ) ) ) (princ) ) Dans ce cas, il peut être intéressant de factoriser la partie du code qui modifie le calque d'une entité pour en faire un fonction plus générique qui permettrait au programmeur de l'utiliser en spécifiant un autre calque que le calque "0". La fonction devra alors avoir 2 arguments : le nom d'entité et le nom du calque à attribuer. Dans la commande ssTo0, lors de l'appel de la sous-routine ChangeLayer, il faudra spécifier le calque "0": (defun ChangeLayer (ent lay / elst) ; ent et lay = arguments, elst = variable locale (setq elst (entget ent)) (entmod (subst (cons 8 lay) (assoc 8 elst) elst)) ) (defun c:ssTo0 (/ ss n) (if (setq ss (ssget)) (progn (setq n 0) (while (setq ent (ssname ss n)) (setq n (1+ n)) (ChangeLayer ent "0") ; appel de ChangeLayer avec 2 arguments ) ) ) (princ) ) Un autre exemple de factorisation ici Voilà, j'espère avoir été clair. N'hésitez pas à poster vos remarques, questions, etc. * Les pionniers (Reini Urban, Vladimir Nesterovsky, etc.) avaient essayé de constituer une gigantesque bibliothèque de routines complémentaires définies en LISP (StdLib) dans laquelle on trouvais les équivalents de la plupart des fonctions vl-* arrivées plus tard avec Visual LISP (exemples ici). On peu trouver ici trois bibliothèques de routines : Dialog.lsp, Vecteurs&Matrices.lsp, Listes.lsp1 point
-
Salut, Je vais essayer de répondre en 2 parties : les variables puis les arguments Les variables On appelle variable un symbole auquel est liée une valeur. En LISP, on définit les variables avec la fonction setq. setq requiert une ou plusieurs paires d'arguments : le symbole et une expression LISP dont l'évaluation donnera la valeur à la variable. (setq a 12)affecte la valeur 12 à la variable a. On redéfinit la valeur de la variable a de la même façon: (setq a 42) On distingue les variables locales et globales selon qu'elles sont ou non déclarées dans la définition d'une fonction. Si on fait : (setq a 12) en ligne de commande (ou dans la console Visual LISP) en dehors de tout code, on affecte au symbole a la valeur 12 et ce pour toute la session dans le dessin courant. On dit que a est globale. Elle conservera sa valeur tant qu'elle n'est pas redéfinie et sera accessible depuis la ligne de commande en entrant : !a. Ceci peut être pratique mais n'est pas sans danger si une fonction LISP dans laquelle la variable a est redéfinie sans être déclarée localement : (defun foo () (setq a (sslength (ssget))) (princ (strcat "\n" (itoa a) " objets sélectionnés")) (princ) ) À chaque fois que foo sera exécutée la valeur de a prendra le nombre d'entités sélectionnées. Pour éviter cela, il suffit de déclarer localement la variable a dans la fonction foo : (defun foo (/ a) (setq a (sslength (ssget))) (princ (strcat "\n" (itoa a) " objets sélectionnés")) (princ) ) Ainsi la valeur que pouvait avoir a à l'extérieur de la fonction n'affectera pas sa valeur dans la fonction et réciproquement. En résumé, à part quelques rares exceptions, il est toujours préférable de déclarer localement les variables utilisées dans une fonction. Lorsque on veut utiliser des variables globales, une convention veut qu'on mette une astérisque au début et à la fin du symbole et la prudence recommande qu'on utilise des noms ayant peu de chance d'être utilisés par d'autres fonctions : *variableGlobale*.1 point
-
coucou merci à Toi d'avoir posé la question, je vais aussi guetter les réponses à force de faire des lisp, il devient urgent d'avoir de la théorie nul doute que (giles), l'excellent ;) va venir nous apporter la substantifique explication amicalement1 point
-
Bonjour, defun truc (argument / variable) Quelque temps que je cherche quelque explication sur ce qu'il se passe entre les parentheses se trouvant apres le defun. l'argument est il une variable déclaré dans une autre fonction? qui n'est pas remis a nil ? Quand est on obligé de déclarer les variables dés le depart ? (j'ai un certain nombre de lisp qui fonctionne tres bien avec les parentheses vides) Merci de m'eclairer. je sais c'est vraiment une question de débutant, mais comme on dit y a pas de question bete...-1 points
