# How can I format a table to look nice?

I have this code, but I would like to see the results well formatted. How can I obtain a well formatted data with alignment similar to this one?

Instead, I obtain the result you see here (click to enlarge):

Here is the code wherein I attempt to obtain a well formatted results:

itmax = 10;
tolerancia = 0.2;
alfa = (-1 + Sqrt[5])/2;
ttheta[Lambda_] = Lambda^2 + 2*Lambda;
a = -3;
b = 5;
La = a + (1 - alfa)*(b - a) // N;
Mu = a + alfa*(b - a) // N;
tthetaLa = ttheta[La];
tLacalc = "*";
tthetaMu = ttheta[Mu];
tMucalc = "*";
Print["iteración_k   |   a_k    b_k   |   Lambda_k     Mu_k   |   \
theta(Lambda_k)  theta(Mu_k)"];
Do[
L = b - a;
Print[i, "   |   ", a, "     ", b, "   |  ", La, "     ", Mu,
"   |  ", tthetaLa, tLacalc "      ", tthetaMu, tMucalc ];
If[tthetaLa > tthetaMu,
If[b - a < tolerancia, Break[]];

a = La;
La = Mu;
Mu = a + alfa (b - a);
tthetaLa = tthetaMu;
tLacalc = " ";
tthetaMu = ttheta[Mu];
tMucalc = " ";,

b = Mu;
Mu = La;
La = a + (1 - alfa) (b - a);
tthetaMu = tthetaLa;
tMucalc = " ";
tthetaLa = ttheta[La];
tLacalc = "*";
]
, {i, 1, itmax}
];
Print["The stimated solution is ", solucionestimada,
" where functions value is ", valorestimado];

-
Have a look at Grid or TableForm and get rid of all your Print statements - the Mathematica workflow offers much better solutions. – Yves Klett Apr 18 '13 at 8:23
@Yves Klett Yves Klett Thank You. I´m agree you, but i think that Grid and TableForm are for Arrays, and i prefer don´t use arrays, because with major algorithms i don´t want to use many memory. – Mika Ike Apr 18 '13 at 8:41
Mathematica generally has little need of Print statements. Focus your code on creating the data you want as a result, then, as Yves has suggested, you can output that data in almost any form you desire using functions like Grid or Table. You may want to look at the functional programming features of Mathematica which would help make your code much more concise. – image_doctor Apr 18 '13 at 8:41
However you generate your data, you should abstract the data from any formatted output. If you want to display it in a notebook in readable textual form, memory should (presumably) not be an issue. How many elements do you want to display? – Yves Klett Apr 18 '13 at 9:00
@image_doctor Ok. Thank you very much. – Mika Ike Apr 18 '13 at 15:58

Here is something not far from your example:

Collecting data using Sow and Reap as shown by cormullion:

Sow[{i, a, b, La, Mu, Row@{tthetaLa, tLacalc}, Row@{tthetaMu, tMucalc}}]


We get:

dat =
{{1, -3, 5, 0.0557281, 1.94427, Row[{0.114562, "*"}], Row[{7.66874, "*"}]}, {2, -3,
1.94427, -1.11146, 0.0557281, Row[{-0.987578, "*"}], Row[{0.114562, " "}]}, {3, -3,
0.0557281, -1.83282, -1.11146, Row[{-0.306418, "*"}],
Row[{-0.987578, " "}]}, {4, -1.83282, 0.0557281, -1.11146, -0.665631,
Row[{-0.987578, " "}],
Row[{-0.888198, " "}]}, {5, -1.83282, -0.665631, -1.38699, -1.11146,
Row[{-0.850238, "*"}],
Row[{-0.987578, " "}]}, {6, -1.38699, -0.665631, -1.11146, -0.941166,
Row[{-0.987578, " "}],
Row[{-0.996539, " "}]}, {7, -1.11146, -0.665631, -0.941166, -0.835921,
Row[{-0.996539, " "}],
Row[{-0.973078, " "}]}, {8, -1.11146, -0.835921, -1.00621, -0.941166,
Row[{-0.999961, "*"}],
Row[{-0.996539, " "}]}, {9, -1.11146, -0.941166, -1.04641, -1.00621,
Row[{-0.997846, "*"}], Row[{-0.999961, " "}]}}


