Anyone using pythontex to generate values for questions?

Added by Luís Sequeira over 6 years ago

As you may well know, pythontex allows one to use python code in latex documents.
I would very much like to use it within AMC - an obvious example is generating random values to use in questions.
For an example, instead of

\begin{question}{q}
What is $2+4$
\end{question}

one can have 2 and 4 replaced by other values, e.g.,

\begin{pycode}
import random
a=random.choice([2,3,4,5,6])
b=random.choice([3,5,7,9,11])
\end{pycode}

\begin{question}{q}
What is $\py{a}+\py{b}$
\end{question}

That by and large is working.

The answers might look like this:

\begin{choices}
\wrongchoice{\py{a+b+1}}
\correctchoice{\py{a+b}}
\end{choices}

Nice, right? The problem is that, although the values appearing in the question do vary, in a reasonable pseudo-random way,
the values showing up in the choices are all over the place.

The problem seems to that the values of variables (a and b in the example) used for evaluating the answers do not match the values in question.
Even more strangely, the values of a not always match between two answers in the same instance, e.g. putting two equal answers like

\wrongchoice{\py{a}}
\wrongchoice{\py{a}}

may show two different values!

Any ideas?

TIA


Replies (10)

RE: Anyone using pythontex to generate values for questions? - Added by Alexis Bienvenüe over 6 years ago

Can you join a minimal (as simple/short as possible) sample tex source file?

RE: Anyone using pythontex to generate values for questions? - Added by Luís Sequeira over 6 years ago

Thank you so much for your reply!

A minimal example is always a great idea...

I took the example I was working with, and was reducing it to provide a minimal one (one question, and no extra embelishments) when suddenly, lo and behold, I was able to figured it out. It is working now! Below I explain how I see the problem and the solution.

Pythontex provides a number of latex commands and corresponding environments - for example one can in principle use
\pyc{...} or \begin{pycode} ... \end{pycode}

The crucial lesson for me is this: in the context of AMC questions and choices, always use the commands, and not the environments.
Using only \pyc{...} for running python code and \py{...} when using python expression values in the document WORKS perfectly.

For completeness, I do enclose a minimal example, but one that works successfully - in the hope that this is useful to someone coming across this question.

Again, thank YOU! It was the cleaning up necessary to produce a minimal example that led me to the right path!

minimal.tex - a small file to illustrate using pythontex together with AMC (881 Bytes)

RE: Anyone using pythontex to generate values for questions? - Added by Matthew Leingang over 6 years ago

This is pretty sweet. I was going to suggest using luatex for embedding scripting into a TeX file, since that's the most portable thing. But I love python so I will check this out.

One thing: is the pythonxelatex engine distributed with TeXShop? Or did you write it yourself?

RE: Anyone using pythontex to generate values for questions? - Added by Luís Sequeira over 6 years ago

If I remember correctly, to do this script pythonxelatex I took an existing "engine" (as TeXShop calls these scripts) pythontex.engine
and slightly modified it. Not complicated to do. I can send you the script I am using if you like.

I am sorry but in fact lualatex may be a better choice, if you are fluent in lua.

I ended up using pythontex because I am much more familiar with python, but I have to say I had to use a roundabout way to do it.

I had no trouble typesetting AMC in TeXShop using pythontex to generate many questions with variable parameters and it seemed it would work nicely.

However, when trying to finalize my tests by using AMC to do the typesetting and all the other things that have to go on behind the scenes I kept hitting a wall. The problem is that AMC uses the source latex document to produce several pdf documents and keep track of everything. We can change the script but running it several times with randomized parameters out of python code creates a mess.

So my roundabout way was to make a small python program to "depythonize" questions, generating multiple versions of each question where python variables appeared (e.g. if there are variables a and b, with a taking values 1-10 and b taking 5,6 generate all or some of the twenty possible combinations as separate questions, complete with different names for each question, as required by AMC).

I got it to work well enough for myself, but it is a kludge.

RE: Anyone using pythontex to generate values for questions? - Added by Matthew Leingang over 6 years ago

Can you just upload the engine script to this thread (for completeness, not just for my own sake)?

I'm not fluent in lua, which is why I'm intrigued by the pythontex approach. Plus, once you get python, you can use all of its packages, including perhaps SymPy for symbolic math.

Regarding the wall you hit: did you try hardcoding the random seed in your source file? I use both \AMCrandomseed and \pgfmathsetseed in my preamble to set it to the same number. THAT number I create either by running a python one-liner or getting a value from random.org (both of these are linked to TextExpander key combinations).

RE: Anyone using pythontex to generate values for questions? - Added by Alexis Bienvenüe over 6 years ago

We can change the script but running it several times with randomized parameters out of python code creates a mess.

Is this only because two different runs of pythontex leads to different values of the random parameters? If so, maybe this could be fixed fixing the seed value for the python random generator, with something like random.seed(123456) once at the beginning of the source file (outside \onecopy).

RE: Anyone using pythontex to generate values for questions? - Added by Luís Sequeira over 6 years ago

Ok, see below, between the dashed lines is the script I use to typeset using xelatex and pythontex
Changes from the original TeXShop engine:
1) call xelatex instead of pdflatex; adjusted some of the parameters of xelatex
2) used anaconda's installation of python, so uncommented respective line and adjusted the path (you need to adjust according to where anaconda is on your system; or comment it out and uncomment the line for the system python distribution)

--------------------------------------
#!/bin/bash

  1. For anaconda distribution of Python, use
    PATH=/Users/me/anaconda/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/Library/TEX/texbin:/opt/local/bin
    export PATH
  1. For system distribution of Python, use
    #PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/Library/TEX/texbin

filename=$1

xelatex -8bit --shell-escape --file-line-error --synctex=1 $*

pythontex --interpreter python:python3 $*

xelatex -8bit --shell-escape --file-line-error --synctex=1 $*


RE: Anyone using pythontex to generate values for questions? - Added by Luís Sequeira over 6 years ago

Is this only because two different runs of pythontex leads to different values of the random parameters? If so, maybe this could be fixed fixing the seed value for the python random generator, with something like random.seed(123456) once at the beginning of the source file (outside \onecopy).

This is a great suggestion, but it is not just that.
It may be my own limitation, but the thing is in the above script both xelatex and pythontex receive all the parameters that are passed to the script.
This works fine in TeXShop, where $* is just the name of the source file.
In AMC, the command line arguments are more complex (and I understand that they have to be, to set \jobname and stuff for what AMC needs to do to create Catalog, Sujet, ...).

The problem is that pythontex does not seem to understand these more complex command lines (of course, they are no problem for xelatex).

To put it in a more visual way:

pythonxelatex myfile

works fine, but

pythonxelatex --jobname=amc-compiled \nonstopmode\def\SujetExterne{1}\def\AMCNombreCopies{3}\def\NoHyperRef{1}\def\NoWatermarkExterne{1} \input{"simple.tex"}

does not because pythontex doesn't know what to do with it.

(1-10/10)