See ​this sage-devel thread for more suggestions, including that we should have a Table class that table calls, which uses something like html.table in the notebook, but also has a _latex_ method, makes ascii art in the command line, etc.

Change History (42)

When defining a table, the user should be able to specify position/alignment (left, right, center). Should they be able to do this for each column, and do we like LaTeX notation for this? Should they be able to specify positioning for each individual entry?

Is it too much work to try to align numbers at their decimal places? ​LaTeX and ​LaTeX ways to do this. ​html and ​html ways to do this, but perhaps complicated or messy.

Should we refactor the matrix printing code so that it uses this class?

html.table expects a nested list as input, and so the entries in [1,2,3] get plotted as separate rows. is that the right thing, or should [1,2,3] get plotted as a single row?

We should probably steal code from html.table, matrix._repr_, matrix.str, matrix._latex_

Okay, here's a first attempt. For some reason I find the syntax table(array, header=another_row) strange, so this just allows for the header argument to be True or False, and the actual row needs to be the first row of array.

Oh, one more thing, at least for now: the previously existing technique of using html.table(...) treated a single list as a column, whereas this patch treats a single list as a row instead. This feels more natural to me. Anyone who really wants either a single row or a single column should use nested lists properly anyway.

My refrain of the last few months to your patches has been "I don't have time to give it a proper review, but this looks great on the face of it", so why not repeat it? I look forward to using this, and I know a lot of other people who rely on the equivalent way too much in Mma will love it.

Right now html.table(data, header=True) treats the first row as the header, but html.table(data, header=['label1', 'label2']) will let you specify the header independently. This is *extremely* useful. Usually I have a table of numbers or something, and being able to just specify the header row separately makes a huge difference in clarity.

is just strange. I can explain what it would do – first add the header row at the top of the data, then add the header column on the left – but in the docstring I just said that doing this is "not supported". Someone can specify True for one argument and a list for the other, or True for both, but I don't want to document using a list for both.

elif header_row is not False: why not just elif header_row? Presumably a Python subtlety.

Do we need something in html.table() (what remains of it) to change it so that the previous behavior of a single list giving a column and not a row is preserved? I know you removed the example, but technically speaking one should deprecate this...

Is there an extra

self._options['header_column'] = header_column

in there? It should be set already above that.

I don't see any error catching. This is particularly important in making sure someone doesn't (contra the doc, but still) try to add in a header row later on via header_row=[1,2,3] and in making sure that the table is, in fact, a rectangle. I think that for sanity, especially with very large tables, this would be helpful to have this error instead of who-knows-what-crazy-error Sage would raise otherwise.

Feature request; take a list of lists and just fill in the rest! I had to make my own code for this in some sense, filling in empty slots, if I recall correctly. But presumably this is like the list in comment:2 and for a future ticket.

I was just speaking with Andrew Mathas of the Sage-combinat group at Sage Days at ICERM and it turns out that he has a pretty impressive (minor bugs remaining) table object as well, which takes any iterable as a header column with indexing and has a slew of formatting options. Although the current functionality is almost ready for showtime, it would be useful to have some dialogue about the relation between these things, especially because some of the formatting stuff is nice. He also has a nice hook to ask for displaying a table in a browser automatically (html gets sent to the browser).

I was just speaking with Andrew Mathas of the Sage-combinat group at Sage Days at ICERM and it turns out that he has a pretty impressive (minor bugs remaining) table object as well, which takes any iterable as a header column with indexing and has a slew of formatting options. Although the current functionality is almost ready for showtime, it would be useful to have some dialogue about the relation between these things, especially because some of the formatting stuff is nice. He also has a nice hook to ask for displaying a table in a browser automatically (html gets sent to the browser).

Feature request; take a list of lists and just fill in the rest! I had to make my own code for this in some sense, filling in empty slots, if I recall correctly. But presumably this is like the list in comment:2 and for a future ticket.

This already works. I think I was wanting to have this work better, so that I didn't have to use map(None,...) and then replace with ''.