And produce the table shown above with:

headings = {"k", "\!$$\*SubscriptBox[\"a\", \"k\"]$$",
"\!$$\*SubscriptBox[\"b\", \"k\"]$$", "\!$$\*SubscriptBox[\"\[Lambda]\", \"k\"]$$",
"\!$$\*SubscriptBox[\"\[Mu]\", \"k\"]$$",
"\[Theta](\!$$\*SubscriptBox[\"\[Lambda]\", \"k\"]$$)",
"\[Theta](\!$$\*SubscriptBox[\"\[Mu]\", \"k\"]$$)"};

divs = # -> AbsoluteThickness@#2 & @@@ {{1, 3}, {2, 2}, {-1, 2}};

Grid[
Dividers -> {{}, divs},
Alignment -> ".",
BaseStyle -> FontFamily -> "Calibri"
]


(Sorry about the horrible looking code for headings; it is simply a list of formatted strings in the Front End.)

As requested, here is complete code to generate the dat expression shown above:

itmax = 10;
tolerancia = 0.2;
alfa = (-1 + Sqrt[5])/2;
ttheta[Lambda_] := Lambda^2 + 2*Lambda;
a = -3;
b = 5;
La = a + (1 - alfa)*(b - a) // N;
Mu = a + alfa*(b - a) // N;
tthetaLa = ttheta[La];
tLacalc = "*";
tthetaMu = ttheta[Mu];
tMucalc = "*";
dat =
Reap[
Do[L = b - a;
Sow[{i, a, b, La, Mu, Row@{tthetaLa, tLacalc}, Row@{tthetaMu, tMucalc}}];
If[tthetaLa > tthetaMu, If[b - a < tolerancia, Break[]];
a = La;
La = Mu;
Mu = a + alfa (b - a);
tthetaLa = tthetaMu;
tLacalc = " ";
tthetaMu = ttheta[Mu];
tMucalc = " ";, b = Mu;
Mu = La;
La = a + (1 - alfa) (b - a);
tthetaMu = tthetaLa;
tMucalc = " ";
tthetaLa = ttheta[La];
tLacalc = "*";], {i, 1, itmax}]
][[2, 1]]


It will be necessary to read the documentation for Sow and Reap to understand this. Also, func @ arg is equivalent to func[arg], I just prefer to use the former sometimes. The [[2, 1]] after Reap is a syntax for Part, and is used to extract (only) the sowed expression from the returned value of Reap. (Again, see the documentation for Reap.)

-
I like very much your answer. Ilove it, but i don´t know how i must modify my code to obtain this. I don´t know how i use Reap Sow , to make the table. Could you attach the .nb file, or a .txt. to learn this?. Thank You very much. – Mika Ike Apr 20 '13 at 4:46
@MikaIke Sorry, I thought the Accepted answer covered this. I'll add an example to my answer. – Mr.Wizard Apr 20 '13 at 4:48
i understand the essence, but my problem is colllecting data with Reap Sow (i don´t know about this before cormullion talks about it). I think that it´s very usefull but untill now, i can´t use it correctly in my code. So i can obtain a table. – Mika Ike Apr 20 '13 at 5:08
The firts time i heard avbout Reap Sow was in the @cormullion message, and i think that it´s usefull. – Mika Ike Apr 20 '13 at 5:09
@MikaIke Does my example adequately illustrate how to use this in your application? – Mr.Wizard Apr 20 '13 at 5:09

Mathematica doesn't do the slickest table formatting in the world, but you can do quite well, with some effort.

To get something like this, you have to get your data into a list, say result, and your headings into another list, say header. Then:

