Discussions related to Visual Prolog
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

A list to CSV

Unread post 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
Harrison Pratt
VIP Member
Posts: 335
Joined: 5 Nov 2000 0:01

Unread post 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).
User avatar
Thomas Linder Puls
VIP Member
Posts: 1194
Joined: 28 Feb 2000 0:01

Unread post 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.
...
Regards Thomas Linder Puls
PDC
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

Unread post 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
User avatar
Tonton Luc
VIP Member
Posts: 204
Joined: 16 Oct 2001 23:01

Unread post 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()
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi »

Dear Sir;
Thank you.
Assume that the list hasn't the same length.
Thanks
Ahmed
User avatar
Thomas Linder Puls
VIP Member
Posts: 1194
Joined: 28 Feb 2000 0:01

Unread post 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.
Regards Thomas Linder Puls
PDC
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

Unread post 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
User avatar
Thomas Linder Puls
VIP Member
Posts: 1194
Joined: 28 Feb 2000 0:01

Unread post 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.
Regards Thomas Linder Puls
PDC
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

Unread post 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
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi »

Dear Sir;

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

regards;

AHMED
User avatar
Thomas Linder Puls
VIP Member
Posts: 1194
Joined: 28 Feb 2000 0:01

Unread post 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.
Regards Thomas Linder Puls
PDC
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Unread post 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).
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
Thomas Linder Puls
VIP Member
Posts: 1194
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

:D
Regards Thomas Linder Puls
PDC
ahmednadi
Active Member
Posts: 37
Joined: 15 Sep 2009 14:06

Unread post by ahmednadi »

Dear Sir;

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

Regards;

AHMED
Post Reply