This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Reading in Integers to a list

17 posts · 3424 views

Simple question which sadly I cannot find an answer to. Basically Im finishing up my ternary tree Program (it was in another thread) but I Have the Insert/ and print functions done.
problem is is that I need to read in integers into a list before I run the insert/print function on them.

Anyways Before I was using an example list.
(defparameter *MYLIST*
(list 4 6 4 18 8 2 14 7 15 5 19 12 15 5 9 0 17 2 2 19))
But I need to make it where I read in the numbers, like ask the user for numbers until they hit N or something to stop. then put them into a list. and then run the insert/print function as I read in each value.

So it'd be something like this:
Read In value---> 5 (user inputs value)
Run Insert/then print on that
Read in value.....
Run Insert/print
Read In value
etc...

And go on until I stop inputting numbers.
(defun T-tree()
(let ((test nil))
(dolist (run *MYLIST*)
(insert test run)
(print (print-tree)))
Right now this Goes through the "example" list I have (named MYLIST) and goes through each Value and does it.
but I want it to do the insert function and print function as the values come in. So first it does it with 1 value.....then with 2 values......etc

I figured the test function should be the same. but I just have some kinda function that asks for another Integer for the list, and then adds it to it.
So something like this?
(defun T-tree()
(let ((test nil))
(askuser) #Ask for Next integer to be put into *MYLIST*
(dolist (run *MYLIST*)
(insert test run)
(print (print-tree)))
Ideas? Criticism? Comments?

thanks a bunch

Re: Reading in Integers to a list

Here's a sample input loop.
(do (value)
    (nil)
  (setf value (read-from-string (read-line) nil nil))
  (unless value (return))
  (format t "You entered ~A~%" value))

Re: Reading in Integers to a list

Note that the *standard-input* stream is defaultly the user input. You can make any character stream get input from that.

You could enter the collector made by nconcing into the following:
(defun callback-read (from callback &key (stop (gensym)))
  "Reading, where each expression is put into a callback."
  (typecase from
    (string
     (with-open-file (stream from) (list-read stream :stop stop)))
    (stream
     (do ((read (read from nil stop) (read from nil stop)))
         ((eql read stop) (values))
       (funcall callback read)))))
And then input the stream *standard-input*.

Re: Reading in Integers to a list

I believe that the simplest and prettiest function that asks for values is this:
(defun prompt (string)
  (format t "~A: " string)
  (read))
cl-user> (prompt "Enter an integer")
Enter an integer: 2
2
A more elaborate version:
(defun prompt (string &key (output *standard-output*) (input *standard-input*))
  (format output "~A: " string)
  (read input))

Re: Reading in Integers to a list

Well Is there any way to read these into a list? (like add them)

say User enters 5
the list is [5]
I do my functions/insert/etc
Next the user enters 7
the list is now [5 7]
do functions/insert etc/

and so on..

Re: Reading in Integers to a list

You mean like this?
cl-user> (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
              until (eq value 'end)
              collect value)
Please enter an integer or "end" to finish:: 1
Please enter an integer or "end" to finish:: 2
Please enter an integer or "end" to finish:: 3
Please enter an integer or "end" to finish:: 4
Please enter an integer or "end" to finish:: 5
Please enter an integer or "end" to finish:: 6
Please enter an integer or "end" to finish:: end
(1 2 3 4 5 6)

Re: Reading in Integers to a list

gugamilare wrote:You mean like this?
cl-user> (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
              until (eq value 'end)
              collect value)
Please enter an integer or "end" to finish:: 1
Please enter an integer or "end" to finish:: 2
Please enter an integer or "end" to finish:: 3
Please enter an integer or "end" to finish:: 4
Please enter an integer or "end" to finish:: 5
Please enter an integer or "end" to finish:: 6
Please enter an integer or "end" to finish:: end
(1 2 3 4 5 6)
\

Yes something like that.
But what variable is the list? is it collect? or wut.
(like if I wanted to use the list in the "dolist" function)

Re: Reading in Integers to a list

Mercfh wrote:Yes something like that.
But what variable is the list? is it collect? or wut.
(like if I wanted to use the list in the "dolist" function)
The variable containing the list is hidden, its value is returned when the loop finishes. To use the list, you need to save it into a variables afterwards, e.g.:
(let ((list (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
                  until (eq value 'end)
                  collect value)))
  (format t "This is the list constructed: ~A~%" list)
  (format t "These are its elements:")
  (dolist (element list)
    (format t "~A" element))
  (format t "~%"))
Try evaluating that code.

Re: Reading in Integers to a list

Ok So it's saved into the variable list "element" there im assuming? or is the list variable actually called list (sorry this is my first time with lisp lol.....can u tell haha)?


Either way could I make this into a function that I could use in my function loop?

Re: Reading in Integers to a list

Mercfh wrote:Ok So it's saved into the variable list "element" there im assuming? or is the list variable actually called list (sorry this is my first time with lisp lol.....can u tell haha)?
The list is actually called list. The variable element runs through the elements of the list, printing each one at a time.

The loop
(loop for value = (prompt "Please enter an integer or \"end\" to finish:")
   until (eq value 'end)
   collect value)
will read your inputs and create a list. The list is then returned, and it will be lost unless you save it somewhere. let is what you use to create new variables. In this case, we created a variable named list and saved the result of the last form into it:
(let ((list     ;; <- this is the variable created, its value will be the next form
       (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
          until (eq value 'end)
          collect value)))
  ...)
dolist is used to iterate through the elements of the list, in this case we used it to print all the elements, one at a time.
Mercfh wrote:Either way could I make this into a function that I could use in my function loop?
This is easy, just define a function and put the loop above (the first code box in this post) inside.

Re: Reading in Integers to a list

Ok so it'd be something like
defun readin()
(let ((list     ;; <- this is the variable created, its value will be the next form
       (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
          until (eq value 'end)
          collect value)))
))
Btw thanks a ton. u've been a HUGE help

and then I can do something like
(defun testing ()
(let ((test nil))
(readin())
(dolist (el *list*)
(insertf test el)
(print (frob-tree test)))
So it reads them all into a list first?

Re: Reading in Integers to a list

Mercfh wrote:Ok so it'd be something like
defun readin()
(let ((list     ;; <- this is the variable created, its value will be the next form
       (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
          until (eq value 'end)
          collect value)))
))
Btw thanks a ton. u've been a HUGE help

and then I can do something like
(defun testing ()
(let ((test nil))
(readin())
(dolist (el *list*)
(insertf test el)
(print (frob-tree test)))
So it reads them all into a list first?
No. let will declare a local variable, and the extent of that local variable finishes where the let finishes. In your example, the variable list will only exist inside the function readin.

What you were supposed to do is this:
(defun readin ()
  (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
     until (eq value 'end)
     collect value))
Then you create a variable in the function that calls this function:
(defun your-function ()
  (let ((list (readin)))
    (dolist (element list)
      (do-something-with element))))

Re: Reading in Integers to a list

Ah Ok i think I understand.

Although our Professor emailed us because people were asking.

APPARENTLY i was just supposed to read in all the values into a list and then do the other functions. instead of what I initially thought (reading in an integer 1 by 1, then performing the task on it....1 by 1)

Although I think I understand now. I can just read them all into a list. but is there any way to kinda store the list as a "global variable"?
since before I had this as an example list
(defparameter *example-list*
(list 4 6 4 18 8 2 14 7 15 5 19 12 15 5 9 0 17 2 2 19))
then I did this number on it
(defun testing ()
(let ((test nil))
(dolist (ms *example-list*)
(insertf test ms)
(print (print-tree test)))
Or is the list you made using ur code already a global variable? so i can just replace *example-list* with it.
IM sorry for being such a newb with these things, but this is a basically learn on my own kinda thing sadly. (our teacher has been ill for the past 2 weeks, sadly no extension on our hw tho)

EITHER WAY, using ur code I get this error:
*** - EVAL: undefined function Ttree::PROMPT
ttree is the name of my package.

Re: Reading in Integers to a list

Re the global variable: Just (setf *example-list* new-value) -- though why not pass the list as a parameter?

Re the undefined function: Did you copy his prompt function into your package and compile it first?

Re: Reading in Integers to a list

nuntius wrote:Re the global variable: Just (setf *example-list* new-value) -- though why not pass the list as a parameter?

Re the undefined function: Did you copy his prompt function into your package and compile it first?
Ya I put it in my package and ran (load "CS.lisp")
and it said *** - EVAL: undefined function PROMPT

I even just made it's OWN file like this
(defpackage :test2
    (:use :common-lisp))


(let ((list (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
                  until (eq value 'end)
                  collect value)))
  (format t "This is the list constructed: ~A~%" list)
  (format t "These are its elements:")
  (dolist (element list)
    (format t "~A" element))
  (format t "~%"))
and I still got that problem.


And I understand what you mean by the global variable. but I need a way to read the list INTO that global variable.
like:
Read data into list called *mylist*
then I can use that global variable on the other functions (which already work)
because here is my function that works perfectly (for my ternary tree)
(defun testing()
  (let ((test nil))
    (dolist (hi *mylist*)
      (insertf test hi)
      (print (list-tree test)))))
im just using this right now as an example list
(defparameter *example-list*
(list 4 6 4 18 8 2 14 7 15 5 19 12 15 5 9 0 17 2 2 19))

I need a way to read in numbers INTO that *example-list* or another global variable like it. if that makes sense? or if thats even possible

Re: Reading in Integers to a list

Mercfh wrote:
nuntius wrote:Re the global variable: Just (setf *example-list* new-value) -- though why not pass the list as a parameter?

Re the undefined function: Did you copy his prompt function into your package and compile it first?
Ya I put it in my package and ran (load "CS.lisp")
and it said *** - EVAL: undefined function PROMPT

I even just made it's OWN file like this
(defpackage :test2
    (:use :common-lisp))


(let ((list (loop for value = (prompt "Please enter an integer or \"end\" to finish:")
                  until (eq value 'end)
                  collect value)))
  (format t "This is the list constructed: ~A~%" list)
  (format t "These are its elements:")
  (dolist (element list)
    (format t "~A" element))
  (format t "~%"))
and I still got that problem.
You forgot to copy the function prompt in my early posts.
Mercfh wrote:[...]

I need a way to read in numbers INTO that *example-list* or another global variable like it. if that makes sense? or if thats even possible
That is what he explained to you.

Se also viewtopic.php?f=2&t=683&p=4263#p4263

Re: Reading in Integers to a list

Don't forget (in-package the-package) then after that the things you declare in that file are actually in said page.