Closed 3f8450e1-87bf-41c6-ab53-29a0552debb3 closed 11 years ago
patch
Attachment: pretty_console_print-EliX-jbp.patch.gz
several examples (some not in the patch)
Attachment: pcp_monkey_patch.py.gz
Whats the difference between _repr_
, _pretty_repr_normal_
, and _pretty_repr_term_
? I think there should be only one _repr_
, using ascii art unconditionally if printing the object benefits from it. Why would you want to turn it off? I don't see the need for a different display handler, we aleady have one that does handle ascii art.
I implement _pretty_repr_
to introduce a special ascii-art method (like in mupad) and I prefere let the method _repr_
to allow differents use. In general case, we can copy the ouput and re-use it in terminal (it is very usefull I think).
Then I put a method _pretty_repr_term_
like we have _repr_term_
for a linear expression.
I saw your handle ascii art and I try to send you a mail to merge that.... (no??).
I saw your email but #14040 has already been merged. What I'm saying is, there should be more integration into the existing framework and less reinventing the wheel. Also nobody wants an ugly representation. You can't copy/paste matrices either. To get an input that recreates the object, we already have
sage: m = matrix(ZZ, [[0, 0, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
sage: m
[0 0 0]
[0 0 0]
[1 0 0]
[0 1 0]
[0 0 1]
sage: sage_input(m)
matrix(ZZ, [[0, 0, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
How about a %magic to switch to the sage input representation to the displayhook, e.g.:
sage: %sage_input on
sage: m = matrix(ZZ, [[0, 0, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
sage: m
matrix(ZZ, [[0, 0, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
or perhaps both (if sage_input
differs from _repr_
)
I don't reinventing the wheel... Then I prefere a nice LaTeX representation too but with some objects the LaTeX compilation is very slow. Then thanks to the method
sage: sage_input(m)
I didn't know but... after try...
sage: R = NonCommutativeSymmetricFunctions(QQ).R()
sage: a = R[1]**3; a
R + R + R + R
* ** * ***
* * **
*
sage: %pcp
'Pretty Console Print' is uninstalled
sage: sage_input(a)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-7eccf1bd1684> in <module>()
----> 1 sage_input(a)
/home/priezjea/sage-5.8.beta4/local/lib/python2.7/site-packages/sage/misc/sage_input.pyc in sage_input(x, preparse, verify, allow_locals)
252 if not verify:
253 sib = SageInputBuilder(allow_locals=allow_locals, preparse=preparse)
--> 254 return sib.result(sib(x))
255
256 # In verify mode, we actually compute and verify the answer with
/home/priezjea/sage-5.8.beta4/local/lib/python2.7/site-packages/sage/misc/sage_input.pyc in __call__(self, x, coerced)
540 return SIE_literal_stringrep(self, loc_name)
541 else:
--> 542 raise ValueError, "Can't convert %r to sage_input form"%x
543
544 def preparse(self):
ValueError: Can't convert R[1, 1, 1] + R[1, 2] + R[2, 1] + R[3] to sage_input form
and
sage: R[1]**3
R[1, 1, 1] + R[1, 2] + R[2, 1] + R[3]
can be easily be copy.
So I don't say I invented something... I just purpose something to work (In my case) easily with linear combination.
So the bug is that NonCommutativeSymmetricFunctions
doesn't define its own Sage input representation (define _sage_input_
). The ascii art should be the default (and only) print representation.
I like the idea of a magic function "%sage_input on". And if every thing is ascii-art... I have some question:
1 - The _repr_
method return (and must return) a string and it is too poor to produce an efficient and usefull ascii-art output. We could image use some baseline notion or ... My opinion is an ascii-art output must be a special class like PrettyConsoleRepr or whatever which can be improve by heritage. (That is not available with string.) --> That why my opinion is we don't have to use _repr_
but anything else.
2 - How to use your code to get (easily) a list, a dict or whatever of some objects with an ascii-art output ? Your code implement only a hack for Matrix (or it was before...) no? --> If it is true my code suggests a solution (may be a bad one...)
(Sorry for my very bad english)
I am a bit new on this discussion, but I want to add my contribution.
I think having _pretty_repr_
as a plus for combinatorial objects is a good idea and useful. It is not the same as _repr_
.
First, you don't want to change the repr of every combinatorial objects to have pretty prints, this will just break everything every where. (I am thinking of trees, Dyck paths, partitions...). Most objects already had a way being pretty printed, it was just not centralized and could not be used in linear combinations.
I actually think having the two _repr_
and _pretty_repr_
is useful. I have started to work with Jean-Baptiste's patch and depending on what I want to do with the output, I use both the pretty prints and usal prints.
Replying to @vbraun:
Whats the difference between
_repr_
,_pretty_repr_normal_
, and_pretty_repr_term_
? I think there should be only one_repr_
, using ascii art unconditionally if printing the object benefits from it. Why would you want to turn it off? I don't see the need for a different display handler, we aleady have one that does handle ascii art.
There is definitely a need for a configurable display. In combinatorics depending on the context we really need to be able to be able to print various object in several different ways: The simplest example is partitions. Sometimes you need to see: (3,3,2,1,1) sometime you need
###
###
##
#
#
or if you are french
#
#
##
###
###
Another example is graphs. Currently we only have Graph on 6 vertices Probably many user will rather have Graph on 6 vertices with 5 edges Or to see the incidence matrix...
So I definitely see a need for configurable output.
Florent
I don't agree with your partition example: It should just print ascii-art (with some cutoff if the tableau gets too large) and provide a method to get the tuple-of-integers. Which you need anyways. And the French should get along with the program and get used to the same notation as the rest of the world ;-)
Seriously, we should first of all think about sane defaults that are as expressive as possible without being overly verbose. Just making everything configurable is a lame cop-out where you admit that you couldn't be bothered thinking about good defaults. If you want to see some other representation then you can always add an extra method. Why do you want a %magic to always print graphs as incidence matrix if you can just call the incidence_matrix()
method?
I would recommend using the GlobalOptions
that was setup in #13605 (you can look in partition.py
or tableau.py
for examples) to choose been what type of output you want on a global level. I also have some fairly generic code for ascii printing lists of arrays (it's currently sitting inside of #13872 and have been calling the specialized display functions _repr_diagram()
), which is what you'd want since you'd want to call partition._repr_
to be consistent with the options specified there. I could separate that out into a separate ticket or copy/paste it here if you'd like.
Replying to @vbraun:
I don't agree with your partition example: It should just print ascii-art (with some cutoff if the tableau gets too large) and provide a method to get the tuple-of-integers. Which you need anyways. And the French should get along with the program and get used to the same notation as the rest of the world ;-)
Unforunately, I seems that many combinatorialist agree with me. Please se the beginning of the sage/combinat/partitions.py
files. There is a PartitionOptions
dictionary which allows one to configure various thing including the output.
new ascii art version.
That one is compatible with the Braun's displayhook.
It uses sympy to rewrite expression (or try to rewrite)::
sage: integral(exp(x^2)/(x+1), x)
⌠
⎮ ⎛ 2⎞
⎮ ⎝x ⎠
⎮ ℯ
⎮ ───── dx
⎮ x + 1
⌡
(FIXME:: For that I have to use utf-8 output for that I use a hack in sage/all_cmdline.py...)
I implement several pretty_repr for combinatorial object and plug that for free_module::
sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon()
sage: Tableaux.global_options(convention="french")
sage: R[3,1,1]
R
***
*
*
sage: R[3,1,1] * R[2,1,2]
R + R
*** ***
* *
* ***
** *
* **
**
sage: F = QSym.F()
sage: F[2,1,2]
F
**
*
**
The AsciiArt module (old PrettyConsolRepr) purpose a 'new' option of baseline.
Attachment: trac_14266_pretty_console_print-EliX-jbp.patch.gz
new ascii art version
Looks pretty nice! I'm fine with the functionality, but the documentation needs to be improved. Especially since you want to provide other developers a framework to enable ascii art output.
Some of the names are awkward in English. Pretty console representation means that the console is pretty, not the repr(esentation). It would be nice (and it would make writing doctests easier) if we install a global function analogous to repr()
to get the ascii art representation. I would suggest we call it display()
and the magic %display
(instead of %pcp
, unless you want to use it as a pun on the hallucinogenic drug).
Similarly, I don't like __pretty_repr__
. Its not a variant of __repr__
with pretty output since it returns a specialized object instead of a string. Its also not a Python builtin, so Sage coding style would use only single underscores. How about we call it _ascii_art_()
? Similarly, set_display
instead of set_pretty_repr
.
Also, since this should be a general framework we should add a default _ascii_art_
method (with suitable documentation to benefit developers) to SageObject
. For example (in sage_object.pyx
):
def _ascii_art_(self):
'''
Return an ASCII art representation.
To implement multi-line ASCII art output in a derived class
you must override this method. Unlike :meth:`_repr_`, which is
sometimes used for the hash key, the output of
:meth:`_ascii_art_` may depend on settings and is allowed to
change during runtime. For example,
:meth:`~sage.combinat.tableau.Tableaux.set_display` can be
used to switch the ASCII art of tableaux between different
mathematical conventions.
OUTPUT:
An :class:`~sage.misc.ascii_art.AsciiArt` object, see
:mod:`sage.misc.ascii_art` for details.
EXAMPLES:
You can use the :func:`~sage.misc.ascii_art.display` function
to get the ASCII art representation of any object in Sage::
sage: display(integral(exp(x^2)/(x+1), x))
⌠
⎮ ⎛ 2⎞
⎮ ⎝x ⎠
⎮ ℯ
⎮ ───── dx
⎮ x + 1
⌡
Alternatively, you can use the `%display on/off` magic to
switch all output to ASCII art and back::
sage: tab = StandardTableaux(3)[2]; tab
[[1, 2], [3]]
sage: %display on
sage: tab
1 2
3
sage: Tableau.set_display("normal")
sage: tab
+---+
| 3 |
+---+---+
| 1 | 2 |
+---+---+
sage: %display off
TESTS::
sage: 1._ascii_art_()
1
sage: type(_)
sage.misc.ascii_art.AsciiArt
'''
from sage.misc.ascii_art import AsciiArt
return AsciiArt(repr(self))
Finally, __every__
function must be documented and doctested. Please follow http://www.sagemath.org/doc/developer/conventions.html#docstring-markup-with-rest-and-sphinx for the markup. For example, we use an OUTPUT:
block instead of @postcondition
.
Replying to @vbraun:
Some of the names are awkward in English. Pretty console representation means that the console is pretty, not the repr(esentation). It would be nice (and it would make writing doctests easier) if we install a global function analogous to
repr()
to get the ascii art representation. I would suggest we call itdisplay()
and the magic%display
(instead of%pcp
, unless you want to use it as a pun on the hallucinogenic drug).
I'm not a big fan of %display
, it's somewhat vague as a true/false. How about %ascii_art
or have %display
accept a string input such as "ascii_art"
incase we end up with more display types later on? (I think if you see ascii art, you're trippin' on some %pcp
O_o )
Similarly, I don't like
__pretty_repr__
. Its not a variant of__repr__
with pretty output since it returns a specialized object instead of a string. Its also not a Python builtin, so Sage coding style would use only single underscores. How about we call it_ascii_art_()
? Similarly,set_display
instead ofset_pretty_repr
.
I like the _ascii_art_()
. However I would rather this be converted into using the GlobalOptions
framework instead of a separate function and attribute (tableaux already has this, and I can do it for Dyck paths if preferred). We can also use this for partitions as well.
Also, since this should be a general framework we should add a default
_ascii_art_
method (with suitable documentation to benefit developers) toSageObject
.
+1
@
Jean-Baptiste
I would also like to see AsciiArt
inherit from SageObject
as well, and subsequently use _repr_
instead of __repr__
(1 underscore instead of 2). Also I would like to see the trailing whitespace removed from the new lines you've added, but this is not too important. (I like your ascii art in the beginning, too bad it's not of a sage [okay, I'm done with bad puns for now, promise].)
Thanks,
Travis
It would be even better if default _ascii_art_
was deTeXed _latex_
, rather than just _repr_
.
I played with tex2mail
a bit and it was quite nice, although I never got to trying to include it into Sage.
Replying to @novoselt:
It would be even better if default
_ascii_art_
was deTeXed_latex_
, rather than just_repr_
. I played withtex2mail
a bit and it was quite nice, although I never got to trying to include it into Sage.
There are other implementations of that idea, for example AsciiTeX. But that's not what this ticket is about.
Replying to @tscrim:
I'm not a big fan of
%display
, it's somewhat vague as a true/false. How about%ascii_art
or have%display
accept a string input such as"ascii_art"
incase we end up with more display types later on?
Sounds good to me. %display ascii_art
and %display repr
, perhaps with aliases on
/off
for the lazy.
Attachment: trac_14266_ascii_art_module-EliX-jbp.patch.gz
New version with several tests for lot of methods... with AsciiArt
inherit SageObject
.
I purpose to use %display ascii_art
and display repr
to select one use.
I hope I don't forget anything.
Enjoy.
Thanks, Jean-Baptiste
I see you are developing your own whitespace style. Unfortunately, its a slap in Guido Rossum's face. Can you have a look at pep8 ( http://www.python.org/dev/peps/pep-0008/#whitespace-in-expressions-and-statements)?
def display_magic_function( self, mode = 'ascii_art'): # no
def display_magic_function(self, mode='ascii_art'): # yes
It is unreadable for you or/and you want and I must code like that???
It is not totally unreadable, but reading code that does not follow a consistent styles does require additional mental resources that are better used elsewhere. As annoying as it seems to be on the outset, there have been scientific studies that have found evidence for the benefits of a consistent code style. All large software projects have one, and Sage uses the Python code style.
What do you mean by
.. TODO::
revenir dessus..
That method looks fine to me. Is there anything left that you want to change?
Sorry I forgot to delete this message. It was when I adapted the text to the code... I have nothing to change.
A few more things:
_private_methods
).AUTHORS:
- Jean-Baptiste ...
EXAMPLES::
trac_14266: new version of ascii art module and magic function associated.
Thanks.
In fact, do not include the trac ticket number in the commit message. Jeroen's merger script will put the correct number there automatically. Just
New version of ascii art module and associated magic functions
Replying to @tscrim:
A few more things:
- There's still a few functions without doctests (this includes
_private_methods
).
I added some test... but sometime when the method it just a capsule:
def meth(self):
return self.other_meth()
or something similar, I just put see :meth:other_meth
.
- Bullet points needs a blankline before them, in particular, the authors block should be
AUTHORS: - Jean-Baptiste ...
I think it's okay now.
- Any block should be in all caps, such as
EXAMPLES::
I hope it's okay too.
- I'd prefer using triple double-quotes rather than triple single-quotes for consistancy, but this is not a big issue
I try to do that when it's not my files and I think (but I don't verify) it is consistant in mine.
- Your commit message should have the description on the first line:
New version of ascii art module and magic function associated.
In the last patch I put that and this one must work on 5.9.
Thanks, Jean-Baptiste
Attachment: trac_14266_ascii_art_module-EliX-jbp.2.patch.gz
I don't like your approach for changing the output, you are monkey-patching sage.misc.displayhook to change its behavior from another module. Thats usually a no-no in production code (unless you cannot control the source that you are patching, which is not the case here). The problem is that if anybody is going to edit sage.misc.displayhook later on, they will inadvertently break your construction since noting in the source code of the displayhook knowns that this is not the actual code that is used when Sage is running. The standard solution to associating state with a function is to use a functionoid, that is, a class with a __call__
method:
class FormatObj():
def __init__(self):
self._display = False
def set_ascii_art(self, ascii_art):
self._display = bool(ascii_art)
def __call__(self, obj):
if self._display:
...
else:
....
format_obj = FormatObj()
As a bonus, your code then wouldn't need layers of indirection format_obj
-> pretty_format
-> simple_format_obj
.
I will try to do that but I'm not really sure to understand the good way...
I have an other problem. I think I don't load display_magic_func.py
at the good place and that fail all tests.
The %display
magic should be defined in sage.misc.sage_extenison
with an @line_magic
like the other magics. You shouldn't have to add anything to sage.all_cmdline
.
Replying to @sagetrac-elixyre:
Replying to @tscrim:
A few more things:
- There's still a few functions without doctests (this includes
_private_methods
).I added some test... but sometime when the method it just a capsule:
def meth(self): return self.other_meth()
or something similar, I just put
see :meth:other_meth
.
The need doctests not just docstings (there are still non-trivial methods without tests). However if they are simple wrappers like that, just make it an alias:
other_meth = meth
- I'd prefer using triple double-quotes rather than triple single-quotes for consistency, but this is not a big issue
I try to do that when it's not my files and I think (but I don't verify) it is consistent in mine.
This is not done in other files you've modified (ex. tableau.py
), and again, to be consistent with the project as whole, I would recommended using double quotes. However in new files you've created, this is a very minor issue to me (i.e. I won't let it hold up a positive review).
Thanks,
Travis
Attachment: trac_14266_ascii_art_13_05_14_EliX-jbp.patch.gz
I make some modifications to use correctly displayhook.
I have several problems for make tests: I use the fact to be in a terminal to take the width of the window... excepted in test context it seems to be differents...
File "ascii_art.py", line 25, in sage.misc.ascii_art
Failed example:
ascii_art(integrate(n^2/(pi*x),x))
Expected:
2
n *log(x)
---------
pi
Got:
stty: stdin isn't a terminal
2
n *log(x)
---------
pi
There is an other points, if we use utf8 in the terminal, it is not utf8 during the tests...
Why don't pass sage to utf8?
Thanks, Jean-Baptiste
The doctesting should be mostly utf-8 clean, I think. See also #14153. What exactly is the problem?
The stty: stdin isn't a terminal comes because the controlling terminal isn't a terminal for doctests. You should set a fixed width (probably 80) independent of the actual terminal size during doctests, something like this:
def terminal_width():
import os, sys
from sage.doctest import DOCTEST_MODE
isatty = os.isatty(sys.stdout.fileno())
if DOCTEST_MODE or not isatty:
return 80
import fcntl, termios, struct
rc = fcntl.ioctl(int(0), termios.TIOCGWINSZ,
struct.pack('HHHH', sys.stdout.fileno(), 0, 0, 0))
h, w, hp, wp = struct.unpack('HHHH', rc)
return w
The "pcp" abbreviation is still floating around in a few places, can you replace those?
Attachment: trac_14266_ascii_art_13_05_15_EliX-jbp.patch.gz
Dependencies: #8703
Hi,
I'm really bad with mercurial but it seems to be good...
I made that module for see quickly trees in terminal so I added _ascii_art
methods for trees. (depends of #8703).
And all "pcp" abbreviation are disappear.
Thanks,
Jean-Baptiste
Looks great! I just have some minor nitpicks:
_terminal_width()
, it should return 80 in doctest mode.revenir dessus
is still theremisc/sage_extension.py
, you probably want to delete that, too.except:
statements are not allowed in Sage (the user might have pressed Ctrl-C and a KeyboardException was raised). Jeroen's merger script will check for that...Apart from that it is good to go.
Changed dependencies from #8703 to #8703 #14203
Reviewer: Volker Braun, Travis Scrimshaw
Description changed:
---
+++
@@ -15,3 +15,10 @@
** ** * *** ****
** ***
+ +--- + +Apply: + +- attachment: trac_14266_ascii_art_13_05_15_EliX-jbp.patch +- attachment: trac_14266-ascii_art-review-ts.patch
I've uploaded a review patch which makes a variety of changes, including:
*_tree.py
tableau.py
dyck_word.py
Volker, would you be willing review my review patch?
Thanks,
Travis
Patchbot:
Apply trac_14266_ascii_art_13_05_15_EliX-jbp.patch trac_14266-ascii_art-review-ts.patch
I get two test failures on sage-5.10.beta3:
sage -t --long devel/sage/sage/doctest/sources.py # 1 doctest failed
sage -t --long devel/sage/sage/misc/ascii_art.py # 1 doctest failed
Fixed:
sage -t --long misc/ascii_art.py
[116 tests, 4.35 s]
sage -t --long doctest/sources.py
[327 tests, 122.27 s]
----------------------------------------------------------------------
All tests passed!
----------------------------------------------------------------------
I also removed all trailing whitespace from misc/ascii_art.py
and fixed some minor docstring issues.
apply trac_14266_ascii_art_13_05_15_EliX-jbp.patch, trac_14266-ascii_art-review-ts.patch
Travis, your patch only applies with fuzz 2. Can you rebase it against the newest Sage beta?
My patch creates a simple ascii-art module to manipule several structure: list,dict,tuple, linear expression:
Apply:
Depends on #8703 Depends on #14203 Depends on #14574
CC: @nthiery @VivianePons
Component: user interface
Keywords: ascii-art
Author: Jean-Baptiste Priez
Reviewer: Volker Braun, Travis Scrimshaw
Merged: sage-5.11.beta0
Issue created by migration from https://trac.sagemath.org/ticket/14266