0

I am writing test-cases for a problem,I want to check my test-cases with Mathematica but I am facing some problems with file input/output.

I have to take Input from a file say "Test.in",the date consists of an Integer/String in each line and the input is terminated by EOF,I have to take the input (every line,one at a time) and in each step I have to process the input and output to a file say "output.out".How can we do this in Mathematica?

PS:I am using Mathematica 7.0

ADDED:

A sample of Test.in would be like this.

Quixotic
  • 2,424
  • 7
  • 36
  • 58

4 Answers4

4

You asked to read (every line,one at a time). Well, that is surely not the Mathematica way of doing things, but as you asked for it, try something along the lines of:

strInp = OpenRead  ["Test.in"];
strOut = OpenWrite ["Test.out"];

While[(str=Read[strInp, Number) != EndOfFile,

     out = yourprocess[str];

     Write [strOut,out];
];

Close [strOut];
Close [strInp];

(* Now show the output file *)
FilePrint ["Test.out]

Edit Other answers posted better and more Mathematica-ish ways of doing this, but that generally implies NOT reading one at a time, as Mathematica favors functional, list-wide programming rather than the iterative way.

Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • Single nit: you do not clean up if you `Abort`. You need to wrap it in `CheckAbort`, otherwise there is a chance the file will remain open. – rcollyer Mar 14 '11 at 03:21
  • 1
    @rcollyer I always try to fly away from this kind of processing in Mma. The file management is just not robust enough. I saw corrupt files and checkpoint management is very difficult to implement. I guess the better path is not to make this approach robust, but to switch to the most natural one (all file in one glup). – Dr. belisarius Mar 14 '11 at 03:29
  • sometimes you can't, so I have a utility function (http://stackoverflow.com/questions/4174791/preventing-avalanche-of-runtime-errors-in-mathematica/4176381#4176381) that wraps the file processing with `CheckAbort` for me, called either Execute Around Code or RAII pattern. Saves my bacon. I usually don't do writes, but I've got the code generalized that it can do either. Although, with the writes there is no guarantee as to the state of the file if I abort midstream, so to speak. – rcollyer Mar 14 '11 at 04:46
2

It's rather clunky to read each value one at a time, but it's natural in M- to read them all at once and then process each one.

Here's a simple infrastructure I use all the time:

(* step one: get data *)
data = Import["ideone_fM0rs.txt", "Lines"];

(* step two: ??? *)
res = {};
Module[{value, result},
  value = #;
  result = yourCodeHere[value];
  AppendTo[res, result];
]& /@ data;

(* step three: PROFIT! *)
Export["out.txt", res, "Lines"];

but see Jon McLoone on AppendTo vs Sow/Reap for large data sets: http://blog.wolfram.com/2011/12/07/10-tips-for-writing-fast-mathematica-code.

Here's a variation with Sow/Reap for the times you'd like to collect values under various tags or categories or genuses or whatever:

data = Import["ideone_fM0rs.txt", "Lines"];

res = Reap[Module[{value, result, tag},
  value = #;
  result = yourCodeHere[value];
  tag = generateTag[value]
  Sow[result, tag];
]& /@ data, _, Rule][[2]];

Export["out.txt", res, "Lines"];

It's tempting to roll all that up into a single awe-inspiring one-liner, but for maintainability I like to keep it unrolled with each step made explicit.

Of course, yourCodeHere[value] could instead be many lines of well-commented code.

Note: I downloaded your data to a local file ideone_fM0rs.txt using the download link at http://ideone.com/fM0rs

Bill White
  • 1,769
  • 14
  • 14
  • 1
    "It's tempting to roll all that up into a single awe-inspiring one-liner" isn't it always... – acl Mar 13 '11 at 12:22
0

That's straightforward to do, and like everything in Mathematica there is more than one way to do it. Personally, I'd use

data = ReadList["Test.in", Number, RecordLists-> True];

and then process data using Map. There's also Import and your data probably is best loaded as type Table, although you can check the full list and see what's there. You could also use Read, but you'd have to control the file open/close yourself.

rcollyer
  • 10,475
  • 4
  • 48
  • 75
0

For the input aspect, this might give you a start.

vals = Import["http://ideone.com/fM0rs", 
  "Table"] /. {aa_ /; ! NumberQ[aa] && FreeQ[aa, List], ___} :> 
  Sequence[] /. {} :> Sequence[]

I think others on this forum may have better ways to go about it though; I'm not much versed in the Import/Export realm.

Daniel Lichtblau Wolfram Research

Daniel Lichtblau
  • 6,854
  • 1
  • 23
  • 30
  • The returned Length@vals is 397, and the OP posted a file with 200 records. You are reading the "line numbers" too, but that should give a length of 400 :( – Dr. belisarius Mar 13 '11 at 02:01