jfcantin1977 Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 BonjourJe cherche depuis quelques temps un moyen de faire une condition à savoirsi je rentre au clavier 6 caractère alors.... fait tel chosesi j'entre 7 caractère fait tel chose ou si je j'inscrit 8 caractère alors.... Je trouve des condition en Lisp mais je trouve rien qui a de 1 des elseif, je ne sais pas si cela existe en Lisp et des condition si j'entre X caratère alors... Bref comment coder cela.... merci de votre aide...
(gile) Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Salut, En LISP on utilise principalement 2 fonctions pour les procédure décisionnelles soumises à condition : if et cond. if requiert comme arguments une expression conditionnelle, un expression unique à évaluer si la conditionnelle retourne un résultat différent de nil et, optionnellement, une expression unique à évaluer si l'expression test retourne nil (else).(if expression_test expression_alors [expression_sinon]) L'équivalent de elseif consisterait à imbriquer des expressions (if ...) dans les "expression_sinon" d'expression (if.. parent) :(setq n (strlen str)) ;_ nombre de caractères de la chaîne (if (= n 6) ;_ expression test ;; alors (princ "\n6 caractères") ;;sinon (if (= n 7) ;_ expression test ;; alors (princ "\n7 caractères") ;;sinon (if (= n 8) ;_ expression test ;; alors (princ "\n8 caractères") ;;sinon (princ "\nmoins de 6 caractères ou plus de 8") ) ) ) La fonction cond permet précisément de répondre à ce cas de figure et permet d'éviter ces imbrications multiples (elle ressemble un peu au switch/case d'autres langages).cond requiert comme arguments un nombre indéterminé de listes dont le premier élément est une expression test et les éléments suivants les expressions à évaluer si la condition est remplie (l'expression test ne retourne pas nil).Les expressions tests sont évaluées tour à tour jusqu'à ce qu'une retourne un résultat non nil, les expressions de la liste de cette condition sont alors évaluées.(setq n (strlen str)) ;_ nombre de caractères de la chaîne (cond ((= n 6) (princ "\n6 caractères")) ((= n 7) (princ "\n7 caractères")) ((= n 8) (princ "\n8 caractères")) (T (princ "\nmoins de 6 caractères ou plus de 8")) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Salut jfcantin1977 Je partirai sur ceci: (setq nb_c (strlen saisie_clavier)) (cond ((= nb_c 6) (traitement1) ) ((= nb_c 7) (traitement2) ) ((= nb_c 8) (traitement3) ) ) ; cond De plus si tu veux en plus de X caractères que la saisie contiennent quelquechose de précis, je partirai alors par un remplacement de (= nb_c X) par une fonctionqui renverrai T ou NIL Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
bseb67 Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Dépassé par (Gile) ;) Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
fabcad Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Ne pas oublier de mettre un progn si plusieurs traitements dans les conditions.
bseb67 Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Oui et non fabcad, le progn ne sert que pour les "if", pour le "cond"il n'est pas utile, car dans le cond l'interpréteur lisp continuera jusqu'aubout du test "vrai" avant de sortir du cond. Rien que pour ca, je n'utilise pratiquement plus le "if" Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Rien que pour ca, je n'utilise pratiquement plus le "if" Pure coquetterie ! (mais je peux être sensible à la coquetterie ;) ) En informatique tout est ramené à des opérations binaires : oui/non, on/off, 1/0...Très certainement l'interpréteur LISP évalue une expression cond de cette façon : un enchaînement de if/else if. Ce qui expliquerait pourquoi if est toujours plus rapide que cond. Ceci dit, dans le cas de conditions multiples une expression cond rend le code plus lisible qu'un enchaînement/imbrication de if. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Ce qui expliquerait pourquoi if est toujours plus rapide que cond. Je pensais aussi que (if test to_do) était plus rapide que (cond test1 to_do1)mais pour cet exemple tout simple: Benchmarking ........Elapsed milliseconds / relative speed for 32768 iteration(s): (IF (= 1 1) (SETQ A 1)).............1031 / 1.05 0.0315ms/ité (COND ((= 1 1) (SETQ A 1))).........1031 / 1.05 0.0315ms/ité (IF (= 1 1) (PROGN (SETQ A 1))).....1078 / 1.00 0.0329ms/ité Et bien c'est la même chose :) , je suis sur qu'en faisant plusieurs benchmarkil y aura des fois une petite différence de quelques ms. J'utilise le cond au-lieu du if, car j'oubliais trop souvent le progn car en mettant deuxinstructions après le test du if, forcément la première est pour test = vrai et la secondetest = faux. Or je voulais exécuter les deux. Cet oubli du progn me vient du C avec les {} Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
jfcantin1977 Posté(e) le 5 octobre 2009 Auteur Posté(e) le 5 octobre 2009 Oublier ce message sorry[Edité le 5/10/2009 par jfcantin1977] [Edité le 5/10/2009 par jfcantin1977]
jfcantin1977 Posté(e) le 5 octobre 2009 Auteur Posté(e) le 5 octobre 2009 Rebonjour et si j'essais un autre truc.... Avec le SI j'arrive à un résultat mais avec un erreur également. J'ai essayé de mettre la fonction progn sans réultat concluant. Voici le code que j'utilise: (defun c:Jeff () (setq AngleDMS (getstring "\n Entrez une Angle DD.MMSS: ")) if((= n 7) (progn (princ (strcat "<" (substr AngleDMS 1 2) "d" (substr AngleDMS 4 2) "'" (substr AngleDMS 6 2) "''")) ) ) ) J'arrive au résultat suivant:<12d34'56''; error: no function definition: nil
(gile) Posté(e) le 5 octobre 2009 Posté(e) le 5 octobre 2009 Salut, Il y a des erreurs d'appariement de parenthèses dans ton code.Tu devrais utiliser l'éditeur Visual LISP. Pour récupérer la valeur retournée par l'expression (cond...), tu peux l'affecter à une variable :(setq result (cond ...)) (defun c:Jeff (/ AngleDMS nb_c result) (setq AngleDMS (getstring "\n Entrez une Angle DD.MMSS: ")) (setq nb_c (strlen AngleDMS)) (setq result (cond ((= nb_c 6) (strcat " (substr AngleDMS 1 1) "d" (substr AngleDMS 4 2) "'" (substr AngleDMS 6 2) "''" ) ) ((= nb_c 7) (strcat " (substr AngleDMS 1 2) "d" (substr AngleDMS 4 2) "'" (substr AngleDMS 6 2) "''" ) ) ((= nb_c 8) (strcat " (substr AngleDMS 1 3) "d" (substr AngleDMS 4 2) "'" (substr AngleDMS 6 2) "''" ) ) ) ) (princ result) (princ) ) Une solution plus simple est de rechercher la position du point dans la chaîne et d'utiliser cette position avec substr. Un exemple qui utilise une sous-routine (une sous-routine est définie par l'utilisateur avec defun et s'utilise comme une fonction LISP prédéfine) (defun jeff_convert (str / pos) (setq pos (vl-string-search "." str)) (strcat " (substr str 1 pos) "d" (substr str (+ 2 pos) 2) "'" (substr str (+ 4 pos) 2) ) ) (defun c:jeff (/ AngleDMS) (setq AngleDMS (getstring "\n Entrez une Angle DD.MMSS: ")) (princ (jeff_convert AngledMS)) (princ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
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