Forum > Beginners

Save and write whole arrays of numbers to the text files

(1/4) > >>

matandked:
I just read article on wiki about handling files (http://wiki.freepascal.org/File_Handling_In_Pascal).

It seems that saving arrays to a binary files is quite easy (http://wiki.freepascal.org/File_Handling_In_Pascal#Binary_files)
However, I would like to read/write whole arrays from/to text/CSV files.

I can do this with for-loop statements (as I do in my code below which saves array to file), but I wonder if there's any better/simpler way of doing this in Free Pascal/Lazarus?
Maybe there's a counterpart of write.csv R! function (http://rprogramming.net/write-csv-in-r/)?



--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; {$mode objfpc}{$H+} uses  {$IFDEF UNIX}{$IFDEF UseCThreads}  cthreads,  {$ENDIF}{$ENDIF}  Classes, Sysutils; const  C_FNAME = 'Array_Saved_to_TextFile.txt';  // separate by tab:  separator = Char(9);var  // I would like to save this array to text file  // separated by tabs or any other character  myArray: array [1..2,1..3] of Real =    ((0.5, 2.4, 1.2), (3.4, 5.3, 6.5));  slInfo: TStringList;  row, column: Integer;  line : String; begin  If not FileExists(C_FNAME) Then    begin       // I wonder if there's any simpler/better solution      // For example if in Free Pascal there's counterpart of      // R! write.table function      /////////////////////////////////////////////////////////      slInfo := TStringList.Create;      For row:=1 to 2 do          begin            line := '';            For column:=1 to 3 do                line := line + FloatToStr(myArray[row, column]) + separator;          Delete (line,Length(Line),1);          slInfo.Add(line);          end;       slInfo.SaveToFile(C_FNAME);      slInfo.Free;      /////////////////////////////////////////////////////////        WriteLn('Array has been saved in file: ' + Char(39) + C_FNAME + char(39));    end  else      begin        WriteLn('Following file already exists: ' + Char(39) + C_FNAME + Char(39));      end;  ReadLn;end. 

Thaddy:
If you insist on storing the values in a human readable format, I am afraid, that your current effort comes close to a good solution. Thumbs up!
If that is not necessary, there are several options to speed things up, big time.

Can you explain - in a better way - why you need the human readable format?

lainz:
Maybe to be edited in a third party software, Excel or LibreOffice Calc

What I learned in university about CSV is that you need to specify (not necessary at all but useful) the width and height of the array, so you can call SetLength at the beginning, then load it line by line, instead of loading the entire text file in memory. If the file is not big you can use TStringList and for each N line do a new temporary TStringList and add the N line as delimitedtext or commatext, I don't remember wich one. Then you can access the horizontal data with an index of the temporary TStringList.

To save you already have a code, is the most simple part, you can specify here the width and height of the array (not needed if you use a TStringList, since it split the data with commatext or delimitedtext at loading time).

Another thing I've learned is that is a wrong code:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---For row:=1 to 2 do ... For column:=1 to 3 do Always refer to the array length, don't use any numeric constants 'magic numbers'. If you change the data length you will not need to change these numbers later.

Handoko:
Yes, 'magic numbers' should be avoid unless you are sure it won't change. So the better code is:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const  RowCount = 2;  ColumnCount = 3; var  myArray: array [1..RowCount, 1..ColumnCount] of Real = ... ...for Row := 1 to RowCount do...  for Column := 1 to ColumnCount do......

matandked:

--- Quote from: Handoko on February 03, 2017, 06:30:09 pm ---Yes, 'magic numbers' should be avoid unless you are sure it won't change. So the better code is:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const  RowCount = 2;  ColumnCount = 3; var  myArray: array [1..RowCount, 1..ColumnCount] of Real = ... ...for Row := 1 to RowCount do...  for Column := 1 to ColumnCount do......

--- End quote ---


I wasn't aware that it is possible to do that in FreePascal - I expected that I will be able to get them in different way for example: myArray.GetNumberOfRows
Thank you!!!



--- Quote from: Thaddy on February 03, 2017, 06:11:11 pm ---If you insist on storing the values in a human readable format, I am afraid, that your current effort comes close to a good solution. Thumbs up!
If that is not necessary, there are several options to speed things up, big time.

Can you explain - in a better way - why you need the human readable format?

--- End quote ---

Thank you for a quick response.

The only reason is that end users requested to have output in Excel and text file/human readable formats, because they're familiar with them.

Generally speaking I was asked to write a program that:

* will read data from a set of Excel workbooks or text files >:D
* perform calculations (currently I have no details, but there will be some simple arithmetic operations as well as linear programming tasks) on just read arrays of numbers 
* save output to Excel spreadsheet and text file

Off topic
I thought about using FPSpreadsheet (http://wiki.freepascal.org/FPSpreadsheet) to read data from Excel file.
I'm not sure if there's any ready-to-use function to read Excel range of cells as Free Pascal array (in such case I will need to write another loop again to iterate over cells in range  >:D).
Anyway, I think that it will be better way to firstly read all numbers as arrays and then performing operations on them (am I correct or should I change all my assumptions from the beginning  ::)
Besides I haven't checked yet if Free Pascal has any library for table/matrix operations (so that I will be able to write shorter code such as in Octave/Matlab), but I assume that yes - it seems to be a cool language from the new user perspective  8-)

Navigation

[0] Message Index

[#] Next page

Go to full version