I wrote some code for reading lists, matrices, and arrays from a file.
Here's a demonstration with some questions along the way.
(C1) load("l:/maxima-io/io.lisp")$
(C2) fn : "l:/maxima-io/fp.data";
(D2) l:/maxima-io/fp.data
The function read_list reads all objects in a file and places them in a
Maxima list. Objects must be separated with whitespace; linefeeds are
ignored. My file fp.data is
0 1 2
3 4 5
6 7 8
The numbers could be floats.
(C3) read_list(fn);
(D3) [0, 1, 2, 3, 4, 5, 6, 7, 8]
read_list doesn't close the file--reading from fn again gives an empty
list
(C4) read_list(fn);
(D4) []
Question 1: Is this behavior what folks would like? Or should the file
be closed after reading?
We can reset the file position to the start using
(C5) reset_file_position(fn)$
(C6) read_list(fn);
(D6) [0, 1, 2, 3, 4, 5, 6, 7, 8]
(C7) reset_file_position(fn)$
To read objects starting with the first and continue reading until either
5 have been read or we run out of data, use the optional arguments
(C8) read_list(fn,1,5);
(D8) [0, 1, 2, 3, 4]
(C9) read_list(fn,1,5);
(D9) [5, 6, 7, 8]
(C10) read_list(fn,1,5);
(D10) []
(C11) reset_file_position(fn)$
With one argument, read_matrix forms a matrix from each line of the file.
My file fn has three lines; thus
(C12) read_matrix(fn);
[ 0 1 2 ]
[ ]
(D12) [ 3 4 5 ]
[ ]
[ 6 7 8 ]
(C13) reset_file_position(fn)$
To read the first 2 lines, use an optional first argument
(C14) read_matrix(fn,2);
[ 0 1 2 ]
(D14) [ ]
[ 3 4 5 ]
(C15) reset_file_position(fn)$
With two optional arguments, ignore line feeds and read the objects into
the matrix linearly
(C16) read_matrix(fn,2,2);
[ 0 1 ]
(D16) [ ]
[ 2 3 ]
(C17) reset_file_position(fn)$
Finally, we can read data into an array.
(C18) array(a,2,2)$
(C19) read_array(fn,a);
(D19) a
(C20) listarray(a);
(D20) [0, 1, 2, 3, 4, 5, 6, 7, 8]
If there isn't enough data left, we get an error
(C21) read_array(fn,a);
Not enough data left in "l:/maxima-io/fp.data" to fill the array. File
position was not changed
-- an error. Quitting. To debug this try DEBUGMODE(TRUE);)
To list all open files and closed files, use
(C22) list_open_files();
(D22) [l:/maxima-io/fp.data]
(C23) close_all_files();
Closing file l:/maxima-io/fp.data
(D23) FALSE
(C24)
(Open files are stored in a hash table; closing them removes them
from the hash table and closes the file).
Question 2: Should these functions check that all objects are numbers? If
so what should happen to the file position when we read a non-number?
Currently, a data file can contain anything that lisp:read can read.
Question 3: Should read_matrix check that all its rows are the same
length? Currently, it's up to matrix, not read_matrix, to signal the
error. If read_matrix signals the error, what should happen to the
file position?
io.lisp is about 156 lines long; I'll send it to anybody with an
interest in developing a non-experimental version. I'll
appreciate all comments.
Barton