elif header_row is not False: why not just elif header_row? Presumably a Python subtlety.

I think that can be changed.

Do we need something in html.table() (what remains of it) to change it so that the previous behavior of a single list giving a column and not a row is preserved? I know you removed the example, but technically speaking one should deprecate this...

Technically speaking, I think you're right. I don't like the old behavior at all; it doesn't make sense to me. It might actually make sense to just raise an error if you pass a single list, not a nested list. I'm not sure what the right thing to do is.

Is there an extra

self._options['header_column'] = header_column

in there? It should be set already above that.

Yes, you're right.

I don't see any error catching. This is particularly important in making sure someone doesn't (contra the doc, but still) try to add in a header row later on via header_row=[1,2,3]

should raise an error instead of just silently making [1,2,3] the header? Okay, I guess that makes sense.

and in making sure that the table is, in fact, a rectangle. I think that for sanity, especially with very large tables, this would be helpful to have this error instead of who-knows-what-crazy-error Sage would raise otherwise.

Feature request; take a list of lists and just fill in the rest! I had to make my own code for this in some sense, filling in empty slots, if I recall correctly. But presumably this is like the list in comment:2 and for a future ticket.

I'm not sure how these last two items relate to each other: the last one sounds like you want to be able to pass lists of different lengths and have the gaps filled in, and the previous one sounds like you want to raise an error if you pass lists of different lengths. But maybe I don't understand.

Would it be useful to have a transpose method to switch rows and columns? Here's a new patch which adds that, and also addresses all of the issues except the old behavior of html.table() and the last issue about a non-rectangular situation.

I also added documentation (in the eval method in html.py) for calling the _html_ method for an object, if it has one. This is analogous to the _latex_ method. I think this could be useful in other situations.

Thanks for clarifying the documentation of html(_) and for making html calling _html_ if it exists.

I have two questions:

Doc of html now says:

In any case, *print* the resulting html string. This method
always *returns* an empty string.

What if I want to print the output in a file and not in the shell. What should I do? This is something I came across in the past.

I really like the table function. I am defining such a function in a patch I posted just yesterday at #13069. In my case, the function takes columns as input and not rows. So, if I want to use your code, would you propose an interface that takes columns as input:

I really like the table function. I am defining such a function in a patch I posted just yesterday at #13069. In my case, the function takes columns as input and not rows. So, if I want to use your code, would you propose an interface that takes columns as input:

Thanks for clarifying the documentation of html(_) and for making html calling _html_ if it exists.

I have two questions:

Doc of html now says:

In any case, *print* the resulting html string. This method
always *returns* an empty string.

What if I want to print the output in a file and not in the shell. What should I do? This is something I came across in the past.

This is just documentation; I haven't changed the code. If we want to change the behavior of html (maybe just adding a str method or something like that), let's do it on another ticket and keep this one focused on tables.

I really like the table function. I am defining such a function in a patch I posted just yesterday at #13069. In my case, the function takes columns as input and not rows. So, if I want to use your code, would you propose an interface that takes columns as input:

This is just documentation; I haven't changed the code. If we want to change the behavior of html (maybe just adding a str method or something like that), let's do it on another ticket and keep this one focused on tables.

I agree. I just can't close my mouth sometimes!

I can add this, but what should happen if you do table(array, column=columns)? Raise an error? Or try to combine the two sets of data somehow? I think I prefer to raise an error.

Just added a patch which does nothing but removing trailing spaces (on 3 lines) and added the r to the """ to make doc be raw strings. ...sometimes I get doctest errors because I do not put this r. Maybe I am afraid of witches...

Jason, Karl-Dieter, to me this is positive review. Did you have anything else to say?

Jason, Karl-Dieter, to me this is positive review. Did you have anything else to say?

If you looked at the latest code carefully, nothing would please me more than for this to get in. I love all the improvements since the very first version. It is probably the number 1 or 2 most-requested basic feature in Sage available at the top level, in my experience, and will be very well received.