4

The sagetex documentation (S. 5) says

Also keep in mind that everything you send to Sage is done within one Sage  session. This 
means you can define variables and reuse them throughout your LaTeX document; if you tell 
Sage that `foo` is 12, then anytime afterwards you can use `foo` in your Sage code and Sage will 
remember that it's 12, just like in a regular Sage session

When I do

a = 12
a-2

in sage 6.3 it displays 12. A document with

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{sagetex}

\begin{document}
\sage{12-2}
\end{document}

creates a PDF with 10 as content (when compiled with pdflatex; sage filename.sagetex.sage && pdflatex), but a document named sagetex_variable_reuse

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{sagetex}

\begin{document}
\sage{a = 12}
\sage{a-2}
\end{document}

Fails with

$ sage sagetex_variable_reuse.sagetex.sage 
Processing Sage code for sagetex_variable_reuse.tex...

**** Error in Sage code on line 6 of sagetex_variable_reuse.tex! Traceback  follows.
Traceback (most recent call last):
  File "sagetex_variable_reuse.sagetex.py", line 8, in <module>
    _st_.inline(_sage_const_0 , latex(a = _sage_const_12 ))
TypeError: __call__() got an unexpected keyword argument 'a'

**** Running Sage on sagetex_variable_reuse.sage failed! Fix sagetex_variable_reuse.tex and try again.

I can now imagine another interpretation of what I cited, so I'd like to get it here or a confirmation that this is a bug. How to save a numeric value after calculation (logical) or assignment in one \sage statement and reuse it in another?


Werner
  • 603,163

2 Answers2

7

There's two issues with your document. The sagetex package lets you do numerical calculations such as \sage{3*5} on the fly but not variable assignments such as \sage{a=12}. If you read further in the documentation it says, "If you have defined the Sage variable foo to be 12 (using, say, the sageblock environment),....". In general, assignments should be done in the sagesilent environment, out of sight of the user. The second issue is that your answer is numerical and needs to be put into your document between dollar signs. Here's an example to illustrate some of these issues:

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
a = 12
MyString = r"This is interesting"
\end{sagesilent}
We can do numerical calculations with Sage, such as 
${5 \choose 2}=\sage{binomial(6,3)}$  whenever we want but 
whenever we are assigning values to variables it should be done 
in the sagesilent environment if you don't want people to see the
work and sageblock if you want them to see the work. After
that, you can do your calculations.
The value of $\sage{a}-2=\sage{a-2}$.
With the variables 
\begin{sageblock}
a = 15
b = 2
\end{sageblock}
The value of $a-b=\sage{a-b}$.\\
The value of $\sage{a}-\sage{b}=\sage{a-b}$.
This is text output:
\sagestr{MyString}
\end{document}

The output: enter image description here

You can see how sageblock puts your work in the document and sagesilent doesn't. Note that inserting a string into the document does not involve math mode so no dollar signs are used.

DJP
  • 12,451
  • Your statement "The sagetex package lets you do numerical calculations on the fly but not variable assignments." is...interesting, considering that you proceed to very nicely demonstrate precisely how to assign values to variables. The \sage macro cannot handle a variable assignment because, in Python, that's a statement, but \sage can only handle an expression. – Dan Drake Aug 24 '15 at 03:02
  • 1
    By "The sagetex package lets you do numerical calculations on the fly but not variable assignments", I meant that \sage{3*5} is is fine but \sage{a=12} isn't. Hence I assigned variable in the sagesilent environment before working with \sage{a}. – DJP Aug 24 '15 at 23:06
  • Ah, now I see. It would be better to say "the \sage{} macro lets you do..."; I was confused because \sage{] is part of the sagetex package. – Dan Drake Aug 25 '15 at 01:26
  • I edited my post to make it clear. – DJP Aug 25 '15 at 03:03
  • If I have a macro \myvalue with value of 3 defined before sagesilent. When I write inside sagesilent environment f(x) = \myvalue * x, I get an error of undefined name myvalue. So, how to fix this by making sagetex recognize all the macros known in the tex memory? Sorry for asking here! – Diaa Mar 16 '22 at 17:25
  • It's not really clear to me how you're using f(x) (such as plotting or trying to generate values). I don't mix TeX and Sage variables so I don't know for sure about what sagetex recognizes. The documentation, halfway down on page 6, gives an example. I've managed to work with combining them by not using f(x)=\myvalue*x but instead using \myvalue*x as needed. So: I think you can use any macro in sagetex. – DJP Mar 16 '22 at 21:40
1

In the source of sagetex.py is the function that evaluates \sage commands:

def inline(self, counter, s):
  self.progress('Inline formula %s' % counter)
  self.souttmp.write('\\newlabel{@sageinline' + str(counter) + '}{{' + \
               latex(s).rstrip() + '}{}{}{}{}}\n')

This assumes an argument that may be evaluated to a string, rather than an assignment. s is the literal argument of the \sage command (literal, not quoted as a string).

Having a command for assigning would involve a new command that would function like the sagesilent environment. I don't have Sage installed, but something like this should work. You can add it to the preamble after loading sagetex.

\makeatletter
\newcommand{\sageslnt}[1]{\ST@wsf{%
try:^^J
 _st_.progress('Inline assignment')^^J
 #1^^Jexcept:^^J
 _st_.goboom(\the\inputlineno)}}
\makeatother

It might be possible to create a single command to handle both cases, but that could be tricky.

G. Poore
  • 12,417
  • This is completely unnecessary; there is already the sageblock and sagesilent environments. I'm surprised you looked through the documentation, wrote the above, and never noticed those environments! – Dan Drake Aug 24 '15 at 03:04