Page 1 of 2

A list to CSV

Posted: 24 Mar 2014 10:35
by ahmednadi
Dear Sir;

I hope to find you in a good health.

Could you help me to write the contents of a list to CSV file?

Is there a way to save factsDB from an internal Database to CSV file to put each field in a column in the CSV file?

Best regards;

AHMED NADY

Posted: 24 Mar 2014 13:37
by Harrison Pratt
AHMED,

There are several different CSF formats in common use. For example, the Excel-type double quotes strings but not numbers; others double quote only strings which have embedded commas, still others double quote everything.

One simple version that quotes everything looks like this:

Code: Select all

list_write_csv([]):- !. list_write_csv([H|[]]):- write('"', H, '"'), !. list_write_csv([H|T] ):- write('"', H, '"', ',' ), list_write_csv(T).

Posted: 24 Mar 2014 15:16
by Thomas Linder Puls
CSV is not a standardized file format, it is merely an encoding "idea".

The separator can be other things than comma.
Fields can be quoted (in order to contain the separator).
But I am not sure how to handle quotes inside fields.
Numbers can be formatted with comma or dot as decimal separator (hence the need not to use comma as over all seperator).
It is not defined how to write dates.
...

Posted: 25 Mar 2014 6:59
by ahmednadi
Dear Sirs;

Thank you for your reply.

I have lists as output and I want to rearrange the items of each list in a column.

Assume that I have three list as output
I want to put the items of List 1 in the first column and so on like a table.

By the way, I have an internal database has some facts, I want to put each fact in a row and each element of a fact in a field like a cell.

You fast action will be high appreciated.

Regards;

AHMED NADY

Posted: 25 Mar 2014 8:08
by Tonton Luc
Hi,

:idea:

Code: Select all

        Sep = "\t",         L1 = ["L1C1","L2C1","L3C1","L4C1","L5C1"],         L2 = ["L1C2","L2C2","L3C2","L4C2","L5C2"],         L3 = ["L1C3","L2C3","L3C3","L4C3","L5C3"],         OutputFile = outputStream_file::create8("C:\\test.xls"),         foreach Cpt = std::fromTo(0,list::length(L1)-1) do             OutputFile:write(list::nth(Cpt,L1),Sep,list::nth(Cpt,L2),Sep,list::nth(Cpt,L3)),OutputFile:nl         end foreach,         OutputFile:close()

Posted: 25 Mar 2014 8:26
by ahmednadi
Dear Sir;
Thank you.
Assume that the list hasn't the same length.
Thanks
Ahmed

Posted: 25 Mar 2014 10:03
by Thomas Linder Puls
You should never use nth for iteration, your algorithm will become quadratic (meaning the day your lists becomes long your program will "never" complete).

Assuming that you have a list of lists instead you can use a reqursive algorithm like this:

Code: Select all

predicates     writeCsv_table : (outputStream Out, string Seperator, Type** ColumnList). clauses     writeCsv_table(Out, Sep, ColumnList1) :-         if moreData(ColumnList1) then             ColumnList2 = writeCsv_row(Out, Sep, ColumnList1),             Out:write("\n"),             writeCsv_table(Out, Sep, ColumnList2)         end if.   predicates     moreData : (Type** ColumnList) determ. clauses     moreData([C|CL]) :- % there is a column which is not empty         [] <> C, ! or moreData(CL).   predicates     writeCsv_row : (outputStream Out, string Seperator, Type** ColumnList1) -> Type** ColumnList0. clauses     writeCsv_row(_Out, _Sep, []) = []. % will actually never be the case, see moreData       writeCsv_row(Out, Sep, [C1|CL1]) = [C0|CL0] :-         C0 = writeCsv_value(Out, C1),         if [] <> CL1 then Out:write(Sep) end if,         CL0 = writeCsv_row(Out, Sep, CL1).   predicates     writeCsv_value : (outputStream Out, Type** Column1) -> Type** Column0. clauses     writeCsv_value(_Out, []) = [].       writeCsv_value(Out, [V|VL]) = VL :-         Out:write(V).
(I have only written the code, not run it; so it may contain errors ;-)).

