Ask Your Question
1

Pretty print output in Jupyter notebook

asked 2019-02-17 10:00:45 -0500

Juanjo gravatar image

In order to provide meaningful results to my students in a Jupyter notebook, I would like to pretty print some output, including text, LaTeX and things computed by Sage. I have found that I could combine either show (or pretty_print) and html, or show and LatexExpr. For example, either

limit = r"\displaystyle\lim_{x\to0}\frac{\sin x}{x}="
value = lim(sin(x)/x, x=0)
show(html("Solucion: "+"${}={}$".format(limit,value)))

or, instead,

limit = r"\displaystyle\lim_{x\to0}\frac{\sin x}{x}="
value = lim(sin(x)/x, x=0)
show("Solucion: ", LatexExpr(limit), value)

I would ask the following questions:

  1. Is there any reason to prefer one approach to the other?
  2. If I replace "Solucion" by "Solución" (please note the accented ó), which is the correct way to write this Spanish word, in both approaches I get meaningless letters instead of the expected output. If I use u"Solución", then Sage raises the error 'ascii' codec can't encode character u'\xf3' in position 6: ordinal not in range(128). Is there a way to use non-English characters?

I am using SageMath 8.5 on a MacBook Pro with macOS High Sierra.

edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted
1

answered 2019-02-17 17:23:56 -0500

Emmanuel Charpentier gravatar image

"Strange characters" : this is a well-known Python snag...

In Python 2, current base, there is a distinction between strings (which are encoded in whatever your source fine is encoded into) and UTF_8 strings. See the Python documentation for discussion.

Check that you use utf8 strings, e. g. u"Solución".

Sage should use UTF-8 in any case, but maybe you are working on a file inadvertently encoded in, say, Latin1 ?

In the (forthcoming) Python3-based Sage, these distinctions should disappear...

An alternative in the Jupyter notebook : you can use display_typeset to get all your output processed by Mathjax.

edit flag offensive delete link more

Comments

Many thanks for your answer. I was aware of %display latex . It seems that typeset is a synonym of latex. Unfortunately, since MathJax only typesets maths, it does not help if the output also contains text. Anyway, while digging in HTML for a different question,I have found a simple workaround: to use the HTML code of the conflicting characters. This works:

limit = r"\displaystyle\lim_{x\to0}\frac{\sin x}{x}="
value = lim(sin(x)/x, x=0)
show(html("Solución: "+"${}={}$".format(limit,value)))
Juanjo gravatar imageJuanjo ( 2019-02-17 19:35:54 -0500 )edit

A function generating the HTML representation of an UTF-8 string probably exists in the zillions of available Python libraries. You could try to pip install one of them and import it in Sage, no ?

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2019-02-18 01:21:50 -0500 )edit

No need necessarily for a non-standard library. On Python 2 you can do:

>>> u'Solución'.encode('ascii', 'xmlcharrefreplace')
'Solución'

Of course in this case you just get a hex escape instead of the more readable entity name, which is not ideal. I think there are ways to get entity name conversions as well. Regardless this shouldn't usually even be necessary, but as you wrote unicode will be handled better in Python 3 across the board.

Iguananaut gravatar imageIguananaut ( 2019-02-18 05:04:30 -0500 )edit

Many thanks for your suggestion. Yes, I could do so in my own computer. But the notebook should run in university or students' computers, which I cannot configure. However, I could include such a function in the notebook. As a proof of concept, I could define

def html_fy(string):
    html_code={"á":"á", "é":"é", "í":"í", 
               "ó":"ó", "ú": "ú"}
    for letter in html_code.keys():
        if letter in string:
            string=string.replace(letter,html_code[letter])
    return string
Juanjo gravatar imageJuanjo ( 2019-02-18 05:42:45 -0500 )edit

And then write

text = html_fy("Solución válida: ")
limit = r"\displaystyle\lim_{x\to0}\frac{\sin x}{x}"
value = lim(sin(x)/x, x=0)
show(html(text+"${}={}$".format(limit,value)))

which provides exactly the kind of output I was seeking for.

Juanjo gravatar imageJuanjo ( 2019-02-18 05:43:15 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-02-17 10:00:45 -0500

Seen: 170 times

Last updated: Feb 17