Universal read_data function



On May 27, Volker van Nek wrote:
---------------------------------------
If you want to read general Maxima expressions
 containing blanks and commas it makes sense
 to me to use the default ";" or "$" as separators. 

E.g.

(%i1) string: "(x:1,y:2,x+y); block([fpprec:24],bfloat(%pi)); foo;"$

(%i2) strings: split(string,";");
(%o2)       [(x:1,y:2,x+y),  block([fpprec:24],bfloat(%pi)),  foo]

(%i3) map(parse_string, strings);
(%o3)   [(x : 1, y : 2, y + x), block([fpprec : 24], bfloat(%pi)), foo]

(%i4) ''%;
(%o4)                [3, 3.14159265358979323846264b0, foo]
----------------------------------------------------------
Thanks for the great suggestion.
Having a read_data function which allows the
user to pass on to split any desired data
separator string makes a lot of sense.

My new (and improved?) version of read_data
has the syntax:

 read_data (filename, data-sep-string, mult).

Using the minimal form:  read_data(filename) 
assumes an arbitrary mixture of commas
and space data separators, convenient for
many applications, but will not allow
string data items containing spaces, since
the default simple version converts all
commas to spaces.

Using read_data (filename, ",")
  or read_data (filename, ";")
assumes all data items are using the
same data separators as indicated.

The code sets the third optional
arg to true , but can be set to false
for use by split.

---------------------------------
Maxima 5.24.0 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.8 (a.k.a. GCL)
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
                                  2011-05-28


(%i1) (display2d:false,fpprintprec:8)$
(%i2) load(readwrite);
(%o2) "c:/work2/readwrite.mac"

(%i3) printfile ("ndata1.dat")$
2.3e9 "Abc"

(%i4) read_data ("ndata1.dat");
(%o4) [[2.3E+9,"Abc"]]
(%i5) read_data ("ndata1.dat"," ");
(%o5) [[2.3E+9,"Abc"]]

(%i6) printfile ("ndata2.dat")$
2 , 4.8, -3/4, "xyz", -2.8e-9

3 22.2  7/8 "abc" 4.4e10

(%i7) read_data ("ndata2.dat");
(%o7) [[2,4.8,-3/4,"xyz",-2.8E-9],[3,22.2,7/8,"abc",4.4E+10]]

(%i8) printfile ("ndata3.dat")$
2.0; -3/7; (x:1,y:2,x+y); block([fpprec:24],bfloat(%pi)); foo

(%i9) read_data ("ndata3.dat",";");
(%o9) [[2.0,-3/7,(x:1,y:2,y+x),block([fpprec:24],bfloat(%pi)),foo]]
(%i10) ev(%);
(%o10) [[2.0,-3/7,3,3.1415926b0,foo]]

(%i11) printfile ("ndata4.dat")$
2.0; -3/7; (x:1,y:2,x+y); block([fpprec:24],bfloat(%pi)); "my error"

(%i12) read_data ("ndata4.dat",";");
(%o12) [[2.0,-3/7,(x:1,y:2,y+x),block([fpprec:24],bfloat(%pi)),"my error"]]
(%i13) ev(%);
(%o13) [[2.0,-3/7,3,3.1415926b0,"my error"]]

(%i14) printfile ("ndata5.dat")$
1 0

2 -1/3

3 -1/2

4 -3/5

5 -2/3
(%i15) read_data ("ndata5.dat");
(%o15) [[1,0], [2,-1/3], [3,-1/2], [4,-3/5], [5,-2/3]]

(%i16) printfile ("ndata6.dat")$
1, 2/3, 3.4, 2.3e9, "file ndata6.dat"

"line two" , -3/4 , 6 , -4.8e-7 , 5.5

7/13, "hi there", 8, 3.3e4, -7.3

4,-3/9,"Jkl", 44.6, 9.9e-6

(%i17) read_data("ndata6.dat",",");
(%o17) [[1,2/3,3.4,2.3E+9,"file ndata6.dat"],
                ["line two",-3/4,6,-4.8E-7,5.5],
                [7/13,"hi there",8,33000.0,-7.3],
                [4,-1/3,"Jkl",44.6,9.9E-6]]
        
(%i18) fundef (read_data);

(%o18) read_data ([%v]) := 
                  block ([%s,%r,%l,%filename,%dsep,%mult:true,
                               %mix:false],
                 %filename:part(%v,1),
                 if not stringp(%filename)
                     then (disp(" file name must be a Maxima string "),
                           return(false)),
                 if not file_search(%filename)
                     then (disp(" file not found "),return(false)),

                 if length(%v) = 1 then %mix:true
                     else (if length(%v) = 2 then %dsep:part(%v,2)
                               else (%dsep:part(%v,2),%mult:part(%v,3))),

                 %s:openr(%filename),%r:[],
                 while (%l:readline(%s)) # false do
                       if %mix
                           then %r:cons(
                                   map(parse_string,
                                       split(ssubst(" ",",",%l))),%r)
                           else %r:cons(
                                   map(parse_string,split(%l,%dsep,%mult)),
                                   %r),
                 close(%s),reverse(%r))
                                 
-------------------------------------------------

Ted Woollett