VDH-Bruno Posté(e) le 1 octobre 2010 Posté(e) le 1 octobre 2010 Bonjour aux membres de ce forum Utilisateur d’AutoCAD depuis la R12, je débute en AutoLISP depuis deux/trois mois, jusqu’ici j’ai réussi à trouver les solutions à mes questions basiques en parcourant les divers messages du forum débutant.Etant actuellement un peu plus familier avec la syntaxe du langage, mes ambitions grandissent ainsi que mes difficultés, je poste donc pour la première fois.. L’objectif que je me suis fixé : C’est de traiter une Liste représentant des longueurs (REAL), du style : '(4.0 7.5 5.0 9.0 9.0 4.0 7.5 7.5 5.0 8.25 9.0 5.0) Pour obtenir en retour une liste du style : '((2 4.0) (3 5.0) (3 7.5) (1 8.25) (3 9.0)) C'est-à-dire une liste ordonnée en fonction des longueurs, et comptabilisant le nombre de longueur identique. J’appréhende la résolution de la manière suivante (au vu de mes maigres connaissances et pérégrinations sur ce forum) 1 – Trier la Liste et en supprimant les doublons. Pour ce faire j’ai employé [surligneur] vl-sort [/surligneur]avec syntaxe suivant : (setq LstOrd (vl-sort LstLong '<)) A la lecture des exemples de l’aide, et une explication de (Gille) dans ce sujet : http:// http://www.cadxp.com//modules.php?op=modload&name=XForum&file=viewthread&fid=100&tid=10385, j'ai pensé (bien que ce soi une fonction VLisp, de toute façon il faudra bien que j'y vienne par la suite) que c'était la plus adapté.. (sic l’anglais n’est pas ma tasse de thé, allemand 1ère langue puis avec les aléas de la vie j’ai acquis quelques mots d’arabe et des notions dans un dialecte berbère du sud Marocain. Mais pas d’anglais à mon vocabulaire !) 2 – Puis effectuer une boucle sur chaque élément de la Liste Ordonnée (LstOrd) pour comptabiliser dans la Liste de Longueur (LstLong) le nombre de longueur identique, Pour le comptage des éléments doubles j’ai adapté (enfin je crois !) une fonction proposé par Elpanov Evgeniy sur ce forum : (setq l '(4.0 7.5 5.0 9.0 9.0 4.0 7.5 7.5 5.0 8.25 9.0 5.0)) (apply '+(mapcar '(lambda(x)(if (= x 9.0)1 0))l)) Parmi les nombreuses fonctions de comptage répertorié dans le forum, j’ai ciblé celle-ci pour sa concision, le style, l’absence de fonctions vl- (qui me sont complètement étrangère) et l’emplois des fonctions apply mapcar lambda que je m’efforce de maitriser (c’est encore loin d’être fait… :casstet: ) Mon code : (qui hélas bug !!) (defun Tri&Comp (LstLong / LstOrd Result Nbr&Long) (vl-load-com) ;; Trie la liste de façon strictement croissante (setq LstOrd (vl-sort LstLong '< )) ;; Boucle tant qu'il y a des Longueurs à comptabiliser (while LstOrd ;; Construction de la liste (Nbr & Long) (setq Nbr&Long (list ;; Compte le nbr élément identique dans la liste (apply '+ (mapcar '(lambda (x) (if (= x (car LstOrd)) 1 0 ) ;_ Fin de if ) ;_ Fin de lambda LstLong ) ;_ Fin de mapcar ) ;_ Fin de apply (car LstOrd) ) ;_ Fin de list ) ;_ Fin de setq ;; Construction de la liste de résultat ((Nbr1 & Long1) (Nbr2 & Long2) etc...) (if Result (setq Result (append Result (list Nbr&Long))) (setq Result (list Nbr&Long)) ) ;_ Fin de if ;; Retire le 1er élément comptabiliser pour la suite du traitement (setq LstOrd (cdr LstOrd)) ) ;_ Fin de while Result ) ;_ Fin de defun Résultat : _$ (Tri&Comp '(4.0 7.5 5.0 9.0 9.0 4.0 7.5 7.5 5.0 8.25 9.0 5.0)) ((2 4.0) (2 4.0) (3 5.0) (3 5.0) (3 5.0) (3 7.5) (3 7.5) (3 7.5) (1 8.25) (3 9.0) (3 9.0) (3 9.0))Voilà c’est hélas assez loin du résultat escompté.. Interprétation : Donc en triturant mon code et les fonctions Lisp utilisés, j’ai remarqué que la fonction vl-sortCe comportait différement avec une liste d’entiers et liste de réels Exemples : Liste d'entiers (suppression des doublons) _$ (vl-sort '(4 7 5 9 9 4 7 7 5 8 9 5) '<) (4 5 7 8 9) Liste d'entiers (pas de suppression des doublons) _$ (vl-sort '(4.0 7.5 5.0 9.0 9.0 4.0 7.5 7.5 5.0 8.25 9.0 5.0) '<) (4.0 4.0 5.0 5.0 5.0 7.5 7.5 7.5 8.25 9.0 9.0 9.0) Consolation: mon code fonctionne trés bien avec des nombres entiers (hélas je travaille exclusivement avec des rélles ;) ) _$ (Tri&Comp '(4 7 5 9 9 4 7 7 5 8 9 5)) ((2 4) (3 5) (3 7) (1 8) (3 9)) En conclusions : En 1- Je constate le comportement de [surligneur] vl-sort [/surligneur]mais je ne me l’explique pas, une petite aide sur la question serai le bien venu.. merci pour celui qui voudra bien me renseigner. En 2- D’une manière général j’aimerais bien avoir un retour sur mon code (dans le soucis de progresser) même si j’ai bien conscience de son imperfection. Dans mes recherche sur le forum je ne doute pas de trouver la fonction toute faite (et je ne suis pas contre pour confronter les solutions), mais j’arrive à un stade de mon apprentissage ou j’aspire plus à les écrire par moi-même plutôt que de continuer à assembler les fonctions des autres. Pour la suite, j’essaierai d’être plus concis dans mes messages mais étant donné que c’est le premier dans ce forum considérez que c’était également pour moi une façon de me présenter. CordialementVDH EDIT 1: Mon exemple ne fonctionne pas même avec des entiers, il faut que je revois cela.. plus tard (pourtant il m'avais semblé.. faut que je revois mes différente version).EDIT 2: Désolé pour les smileys dans les ligne de codes, il n'y a pas que le Lisp que je ne maitrise pas encore.. :cool: EDIT 3: Corrigé mon code (manqué une parenthèse et modifié une variable), un malencontreux copier coller de l'ancienne version.., [Edité le 1/10/2010 par VDH-Bruno][Edité le 1/10/2010 par VDH-Bruno] [Edité le 1/10/2010 par VDH-Bruno] Apprendre => Prendre => Rendre
Tramber Posté(e) le 1 octobre 2010 Posté(e) le 1 octobre 2010 Hello, pour les smileys, faut juste s'habituer !Aucun webmaster n'a osé s'y attaquer ! (setq trie(vl-sort LstLong '(setq linulle nil compt 0) (while trie(if(=(car trie)(cadr trie)) (setq compt(1+ compt)trie(cdr trie)) (setq linulle(append linulle(list(list(1+ compt)(car trie)))) trie(cdr trie) compt 0))) linulle Pour ma petite fonction, je ne me suis pas cassé la tête (juste un peu).On peut le faire en Vlisp, je pense avec du récursif en ne se servant que de vl-every ou vl-some. Je le dis d'instinct. Mais face à une telle question, tu as vu, j'ai eu un vieux réflexe de faire du bon Autolisp. VL-SORT est tout simple : il classe et élimine les doublons. JE réfléchis un peu mais il doit aussi y avoir une solution avec la comparaison de trie avec LstLong .A+ Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
Tramber Posté(e) le 1 octobre 2010 Posté(e) le 1 octobre 2010 Tiens, mais c'est idiot ce que je dis puisque je me suis servi de la propriété contraire mais :"Duplicate elements may be eliminated from the list."Les doublons ne sont pas éliminés. Sans doute car ce sont des réels et non des entiers. (vl-sort '(4 4 4 4) 'renvoie une liste à 1 élt.(vl-sort '(4. 4. 4. 4) 'renvoie une liste à 4 élts ! Attention. Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
VDH-Bruno Posté(e) le 1 octobre 2010 Auteur Posté(e) le 1 octobre 2010 Merci pour ta réponse Tramber Je vais décortiquer tranquillement (et à tête reposé) tes lignes de codes.Oui visiblement vl-sort supprime les doublons pour les chaînes et les entiers, mais pas pour les réels c'est justement ce qui me trouble dans cette histoire.. Une explication serai le bienvenu si quelqu'un la connait..Sinon en plus du smiley dans la ligne de code, il fait visiblement sauter une parenthèse une fin de ligne. J'ai essayé en vain de la rajouter (c'est génant pour ceux qui voudraient tester), peut être en la doublant, à suivre.. Merci et au revoir Apprendre => Prendre => Rendre
Tramber Posté(e) le 1 octobre 2010 Posté(e) le 1 octobre 2010 Citation Oui visiblement vl-sort supprime les doublons pour les chaînes et les entiers, mais pas pour les réels c'est justement ce qui me trouble dans cette histoire.. Une explication serai le bienvenu si quelqu'un la connait.. C'est comme cela et c'est tout. C'est pour ça que j'ai extrait l'anglais. Littéralement "may be eliminated" signifie les doublons "peuvent être éliminés". Pas d'explication puisque c'est la doc. Pour le code : le forum est concu pour afficher des BBcode sous forme de smiley. Je ne sais pas si parmi nous il y a des astucieux mais glisse déjà des espaces là où sa coince, il ne reconnaitra plus les smileys. Je mets ";" suivi de ")" avec ou sans espaces dans les 2 lignes suivantes, regardes le résultat !; );) (setq trie(vl-sort LstLong '(setq liverite(mapcar '(lambda (x y)(= x y))(cdr trie) trie )) Je réfléchis à tonproblème pour donner une solution qui tue mais c'est coton !Ci-dessus un code dont j'ai tenté de me servir. Occasion pour donner une petite explication. mapcar applique une opération à tout élément d'une liste. Mais il devient encore plus tordu de considérer qu'il peut le faire d'un élément de liste à celui correspondant en position mais contenu dans une autre.Ainsi j'ai exposé 2 listes (d'où le x et le y pour les éléments repsectifs extraits de ces 2 listes).J'ai exposé la liste trie et la liste (cdr trie), allégée du premier élément. Voilà donc une liste de vérité, livérité qui dit oui ou non si chaque voisin est égal au précédent. Elle juste d'une longeur n-1, ce qu'il faut traiter.Et pire de tout, elle ne fait pas avancer le schmilblick ! Mais ca t'en apprends peut-être ? [Edité le 1/10/2010 par Tramber] Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
VDH-Bruno Posté(e) le 1 octobre 2010 Auteur Posté(e) le 1 octobre 2010 Bonsoir, Euréka j'ai trouvé.. pour le Smileys et la parenthèse manquante en fin de ligne Rappel du problème d'affichage : _$ (vl-sort '(4 7 5 9 9 4 7 7 5 8 9 5) '<) (4 5 7 8 9) _$ Après plusieurs essaie, il suffit de rajouter un espace après le < et la parenthèseCe qui donne : _$ (vl-sort '(4 7 5 9 9 4 7 7 5 8 9 5) '< ) (4 5 7 8 9) _$ On alors en ne se servant pas du formatage.._$ (vl-sort '(4 7 5 9 9 4 7 7 5 8 9 5) '<)(4 5 7 8 9)_$ Et cela ne gène en rien l'interprétation dans Visual Lisp :D Ca progresse.. ça progresse.. à vitesses grand V, espérons que ça en aille de même en Lisp.. ;) Edit: Zut. Je me suis fait doublé pour l'explication sur BB Codes, j'ai l'air malin avec mes explication qui font doublons maintenant.. :casstet: Merci pour l'explication Tramber [Edité le 1/10/2010 par VDH-Bruno] [Edité le 1/10/2010 par VDH-Bruno] Apprendre => Prendre => Rendre
VDH-Bruno Posté(e) le 1 octobre 2010 Auteur Posté(e) le 1 octobre 2010 Merci Tramber de l’intérêt que tu porte à mon problème, j’avoue que tes explications sur mapcar ne sont pas encore très évidentes pour moi, mais je suppose que cela doit être un point de passage obligé dans l’apprentissage du Lisp, je l’avais mis à mon "planning" mais après une meilleure maîtrise de l’éditeur visual et des outils de suivie pour mieux comprendre le fonctionnement de cette fonction.A+ Apprendre => Prendre => Rendre
(gile) Posté(e) le 1 octobre 2010 Posté(e) le 1 octobre 2010 Salut, Une réponse basée sur quelques challenges LISP. Pour dénombrer le nombre d'éléments identiques dans une liste : Challenge 3 On avait noté le fonctionnement bizarre de vl-sort dans le challenge 13 et bien joué avec des routines de tri qui ne suppriment pas les doublons dans le challenge 20. Pour répondre au problème en utilisant la routine test3 du challenge 3 (modifiée pour inverser l'ordre des paires pointées) et la routine tri d'Evgeniy Elpanov dans le challenge 20 ;; tri (Evgeniy Elpanov) ;; comme vl-sort mais sans supprimer les doublons (defun tri (lst fun) (mapcar (function (lambda (x) (nth x lst))) (vl-sort-i lst fun) ) ) (defun Tri&Comp (lst / sub) (defun sub (lst n) (if (cadr lst) (if (equal (car lst) (cadr lst)) (sub (cdr lst) (1+ n)) (cons (cons n (car lst)) (sub (cdr lst) 1)) ) (list (cons n (car lst))) ) ) (sub (tri lst ') PS : pour les smileys, il suffit de cocher la case "Désactiver les smileys?" Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 2 octobre 2010 Posté(e) le 2 octobre 2010 Re, J'ai répondu un peu vite hier soir, et t'ai dirigé vers de liens où les codes sont peut-être un peu ardu à comprendre pour un débutant (mais il me semble que tu es déjà pas mal dégrossi). De toutes façons, la lecture (et la compréhension) de codes écrits par d'autre est aussi un excellent moyen d'apprendre. J'ai surtout oublié de te souhaiter la bienvenue sur CADxp et je tenais à te féliciter pour la clarté de ton premier message : explicite, détaillé et témoignant d'un travail de recherche sur le site et d'une volonté d'apprendre (ce qui est loin d'être le cas pour certains...). J'ai essayé à plusieurs reprises d'expliquer les fonctions mapcar, apply, lambda, etc. la dernière fois dans ce sujet (réponse 5). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Tramber Posté(e) le 2 octobre 2010 Posté(e) le 2 octobre 2010 Avec le génie d'Eugène et la patience et le gout de la précision de (gile), te voilà bien entouré ! Pour les smileys et la desactivation du BBCode, j'ai un peu la honte car je n'avais pas pensé à cette solution que j'applique parfois,...quand j'y pense :cool: (setq LstLong '(4.0 7.5 5.0 9.0 9.0 7.5 7.5 5.0 8.25 9.0 5.0)) (setq trie(vl-sort LstLong '(setq lisorti nil) (setq valeurencours nil cont 0) (setq trie(append(list(car trie))trie)) (mapcar '(lambda (x y)(if(= x y) (setq cont(1+ cont)valeurencours x) (setq lisorti(append lisorti(list(cons cont valeurencours))) cont 1 valeurencours y))) trie(cdr trie) ) (setq lisorti(append lisorti(list(cons cont valeurencours)))) lisorti Voivi un modeste code qui a l'air de fonctionner. Il est sur le principe de ma précédente proposition mais évite le WHILE ou un REPEAT grâce à MAPCAR et se trouve un peu amélioré. Un peu d'explications :(setq trie(append... est une astuce qui allonge la liste au début afin de comparer le n°1 avec lui même, en quelque sorte (c'est l'amélioration sus-citée).Dans le lambda, je déclare 2 listes : l'une complète, l'autre vidée du 1er élément. et je fais un if tout bête.Ex au 2ème tour du mapcar : x=4.0 et y=7.5 alors(= x y) est nul. Donc 2ème SETQ qui en finit avec le comptage des 4.0 en agrandissant lisorti et en remettant le compteur (cont) à 1 et la valeur en cours à 7.5.Et ainsi de suite.A la fin, on n'oublie pas d'ajouter le résultat de la dernière valeur en cours. Je n'ai pas beaucoup participé aux challenges de CADxp, il s'agissait de périodes pendant lesquelles j'étais sans doute indisponible ou occupé. Mais il est vrai que si tu tapes déjà du mapcar et compagnie en débutant, tu vas aller loin. Pas comme certains (que ceux qui se sentent visés me pardonnent, je ne pense pas à beaucoup de monde) ! Mais ne profitons pas de ce message pour faire de la politique ou enfoncer des clous, mes excuses VHD-Bruno. Voilà, il y a certainement d'autres solutions encore et je suis resté un peu bloqué. D'autres préférerons des codes plus "esthétiques", plus puissant et c'est tout à leur immense honneur ! Je préfère d'ailleurs le code proposé par (gile).Un nouveau Challenge peut-être ? Ou est-il inutile d'aller plus loin ? Je crois que c'est inutile. Je teste un peu plus en avant mon code avant de manger ! [Edité le 2/10/2010 par Tramber] Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
Tramber Posté(e) le 2 octobre 2010 Posté(e) le 2 octobre 2010 Bon, il y a déjà un problème : les entiers !Mais, comme le précise (gile) un peu plus haut, il suffit d'utiliser une autre fonction. J'ai regardé le code de (gile) un peu plus en avant.C'est quand même balaise le récursif :exclam: [Edité le 2/10/2010 par Tramber] Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
VDH-Bruno Posté(e) le 2 octobre 2010 Auteur Posté(e) le 2 octobre 2010 Bonsoir, (gile), merci pour ton message de bienvenue, les liens et ton codes : _$ (Tri&Comp '(4.0 7.5 5.0 9.0 9.0 4.0 7.5 7.5 5.0 8.25 9.0 5.0)) ((2 . 4.0) (3 . 5.0) (3 . 7.5) (1 . 8.25) (3 . 9.0))Il répond parfaitement à ma demande, j’espère trouver le temps dans la semaine pour le décortiquer et assimiler, ainsi que tes liens. Citation il me semble que tu es déjà pas mal dégrossiMerci, c’est surtout le forum débuter en Lisp que j’ai pas mal dégrossi.. (J’ai consulté les messages en entête, et je parcours le forum depuis sa création, j’en suis à la fin 2006..). Je m’efforce d’avancer de façon méthodique déformation professionnel sans doute (projeteurs structure béton armé et précontraint à l’origine). Citation PS : pour les smileys, il suffit de cocher la case "Désactiver les smileys?"Evidemment, maintenant que tu l’écris je vois la coche, pourquoi faire simple quant on peut faire compliqué… Tramber, merci pour tes encouragements, j’ai également testé tes lignes de codes : ‘(4.0 7.5 5.0 9.0 9.0 7.5 7.5 5.0 8.25 9.0 5.0) … … ((1 . 4.0) (3 . 5.0) (3 . 7.5) (1 . 8.25) (3 . 9.0)) _$Elles me conviennent également, comme pour celles de (gile) j’espère pouvoir les décortiquer un peu plus dans le courant de la semaine. Je pense clôturer ce sujet que je considère comme résolu, en espérant y revenir dessus lorsque j’aurais écris ma propre fonction, pour la suite je pense enchaîner sur les jeux et autres filtres de sélections.. Apprendre => Prendre => Rendre
Tramber Posté(e) le 3 octobre 2010 Posté(e) le 3 octobre 2010 Citation Je m’efforce d’avancer de façon méthodique déformation professionnel sans doute (projeteurs structure béton armé et précontraint à l’origine). En somme, tout lire comme tu le fais, c'est précontraindre. Tu vas bientôt couler, décoffrer et relacher la tension quand ca sera sec ! Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
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