Page 1 of 3
Reading In text file.
Posted: Tue Apr 06, 2010 10:04 pm
by Mercenary85
Hi All im new to the site. Having a bit of a problem, im pretty new to lisp but I've been trying to learn it just as something to experiment with for fun
Anyways Im trying to figure out how to read in data and store it as kinda a global parameter.
Like for instance (dunno if I can do this)
So that would define a blank list
and then I would read data from "mydata.txt"
which contains various numbers.
I found something on google, but it didnt actually store the data in anything. I'd prefer to store it in a list.....but everything i've found doesn't keep it in a variable.
then I can do stuff with *imalist* but now after I read in the data *imalist* would be a list with a bunch of numbers in it. Then Im gonna do some math calculations on the list (but thats for another day) the main problem I have right now is Storing them into a list (because I have the function done that calculates the average of the *imalist* right now)
Appreciate everyones help
Re: Reading In text file.
Posted: Wed Apr 07, 2010 5:09 am
by gugamilare
To change the value of a variable, use
setf. Like this:
Code: Select all
(defun read-integers-from-file (file)
;; reads file and returns a list with the integers inside it
...)
(defparameter *imalist* (list))
(setf *imalist* (read-integers-from-file "/path/to/mydata.txt"))
Re: Reading In text file.
Posted: Wed Apr 07, 2010 6:26 am
by Jasper
Or a little more advanced, you can use LET on special variables:
Code: Select all
;;Defvar or defparameter *imalist* somewhere before
(let ((*imalist* (read-integers-from-file "/path/to/mydata.txt")))
(function-depending-on-imalist)) ;Depends on the one as set
(function-depending-on-imalist) ;Doesn't depend on as set, outside that LET
It kindah sneaks in the special variable as argument where-ever it is needed.(So it is useful when you find yourself entering an argument unchanged all the time.) I am starting to like that feature as much as macros

.
Re: Reading In text file.
Posted: Wed Apr 07, 2010 10:14 am
by Mercenary85
gugamilare wrote:To change the value of a variable, use
setf. Like this:
Code: Select all
(defun read-integers-from-file (file)
;; reads file and returns a list with the integers inside it
...)
(defparameter *imalist* (list))
(setf *imalist* (read-integers-from-file "/path/to/mydata.txt"))
Oh ok that makes sense.
in the read-integers-from-file. what would I need to do to make sure it "stays" a global parameter
would something like THIS work
Code: Select all
(let ((in (open "data.txt" :if-does-not-exist nil)))
(when in
(loop for line = (read-line in nil)
while line do (format t "~a~%" line))
(close in)))
then have
Code: Select all
(defparameter *imalist* (list))
(setf *imalist* (read-integers-from-file "/path/to/mydata.txt")
like after that?
remember im new

Re: Reading In text file.
Posted: Wed Apr 07, 2010 10:52 am
by gugamilare
Sorry, I didn't quite understand what you are trying to do. If you declare
then
*imalist* will still be a global variable no matter how many times you change its value using
setf or
let (like in Jasper's example). Or maybe what you want is not to change its value? In this case all you need to do is not to use
setf and always use non-destructive functions when operating with your variable.
To know if a function is destructive, look at its documentation. For example, comparing delete and remove:
Code: Select all
cl-user> (documentation 'delete 'function)
"Return a sequence formed by destructively removing the specified ITEM from
the given SEQUENCE."
cl-user> (documentation 'remove 'function)
"Return a copy of SEQUENCE with elements satisfying the test (default is
EQL) with ITEM removed."
they do the same thing, but delete is destructive while remove is not.
Re: Reading In text file.
Posted: Wed Apr 07, 2010 12:05 pm
by Mercenary85
Ok basically here is what Im trying to do.
I have a global parameter *mylist* that defines a list (like 1 3 5 6 3 1) etc...
Right now Im just using that as an example.
What I want to do is read in a text file (which consists of JUST integers) into the global parameter *mylist*. thats all I need to do.
So after the readin function, *mylist* will contain the numbers from the text file (if that makes sense)
the text file just has a bunch of integers in it
This code u listed above i think would work. except I dont know what goes in the "..." part. because this is my first time with lisp
Code: Select all
(defun read-integers-from-file (file)
;; reads file and returns a list with the integers inside it
...)
(defparameter *imalist* (list))
(setf *imalist* (read-integers-from-file "/path/to/mydata.txt"))
Re: Reading In text file.
Posted: Wed Apr 07, 2010 12:46 pm
by gugamilare
Mercenary85 wrote:Ok basically here is what Im trying to do.
I have a global parameter *mylist* that defines a list (like 1 3 5 6 3 1) etc...
Right now Im just using that as an example.
What I want to do is read in a text file (which consists of JUST integers) into the global parameter *mylist*. thats all I need to do.
So after the readin function, *mylist* will contain the numbers from the text file (if that makes sense)
the text file just has a bunch of integers in it
Ok, so you are asking if
*mylist* will
"forget" its previous value and contain a list with only the numbers from the text file? Yes, that is what the code will do.
Mercenary85 wrote:This code u listed above i think would work. except I dont know what goes in the "..." part. because this is my first time with lisp
It seems you have a text file? You need the macro
with-open-file and the function
read. An example how it is supposed to do. If "data.txt" contains
Then
Code: Select all
cl-user> (with-open-file (data "/home/gugamilare/data.txt")
(format t "The first integer is ~A~%" (read data nil :eof))
(format t "The second integer is ~A~%" (read data nil :eof))
(format t "The third integer is ~A~%" (read data nil :eof))
(format t "No more numbers in the file!~%The value returned by (read data nil :eof) is ~S~%"
(read data nil :eof)))
The first integer is 23
The second integer is 42
The third integer is 25
No more numbers in the file!
The value returned by (read data nil :eof) is :eof
nil
This is just an example, you will need to put this in a loop.
Re: Reading In text file.
Posted: Wed Apr 07, 2010 12:55 pm
by Jasper
Mercenary85 wrote:except I dont know what goes in the "..." part. because this is my first time with lisp
In the vein of teaching to fish rather than giving fish: try use WITH-OPEN-FILE to open a file (could also just OPEN and CLOSE yourself) with READ, check they're numbers with NUMBERP then you could collect that into a list with LOOP
like here, but with (prompt ..) replaced.
Re: Reading In text file.
Posted: Wed Apr 07, 2010 1:26 pm
by Mercenary85
I understand the readin part. but I still dont see how that puts it into the global variable *mylist*?
Like if I define *mylist* as a parameter list thats blank.
then I read in the numbers from data.txt
and data.txt contains (5 6 7 1 5 12 6 7)
then after I readin. I want *mylist* (the global variable) to contain (5 6 7 1 5 12 6 7) and
never lose those values (until i decide to change them)
would something like this work
Code: Select all
(defun read-setup (thefile)
(with-open-file (stream thefile)
(loop for line = (read stream nil 'end)
until (eq line 'end)
do (print (list (coerce line 'integer) ;want to make single list
)
)
)
)
)
then have this?
Code: Select all
(defparameter *imalist* (list))
(setf *imalist* (read-integers-from-file "/path/to/mydata.txt"))
would that store the integers into the global variable list *imalist*
Re: Reading In text file.
Posted: Wed Apr 07, 2010 2:31 pm
by nuntius
Yes. (setf x y) stores y into the place currently known as x.