On 05/28/2011 01:31 PM, Edwin Woollett wrote:
> 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
>
> _______________________________________________
> Maxima mailing list
> Maxima at math.utexas.edu
> http://www.math.utexas.edu/mailman/listinfo/maxima
>
Hi Ted:
I tried your latest Universal read_data function on the same file I used
with the one I last presented and it chokes no matter what separator I
use. This is what I think your function is (in case I copied it
incorrectly):
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)
);
My data file (with embedded CRs, LFs, and spaces, which probably don't
show up in this message, but I can attach it if necessary):
2.3e9 "Abc"
10.3
14.4
read_data1(%filename):=block([%s,%r],if notfile_search(%filename) then
(disp(" file not found "),return(false))
,%s:openr(%filename),%r:[],while (l:readline(%s))#false do
%r:cons(map(parse_string,split(l)),%r),reverse(%r))
12.6
14.5
If I use a space separator I get:
stdin:2:incorrect syntax: Premature termination of input at $.
If I use a "," or ";" separator I get:
stdin:11:incorrect syntax: Abc is not an infix operator
Maybe I'm making the data file more complex than it should be, but if
you're calling it a universal read data function, It should be bullet proof.
Paul