views:

254

answers:

3

Hello people, I'm getting crazy with a small problem here, I keep getting an error and I cant seem to figure out why, the code is supposed to change the range of a list, so if we give it a list with values (1 2 3 4) and we want to change the range in 11 to fourteen the result would be (11 12 13 14) the problem is that the last function called scale-list will give back an error saying:

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

anybody has a clue why? I use aquamacs as an editor thanks in advance

;;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)
A: 

I re post the code because something went wrong...

;;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)
rabidmachine9
Why not just edit the post, instead of making an "answer"?
Frank Shearar
A: 

Your actual stack trace is something like:

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

I guess you determine a wrong nth element and this returns nil, which messes up the subtraction.

Bozhidar Batsov
thanks...this function can return up to one valueif I give the right arguments to ask just one value it can give it back...the problem seems to appear when a second value is tried to cons with the first one...but yes... this error appears to be about n, still makes no sense to me
rabidmachine9
In second invocation of scale-list witn n-1 nth return nil. I guess it's simply out of range - running program through a debugger on adding some print statements to monitor your values should help you pip-point the exact cause of the problem.
Bozhidar Batsov
+3  A: 

The definitions of maximum and minimum need to be improved. SORT is destructive. It is also wrong to call SORT with a literal constant like '(1 2 3 4) - again, SORT is destructive.

Better definitions:

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

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

A more efficient definition of range:

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

SCALE-LIST and SCALE-VALUE are also not Lisp-like. If you call NTH like this in a recursive function then something is wrong. You should recurse over the list, not the index. SCALE-VALUE calls RANGE and MINIMUM for each call. Why?

Check this variant:

;;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)

What can you improve more? For example I would get rid of the recursion and replace it with MAPCAR.

Rainer Joswig
This answer is like a dream coming true...thanks a lot, I would only like to mention that a friend of mine checked my functions on LispWorks and they worked, but they wouldnt work on my computers on Aquamacs...This sounds really strange to meBut anyway your implementation is way better and runs on both, thanks a lot!
rabidmachine9
@rabidmachine9 : Aquamacs is your editor, but what Lisp are you using?
Rainer Joswig
I am using Slime
rabidmachine9
Slime is just a lisp interaction mode - are you using sbcl or some other implementation of Common Lisp?
Bozhidar Batsov
actually not...I installed aquamacs and then slime, but nothing more...Is there something else needed?
rabidmachine9
@rabidmachine9 : we are asking you what car you are driving and you are telling us that you are using a steering wheel. SLIME is development environment and has two parts: one that hooks into Emacs and another one the runs in some Common Lisp. SLIME controls the communication between a Common Lisp implementation and Emacs. So, which Common Lisp implementation are you using with SLIME?
Rainer Joswig
as you probably have already figured out...I don't knowso the question is, is there a script I can run in order to learn?
rabidmachine9