pythontex
pythontex copied to clipboard
How to share variables between pyconsole and pyblock?
I read the documentation, and I suppose this sounds strange, but I want to have python variables shared between the pyconsole and pyblock families.
Is this possible?
Not that I'm using the v0.12 version which came with texlive on my ubuntu box.
Thanks
That's not currently possible, and would actually be difficult to implement since pyconsole is executed via Python's code
module (emulate console) while pyblock is treated as a script. If you can give me an idea of what you are trying to do, I might have some ideas. Also, if you haven't looked at the \pyconc
command and pyconcode
environment (execute console code without showing anything) and the \pycon
command (get console output without showing input), those might help.
If you just want shared startup code between the two, along the lines of pythontexcustomcode
, that should be doable.
What I'm trying to do is talk about a function in a module and then illustrate the use of that function in a console. For example
\begin{pyblock}
def foo(x):
return 2*x
\end{pyblock}
And this is how you use the function,
\begin{pyconsole}
x = 10
foo(x)
\end{pyconsole}
I hope that makes sense. I understand the narrative structure I'm going for is a little bit outside of the design plan of PythonTeX. The problem with your suggestion of using the pyconcode environment is that it results in a lot of duplicated code (one block to be typeset and the other not), which would make it hard for me to maintain as I develop the narrative.
Thanks again
Something like this should do what you want. This creates a pyconcodeblock
environment using fancyvrb
's VerbatimOut
. pyconcodeblock
saves its contents to a temp file. Then this code is brought into the console session and is also typeset. Note that the code is not brought into the default non-console session, so it is not accessible in pycode
etc. But if you needed that, you could use the same exec
trick with \pyc
.
\documentclass{article}
\usepackage{pythontex}
\newenvironment{pyconcodeblock}%
{\VerbatimEnvironment
\begin{VerbatimOut}{temp.py}}%
{\end{VerbatimOut}%
\pyconc{exec(compile(open('temp.py', 'rb').read(), 'temp.py', 'exec'))}%
\inputpygments{python}{temp.py}}
\begin{document}
\begin{pyconcodeblock}
def foo(x):
return 2*x
\end{pyconcodeblock}
\begin{pyconsole}
x = 10
foo(x)
\end{pyconsole}
\end{document}
Could we/you consider a de-coupling of typesetting (display) and execution? Something like: \begin[show=[true, false, console], execute=[true, false], session=mysession]{pythontex} \end{pythontex} where all combinations of show and execute is legal (where show=false, execute=false is a wierd way of commenting it out, so maybe a warning?).
In addition to a similar function to grab code from an external file, with optional, start_line and end_line arguments.
I have been using pythontex since the start, and the current environment setup still confuses me (I always need to look it up).
On 06 Feb 2015, at 21:05, Geoffrey Poore [email protected] wrote:
Something like this should do what you want. This creates a pyconcodeblock environment using fancyvrb's VerbatimOut. pyconcodeblock saves its contents to a temp file. Then this code is brought into the console session and is also typeset. Note that the code is not brought into the default non-console session, so it is not accessible in pycode etc. But if you needed that, you could use the same exec trick with \pyc.
\documentclass {article}
\usepackage {pythontex}
\newenvironment{pyconcodeblock}%
{ \VerbatimEnvironment
\begin{VerbatimOut}{temp.py}}%
{ \end{VerbatimOut}%
\pyconc{exec(compile(open('temp.py', 'rb').read(), 'temp.py', 'exec'))}%
\inputpygments {python}{temp.py}}
\begin {document}
\begin {pyconcodeblock} def foo(x): return 2*x
\end {pyconcodeblock}
\begin {pyconsole} x = 10 foo(x)
\end {pyconsole}
\end{document} � Reply to this email directly or view it on GitHub.
@obtitus That's something I would like to do soon. About 2 years ago, I wrote up a list of future features. A generic environment like you describe, and per-session customization for execution conditions, are the main things that remain to be implemented from that list.
I would want a switch for showing code and for showing stdout and/or stderr. And, like you suggest, for turning execution on and off. I'm not sure about show=console
, though. With the current implementation, code is executed either as a script or via the code
module's console emulation. In principle, it should be possible to go in and out of console mode. But I'm guessing that that would require a highly customized version of the code
module.
I've opened a new issue for this (#56), for continued discussion. I will try to post my old notes on this under that issue soon.
I am afraid, this workaround does not work for me. The example above yields the following error:
---- Messages for pycon:default:default ----
* PythonTeX stderr - error near line 17 in console code:
Console code is not typeset, and should have no output
>>> exec(compile(open('temp.py', 'rb').read(), 'temp.py', 'exec'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'temp.py'
--------------------------------------------------
PythonTeX: test - 1 error(s), 0 warning(s)
I am using XeLaTeX invoked with xelatex test && /usr/local/texlive/2014/texmf-dist/scripts/pythontex/pythontex.py test && xelatex test && xelatex test
and PythonTeX v0.13 is used here.
XeTeX 3.14159265-2.6-0.99991 (TeX Live 2014)
kpathsea version 6.2.0
Copyright 2014 SIL International, Jonathan Kew and Khaled Hosny.
There is NO warranty. Redistribution of this software is
covered by the terms of both the XeTeX copyright and
the Lesser GNU General Public License.
For more information about these matters, see the file
named COPYING and the XeTeX source.
Primary author of XeTeX: Jonathan Kew.
Compiled with ICU version 53.1; using 53.1
Compiled with zlib version 1.2.8; using 1.2.8
Compiled with FreeType2 version 2.5.3; using 2.5.3
Compiled with Graphite2 version 1.2.4; using 1.2.4
Compiled with HarfBuzz version 0.9.28; using 0.9.28
Compiled with libpng version 1.6.10; using 1.6.10
Compiled with poppler version 0.25.2
Compiled with fontconfig version 2.11.1; using 2.11.0
The following file structure is created:
% find .
.
./test.pdf
./test.log
./pythontex-files-test
./pythontex-files-test/test.pytxmcr
./pythontex-files-test/pythontex_data.pkl
./pythontex-files-test/test.pytxpyg
./test.tex
./test.pytxcode
./test.aux
./temp.py
If I fix the workaround to with
\inputpygments{python}{../temp.py}}
instead of
\inputpygments{python}{temp.py}}
I get
Output written on test.pdf (1 page).
Transcript written on test.log.
This is PythonTeX v0.13
Traceback (most recent call last):
File "/usr/local/texlive/2014/texmf-dist/scripts/pythontex/pythontex.py", line 62, in <module>
pythontex.main()
File "/usr/local/texlive/2014/texmf-dist/scripts/pythontex/pythontex2.py", line 2607, in main
do_multiprocessing(data, temp_data, old_data, engine_dict)
File "/usr/local/texlive/2014/texmf-dist/scripts/pythontex/pythontex2.py", line 1329, in do_multiprocessing
result = task.get()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
raise self._value
AttributeError: 'NoneType' object has no attribute 'decode'
Any ideas?
@meisterluk Starting in PythonTeX version 0.14, the default working directory is the document root directory, rather that the pythontex-files*
directory (since that was causing too much confusion). The above code assumes this for working with the path to temp.py
. If you add \setpythontexworkingdir{.}
to the preamble of the example, right after loading pythontex
, the example should work as-is with PythonTeX 0.13.
Otherwise, you would need to modify the paths in the exec()
to get everything to work. Probably something like this:
\newenvironment{pyconcodeblock}%
{\VerbatimEnvironment
\begin{VerbatimOut}{temp.py}}%
{\end{VerbatimOut}%
\pyconc{exec(compile(open('../temp.py', 'rb').read(), '../temp.py', 'exec'))}%
\inputpygments{python}{temp.py}}
@gpoore The \setpythontexworkingdir{.}
fix works perfectly fine for me. Thank you :-)
@gpoore Your pyconcodeblock
environment works perfectly. However, I wanted to execute some code (which defines a function), use it in a pyconsole
, and only later typeset it (this is a book with exercises that illustrate the usage of a function, and only later explain how to write it). Furthermore I need to do this multiple times. I tried using a variation on what you wrote along the following lines (the idea is that rather than writing to a file called temp.py
, this can specified by a parameter to the environment):
\newenvironment{pyconcodeblock}[1]%
{\VerbatimEnvironment
\begin{VerbatimOut}{#1.py}}%
{\end{VerbatimOut}%
\pyconc{exec(compile(open('#1.py', 'rb').read(), '#1.py', 'exec'))}}
but the above generates errors (Illegal parameter number in definition of \pytx@argdetok. \end{pyconcodeblock}
).
Does anyone have any advice on how to parametrize (with the filename) @gpoore's solution?
@banbh Environment arguments are only available at the beginning of the environment, not at the end. You will probably want to store #1
in a temp macro, and then use that at the end of the environment. More details.
@gpoore Thank you. I read through the tex.stackexchange
answer, which was very helpful. Here is my new attempt:
\newenvironment{pyconcodeblck}[1]%
{\newcommand{\snippetfile}{#1.py}
\VerbatimEnvironment
\begin{VerbatimOut}{\snippetfile}}%
{\end{VerbatimOut}%
\pyconc{exec(compile(open('\snippetfile', 'rb').read(), '\snippetfile', 'exec'))}}
But now I have a new problem. It seems that the macro does not get expanded in the \pyconc
call. When I run pythontex main
(my latex file is main.tex
) I get
This is PythonTeX 0.14
---- Messages for pycon:default:default ----
* PythonTeX stderr - error near line 65 in console code:
Console code is not typeset, and should have no output
>>> exec(compile(open('\snippetfile ', 'rb').read(), '\snippetfile ', 'exec'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: '\\snippetfile '
--------------------------------------------------
PythonTeX: main - 1 error(s), 0 warning(s)
Any suggestions on how to get macro-expansion to happen?
@banbh All of the commands like \pyconc
take literal arguments, so you will have to do the expansion beforehand. You can try something like this (untested).
\newcommand{\expandpyconc}[1]{\expandafter\reallyexpandpyconc\expandafter{#1}}
\newcommand{\reallyexpandpyconc}[1]{\pyconc{exec(compile(open('#1', 'rb').read(), '#1', 'exec'))}}
...
{\end{VerbatimOut}%
\expandpyconc{\snippetfile}}
@gpoore Thank you! It works perfectly. I will post a MWE example in a day or two.
Here is a more-or-less MWE of the macros @gpoore proposed:
\documentclass{article}
\usepackage{pythontex}
\newcommand{\expandpyconc}[1]{\expandafter\reallyexpandpyconc\expandafter{#1}}
\newcommand{\reallyexpandpyconc}[1]{\pyconc{exec(compile(open('#1', 'rb').read(), '#1', 'exec'))}}
\newenvironment{pyconcodeblck}[1]%
{\newcommand{\snippetfile}{snippet-#1.py}
\VerbatimEnvironment
\begin{VerbatimOut}{\snippetfile}}%
{\end{VerbatimOut}%
\expandpyconc{\snippetfile}}
\newcommand{\typesetcode}[1]{\inputpygments{python}{snippet-#1.py}}
\begin{pyconcodeblck}{temp}
def foo(x):
return 2*x
\end{pyconcodeblck}
\begin{pyconcodeblck}{temp2}
def foobar(x):
return foo(foo(x))
\end{pyconcodeblck}
\begin{document}
Here is an example of some functions:
\begin{pyconsole}
foo(10)
foobar(10)
\end{pyconsole}
Here is foo:
\typesetcode{temp}
And here is foobar:
\typesetcode{temp2}
\end{document}
It works perfectly for me.
Hello.
First, thank you very much for your answers on this topic.
In the context of a beamer use of pyconcodeblock, I would like to now if there is a way to box the blocks produced by this function (or pyconc). I was not able to find such a way in the PythonTex manual.
Thank you in advance for your help.
@cccccp There isn't a built-in way to put boxes around the console commands and environments. But you can use the tcolorbox
package or other framing packages to put boxes around environments, and \fcolorbox
etc. for commands.