When going through rows, I keep an empty list for exhausted columns, to keep the remaining data in their own column.

So the algorithm is finished when all columns have become the empty column/list.

Posted: 25 Mar 2014 12:22
by ahmednadi
Dear Sir;

Thank you.

I try the proposed code but there is an error which is:

Code: Select all

The expression has type 'Type**', which is incompatible with the type 'Type*'
In the predicate called writeCSV_row.

You are kindly requested to help me to solve this problem.

By the way, I have an internal database has some facts, I want to put each fact in a row and each element of a fact in a field like a cell.

Regards;

AHMED NADY

Posted: 25 Mar 2014 19:01
by Thomas Linder Puls
I have of course added a small errors to make sure that you analyze the code :-).
  • Type** means is lists of lists of Type
  • Type* means is lists of Type
See if you can solve the type puzzle.

Posted: 26 Mar 2014 7:02
by ahmednadi
Dear Mr. Thomas;

Thanks a lot for your response.

I try to analysis the code but I would like to inform you that it is the first time to deal with lists of lists structure so, you help will enable me to understand this structure and how are data arranged in this structure?

So, your quick help is needed and your comments also.

Regards;

AHMED NADY

Posted: 26 Mar 2014 12:19
by ahmednadi
Dear Sir;

I try to used zip_nd but the lists hasn't the same length. it is fail.

regards;

AHMED

Posted: 26 Mar 2014 13:25
by Thomas Linder Puls
[A, B, C, D, ...] is a list. If A, B, C, D, ... are themselves lists, then you have a list of lists:

Code: Select all

[[A1, A2, ...], [B1, B2, ...], [C1, C2, ...], [D1, D2, ...], ...]
A table is a number of columns, each column is number of values.

So a table is a list of columns and a column is a list of values, hence a table is a list of lists of values.

This means that column have type Type* (list of something) and table have type Type** (list of list of something). So to solve the problem in my code you have to look for places where Table is not Type** and/or column is not Type*

Here Type is string:

Code: Select all

ColumnA= ["A1", "A2", "A3"], ColumnB = ["B1", "B2"], ColumnC = ["C1", "C2", "C3", "C4"], Table = [ColumnA, ColumnB, ColumnC], Out = stdio::getOutpueStream(), writeCsv_table(Out, ",", Table)
By the way, I think it is a bad strategy to write some completely different code (based on e.g. zip_nd) instead of solving the type error in the code I have presented.

Posted: 26 Mar 2014 13:39
by George
:roll: :roll:

Code: Select all

predicates     writeCsv_table : (outputStream Out, string Seperator, Type** ColumnList). clauses     writeCsv_table(Out, Sep, ColumnList1) :-         if moreData(ColumnList1) then             ColumnList2 = writeCsv_row(Out, Sep, ColumnList1),             Out:write("\n"),             writeCsv_table(Out, Sep, ColumnList2)         end if.   predicates     moreData : (Type** ColumnList) determ. clauses     moreData([C|CL]) :- % there is a column which is not empty         [] <> C, ! or moreData(CL).   predicates     writeCsv_row : (outputStream Out, string Seperator, Type** ColumnList1) -> Type** ColumnList0. clauses     writeCsv_row(_Out, _Sep, []) = []. % will actually never be the case, see moreData       writeCsv_row(Out, Sep, [C1|CL1]) = [C0|CL0] :-         C0 = writeCsv_value(Out, C1),         if [] <> CL1 then Out:write(Sep)         end if,         CL0 = writeCsv_row(Out, Sep, CL1).   predicates  %Place to play.. :)     writeCsv_value : (outputStream Out, Type* Column1) -> Type* Column0. clauses     writeCsv_value(_Out, []) = [].       writeCsv_value(Out, [V|VL]) = VL :-         Out:write(V).

Posted: 26 Mar 2014 22:38
by Thomas Linder Puls
:D

Posted: 27 Mar 2014 14:35
by ahmednadi
Dear Sir;

could you help me to get the output in an external file *.csv?

Regards;

AHMED