Aller au contenu

Classement

Contenu populaire

Affichage du contenu avec la meilleure réputation le 04/06/2024 dans Messages

  1. Il arrive qu'on parle ici ou là de "récursivité" ou de "fonctions récursives". Qu'en est il plus précisément ?... Comment ça se traduit en LISP ?... Je vais tenter de répondre à ces questions. Une fonction récursive est une fonction qui s'appelle elle même pendant son exécution. En LISP on reconnaît un fonction récursive à l'appel fait à elle même dans son DEFUN. L'exemple le plus souvent utilisé pour expliquer la récursivité est la fonction factorielle, petit rappel de math : Factorielle n s'écrit n! si n = 0 => n! = 1 et pour tout n > 0 => n! = n * (n - 1)! Par exemple : 4! = 4 * 3! = 4 * 3 * 2! = 4 * 3 * 2 * 1! = 4 * 3 * 2 * 1 = 24 En LISP, on peut écrire : (defun fact (n) (if (zerop n) 1 (* n (fact (1- n))) ) ) Une fonction définie récursivement contient au moins une condition d'arrêt : (zerop n) -> 1 et un appel récursif : (* n (fact (1- n))) Par exemple : (fact 4) sera interprété une première fois (* 4 (fact 3)), puis (* 4 (* 3 (fact 2))) etc,... jusqu'à (* 4 (* 3 (* 2 (* 1 (fact 0))))) où (fact 0) remplit la condition d'arrêt et retourne 1 On appelle "empilement" les appels successifs à la fonction jusquà la condition d'arrêt et "dépilement" leurs interprétations depuis cette condition. On peut voir la procédure dans la fenêtre de suivi de la console VisualLISP en "traçant" la fonction fact avec la fonction LISP trace : http://img155.imageshack.us/img155/4381/rcurs1ku8.png Du fait de l'utilisation de la pile, l'usage de fonctions récursives permet souvent de faire de manière plus élégante ce qui avec une boucle (while) aurait nécéssité l'utilisation d'une nouvelle variable pour stocker les résultats successifs. Par exemple la fonction fact définie de manière itérative, avec while : (defun fact (n / rslt) (cond (( (T (setq rslt n) (while ( (setq rslt (* rslt (setq n (1- n)))) ) ) ) ) L'usage de fonction récursives est aussi très pratique avec des listes. ;;; TRUNC Retourne la liste tronquée à partir de la première occurrence ;;; de l'expression (liste complémentaire de celle retournée par MEMBER) (defun trunc (expr lst) (cond ;; Conditions d'arrêt ((or (null lst) (equal (car lst) expr) ) nil ) ;; Appel récursif (T (cons (car lst) (trunc expr (cdr lst)))) ) ) http://img86.imageshack.us/img86/4333/rcurs2je6.png Pour comparaison, la fonction trunc définie de façon itérative : (defun trunc (elt lst / n rslt) (setq n 0) (while ;; Conditions d'arrêt (and ( (not (equal (nth n lst) elt)) ) (setq rslt (cons (nth n lst) rslt)) (setq n (1+ n)) ) ;; Résultat (reverse rslt) ) Les fonctions récursives ont aussi quelques inconvénients, la pile n'est pas infinie et ne permet qu'un certains nombre d'évaluations au-delà duquel la "limite de la pile interne atteinte" produit une erreur. D'après mes essais, cette limite semble être fixée à 19975 sur AutoCAD. On ne peut donc utiliser de fonction récursives sur des listes de plus de 19975 éléments. L'avantage de cet inconvénient est que si la condition d'arrêt n'est jamais remplie, on n'entre pas dans une boucle sans fin comme avec (while ...) On peut faire le test avec (fact -1) D'autre part, l'exécution des fonctions récursives semble plus lente que celle des fonctions itératives et ce d'autant plus que le nombre d'interprétations (hauteur de la pile) est important. Bien évidemment, tous les eventuels ajouts, remarques, corrections, questions sont les bienvenus. [Edité le 6/8/2006 par (gile)]
    1 point
  2. Bien vu ! Pour info soit tu utilises les noms de commandes / options de commandes en langue internationale, auquel cas il faut toujours utiliser un underscore, soit tu considères uniquement les commandes dans la langue locale (donc par exemple en français) et du coup, pas besoin de mettre d'underscore. Il est fortement conseillé d'utiliser les commandes internationales, pour éviter toute erreur potentielle (imaginons par exemple qu'un collègue français préfère utiliser un AutoCAD anglais) mais cela requiert d'être parfaitement au courant des options dans cette langue. Pour le nom des commandes tu peux utiliser la fonction (getcname) lorsque tu as un doute (mais pas dans un programme, c'est juste pour toi pour connaître l'orthographe exacte). Bisous, Luna
    1 point
  3. Coucou @YuGzeBuL et @didier, En effet, il faut toujours utiliser (cons) lorsqu'on a une variable (et donc (list) et non une (quote) / ' ) pour pouvoir justement interpréter la valeur d'une variable. Je remarque également ceci : (setq layerColor "114") ; Couleur 114 Donc ici layerColor est de type 'STR (string), donc une chaîne de caractères. Si maintenant tu fais un (entget) sur le calque "0" par exemple, tu as ceci : Explore-DXF in progress from "LAYER" (<Nom d'entité: 1f472e8c900>) : | (-1 . <Nom d'entité: 1f472e8c900>) | (0 . "LAYER") | (5 . "10") | (102 . "{ACAD_XDICTIONARY") | (360 . <Nom d'entité: 1f472e8d9e0>) | (102 . "}") | (330 . <Nom d'entité: 1f472e8c820>) | (100 . "AcDbSymbolTableRecord") | (100 . "AcDbLayerTableRecord") | (2 . "0") | (70 . 0) | (62 . 7) | (6 . "Continuous") | (290 . 1) | (370 . 0) | (390 . <Nom d'entité: 1f472e8c8f0>) | (347 . <Nom d'entité: 1f472e8ce00>) | (348 . <Nom d'entité: 0>) | End of exploration... Et plus particulièrement la ligne | (62 . 7) Que remarques-tu @YuGzeBuL ? (je vais répondre directement 🙂) Le code DXF 62 attend une valeur entière, comprise entre 0 et 254 (pour les calques uniquement) correspondant à la valeur ACI (AutoCAD Color Index). Cette valeur est donc de type 'INT (Integer), soit un nombre entier. A titre purement éducatif, si tu désires utiliser des couleurs RGB (et non ACI), alors il faudra définir ta couleur RGB à partir du code DXF 420 (qui requiert d'ailleurs une petite conversion, cf. les explications >>ici<<) tout en conservant le code DXF 62 le plus proche de ta couleur RGB (pour cela tu peux t'aider des fonctions développées par LeeMac pour faire toutes les conversions possibles des couleurs >>ici<<). Et s'il faut utiliser des couleurs d'un carnet de couleur, alors il faudra également ajouter le code DXF 430 (qui cette fois-ci n'est qu'une chaîne de caractères représentant le nom de la couleur) en plus des codes DXF 420 et 62 les plus proches de cette couleur. Bref, tout chat pour dire que le choix des couleurs peut être plus ou moins complexe selon le type de couleur souhaité 🙂 Dernière remarque vis-à-vis de ton code : (setq layerLineweight 50) '(370 . 50) ;; épaisseur de ligne 0.50 mm Pourquoi ne pas utiliser ta variable layerLineweight ici ? Car je trouve chat dommage de créer une variable que tu n'utilises pas...Du coup il faudrait juste remplacer ta ligne par : (cons 370 layerLineweight) ;; épaisseur de ligne Bisous, Luna
    1 point
  4. Bonjour @YuGzeBuL C'est que je dis souvent pour la formation, et du coup, je le répète : il faut que les bases soient parfaitement assimilées avant de relever le niveau du but à atteindre. Amicalement
    1 point
  5. Bonjour @YuGzeBuL Tout est question de syntaxe, ce qui suit une quote n'est pas interprété. Je pense que ceci fonctionnera : j'ai surligné les lignes à modifier, Amicalement
    1 point
  6. On dit aussi parfois : "Une fonction récursive est une fonction récursive."
    1 point
×
×
  • 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é