Panel[
Print["The estimated solution is ", solucionestimada,
" where functions value is ", valorestimado];
Style[
TableForm[
result,
TableSpacing -> {1, 1},
Style["" <> #, Bold, TextAlignment -> Right, 10] & /@ header},
TableAlignments -> {".", Bottom}],
14, FontFamily -> "Georgia"]
]


To obtain the list from your code, do away with the Print statements, and instead collect the data. As you requested, this is the code I used to generate header and result, but please note that this was just a quick hack to get your code working the way I wanted it to - this isn't how to write Mathematica code!

itmax = 10;
tolerancia = 0.2;
alfa = (-1 + Sqrt[5])/2;
ttheta[lambda_] = lambda^2 + 2*lambda;
a = -3;
b = 5;
La = a + (1 - alfa)*(b - a) // N;
Mu = a + alfa*(b - a) // N;
tthetaLa = ttheta[La];
tLacalc = "*";
tthetaMu = ttheta[Mu];
tMucalc = "*";
header = {"iteración-k", "a-k", "b-k", "Lambda-k", "Mu-k",
"theta(Lambda-k)", " ", "theta(Mu-k)", " "};
collected = Reap[
Do[L = b - a;
Sow[{i, a, b, La, Mu, tthetaLa, tLacalc , tthetaMu, tMucalc}];
If[tthetaLa > tthetaMu, If[b - a < tolerancia, Break[]];
a = La;
La = Mu;
Mu = a + alfa (b - a);
tthetaLa = tthetaMu;
tLacalc = " ";
tthetaMu = ttheta[Mu];
tMucalc = " ";
, b = Mu;
Mu = La;
La = a + (1 - alfa) (b - a);
tthetaMu = tthetaLa;
tMucalc = " ";
tthetaLa = ttheta[La];
tLacalc = "*";],
{i, 1, itmax}];
]
result = Flatten[Rest[collected], 2];


This collects everything as you go, ready for the separate stage of formatting and presentation, once the calculation is finished. Another benefit of this is that you can spend hours playing with the formatting, without having to do all the calculations again... :)

If you want to play with Grid, you can get carried away and do stuff like this:

Panel[
Grid[
Spacings -> {0, 1},
Alignment -> {".", Automatic},
Background -> {None, {Lighter[Yellow, .9],
{White, Lighter[Blend[{Blue, Green}], .9]}}},
Frame -> True,
FrameStyle -> Directive[AbsoluteThickness[-10]]],
Style[Row[{"The estimated solution is ", solucionestimada,
" where functions value is ", valorestimado}], 16, Bold]]


(Odd that all the color and styling is in Grid but not TableForm...)

-
I think Grid ain´t half bad. Producing nice tables with TeX or (oh dear) Excel also takes a fair amount of work. – Yves Klett Apr 18 '13 at 9:15
I couldn't get TextAlignment working here... – cormullion Apr 18 '13 at 9:16
@YvesKlett You can do the Grid version... :) – cormullion Apr 18 '13 at 9:16
ouch - that hurt :-P – Yves Klett Apr 18 '13 at 9:48
@YvesKlett As you said, it ain't half bad :) – cormullion Apr 18 '13 at 10:57

The undocumented function TableView in version 9 (it exist in 8 too) looks quite close to Excel(and it has some basic Excel-like functions, try it out with a right click):

TableView[RandomReal[1, {6, 6}]]

, which would be a fine choice for lazy guys like me :D.

-
Just a note: TableView is notoriously unstable, you can easily crash the kernel fiddling with it, e.g. by editing a field. Until better integration (making it a proper, documented built-in) I wouldn't recommend using it. – István Zachar Apr 20 '13 at 7:41

I give below the table I did some time ago. You only need to replace my table by yours, that has the same structure. Note that the first sublist in the list "table" contains the titles of the columns in the resulting table, and the first elements of the other sublists are the titles of the lines. Play a bit with the colors to select ones according to your taste.

table = {{"Segment",
Column[{"Skin temperature [\[Degree]C]",
"@ cold stable conditions"}],
Column[{"Skin temperature [\[Degree]C]",
"@ warm stable conditions"}]},
{"Cheek", 27.7, 36.3},
{"Front neck", 33.5, 36.8},
{"Back neck", 34.5, 36.1},
{"Chest", 30.9, 36.1},
{"Back", 32.4, 36.3},
{"Abdomen", 28.7, 36.2},
{"Upper arm", 24.7, 36.4}};

Panel@Grid[table, Frame -> All,
Dividers -> Directive[Gray, Thickness[4]],
ItemSize -> {Automatic, 2},
Background -> {None, {LightYellow, {LightBlue, LightOrange}},
1 -> LightYellow}]


That is what should appear as the result:

-
Thank You very Much, i want to try and aunderstad the different options, but now my problem is that i don´t understand how i must modify my code, and how to collect data with Reap Sow to show them in a table. – Mika Ike Apr 20 '13 at 4:48