2010-04-18 40 views
1

Je deviens fou avec un petit problème ici, Je continue à obtenir une erreur et je ne peux pas sembler comprendre pourquoi, le code est censé changer la plage d'une liste, si nous lui donnons une liste des valeurs (1 2 3 4) et nous voulons changer la gamme de 11 à quatorze ans le résultat serait (11 12 13 14) le problème est que la dernière fonction appelée scale-list redonnera une erreur en disant:une question sur le lisp commun

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)

quelqu'un a une idée pourquoi? J'utilise Aquamacs comme un éditeur merci à l'avance

;;finds minimum in a list 
(defun minimum (list) 
    (car (sort list #'<))) 

;;finds maximum in a list 
(defun maximum (list) 
    (car (sort list #'>))) 

;;calculates the range of a list 
(defun range (list) 
    (- (maximum list) (minimum list))) 

;;scales one value to another range 
(defun scale-value (list low high n) 
    (+ (/ (* (- (nth (- n 1) list) 
       (minimum list)) 
      (- high low)) 
     (range list)) 
     low)) 


;;is supposed to scale the whole list to another range 
(defun scale-list (list low high n) 
    (unless (= n 0) 
    (cons (scale-value list low high n) 
     (scale-list list low high (- n 1))))) 

(scale-list '(1 2 3 4) 21 24 4) 
+1

Qu'est-ce que votre _editor_ a à faire avec la question? – Svante

+0

peut-être qu'il pensait que l'éditeur est un lisp! –

+0

aucun homme ... mais puisque je ne sais pas vraiment ... Je pensais que peut-être l'éditeur prend en charge un mode nativement ... de toute façon je viens de m'impliquer dans le lisp commun pour aider un ami dans sa tâche et je ne me sens pas comme Je dois tout savoir sur la langue depuis le jour 0 ... alors c'est facile – rabidmachine9

Répondre

4

Les définitions du maximum et du minimum doivent être améliorées. TRIER est destructeur. Il est également faux d'appeler SORT avec une constante littérale comme '(1 2 3 4) - encore une fois, TRIER est destructeur.

meilleures définitions:

(defun minimum (list) 
    (reduce #'min list)) 

(defun maximum (list) 
    (reduce #'max list)) 

Une définition plus efficace de la gamme:

(defun range (list) 
    (loop for e in list 
     maximize e into max 
     minimize e into min 
     finally (return (- max min)))) 

SCALE-LIST et SCALE-valeur sont pas non plus Lisp. Si vous appelez NTH comme ceci dans une fonction récursive, alors quelque chose ne va pas. Vous devriez recurse sur la liste, pas l'index. SCALE-VALUE appelle RANGE et MINIMUM pour chaque appel. Pourquoi?

Vérifiez cette variante:

;;scales one value to another range 
(defun scale-value (item low high min range) 
    (+ (/ (* (- item min) 
      (- high low)) 
     range) 
     low)) 

;;is supposed to scale the whole list to another range 
(defun scale-list (list low high) 
    (let ((min (minimum list)) 
     (range (range list))) 
    (labels ((scale-list-aux (list) 
       (when list 
       (cons (scale-value (first list) low high min range) 
         (scale-list-aux (rest list)))))) 
     (scale-list-aux list)))) 

(scale-list '(1 2 3 4) 21 24) 

Que pouvez-vous améliorer plus? Par exemple je voudrais me débarrasser de la récursivité et le remplacer par MAPCAR.

+0

Cette réponse est comme un rêve devenu réalité ... merci beaucoup, je voudrais juste mentionner qu'un de mes amis vérifié mes fonctions sur LispWorks et ils ont travaillé, mais ils ne fonctionneraient pas sur mes ordinateurs sur Aquamacs ... Cela me semble vraiment étrange Mais de toute façon votre mise en œuvre est bien mieux et fonctionne sur les deux, merci beaucoup! – rabidmachine9

+0

@ rabidmachine9: Aquamacs est votre éditeur, mais quel Lisp utilisez-vous? –

+0

J'utilise Slime – rabidmachine9

0

je re poster le code parce que quelque chose a mal tourné ...

;;finds minimum in a list 
(defun minimum(list) 
    (car (sort list #'<))) 
;;finds maximum in a list 
(defun maximum(list) 
    (car (sort list #'>))) 
;;calculates the range of a list 
(defun range(list) 
    (- (maximum list) (minimum list))) 

;;scales one value to another range 
(defun scale-value(list low high n) 
    (+ (/ (* (- (nth (- n 1) list) (minimum list)) (- high low)) (range list)) low)) 


;;is supposed to scale the whole list to another range 
(defun scale-list(list low high n) 
    (unless (= n 0) 
    (cons (scale-value list low high n) (scale-list list low high (- n 1))))) 

(scale-list '(1 2 3 4) 21 24 4) 
+1

Pourquoi ne pas simplement éditer le message, au lieu de faire une "réponse"? –

0

Votre trace de la pile réelle est quelque chose comme:

-(nil 0.1) 
    (* (- (nth ... list) (minimum list)) (- high low)) 
    (/ (* (- ... ...) (- high low)) (range list)) 
    (+ (/ (* ... ...) (range list)) low) 
    scale-value((0.1) 20 30 3) 

Je suppose que vous déterminez un nième mauvais élément et cela renvoie zéro, ce qui désorganise la soustraction.

+0

merci ... cette fonction peut renvoyer jusqu'à une valeur si je donne les bons arguments pour demander juste une valeur qu'elle peut lui rendre ... le problème semble apparaître lorsqu'une seconde valeur est essayée par contre avec la première un ... mais oui ... cette erreur semble être sur n, n'a toujours aucun sens pour moi – rabidmachine9

+0

Dans la deuxième invocation de l'échelle-liste avec n-1 nième retour nul. Je suppose que c'est tout simplement hors de portée - exécuter un programme via un débogueur sur l'ajout de quelques instructions d'impression pour surveiller vos valeurs devrait vous aider à pointer la cause exacte du problème. –