PythonTex


Le yeti explorateur de mathématique et d'informatique. yeti

PythonTex est un package qui permet d'executer du code python à l'intérieur d'un fichier .tex

Le fichier obtenu après compilation contiendra les sorties obtenues avec python qui seront insérées dans votre document LaTeX.

Le dépôt à été mis à jour en 2017 :

La combinaison de LaTeX et de python permet d'automatiser certaines taches (et d'éviter les erreurs) :

  • Le calcul d'une valeur approchée
  • Le développement d'une expression algébrique en utilisant le module sympy
  • La récupération des sorties (des variables ?) d'un algorithme
  • etc ...

Dans la suite de l'article je vais montrer les usages que j'ai testé ainsi qu'une configuration possible

Voici un premier fichier .tex.

L'appel du package se fait ligne 9 par \usepackage{pythontex}. Le package est  à installer dans votre distribution de LaTeX préférée.

Le calcul de 1+1 se fait grâce à python par l'instruction \py{1+1}  à la ligne 14.

Vous pouvez constater que le résultat est affiché dans le document produit.

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
% Appel du package pythontex 
\usepackage{pythontex}
%
\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Pour s'échauffer :}
$1+1 = $ \py{1+1}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

Second exemple, cette fois avec des calculs plus complexes.

Lignes 11 et 12 le code permet de remplacer le par la  dans le mode mathématique.

Ligne 26, l'environnement pycode  permet d'éxecuter du code python sans afficher de résultat dans le pdf. Cela permet, par exemple, d'appeler des modules supplémentaires, ici le module sqrt.

Il est possible aussi de manipuler des variables. Elle peuvent être affectées dans un environnement pycode puis utilisées dans des calculs plus loin dans le fichier .tex.

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
% Appel du package pythontex 
\usepackage{pythontex}
%
\usepackage[output-decimal-marker={,}]{siunitx} % Pour transformer le .  en virgule decimale en mode maths
\mathcode`\.="013B

\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Pour s'échauffer :}
$1+1 = $ \py{1+1}

\section{Aller on essaye !} \noindent
Respect des priorités :  $1 + 2 \times 10 = $ \py{1+2*10} \\
Et les fractions ? $\frac{1}{3} + \frac{1}{2} \approx \py{1/3+1/2}$ \\
Et les racines carrées ? 
%
% Il faut un module supplémtaire :  appellons le avec l'environnement pycode
%
\begin{pycode}
from math import sqrt
\end{pycode}
%
$$\sqrt{2} \approx  \py{ sqrt(2) } $$
%
% Avec pycode il est possible de définir des variables utilisables dans tout le document
% comme avec des variables globales
\begin{pycode}
a=2
b=5
\end{pycode}
%
Les variables : si $a=2$ et $b=5$ alors $a \times b = $ \py{a*b}

\section{Un peu plus loin ...}\noindent
La division euclidienne de $3551$ par $7$ : le quotient est $\py{3551//7}$ et le reste est 
$\py{3551%7}$  \\
Vérification : $507 \times 7 + 2 = \py{507 * 7 + 2}$

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

Un des avantages de ce package est de profiter d'outils avancés pour le calcul littéral sans avoir besoin de "sortir" du fichier .tex

Pour ma part j'utilise le package (python) sympy pour le calcul littéral. Vers sympy

Je me suis retrouvé bloqué pour l'usage de la fonction $\exp$ . Cela venait d'un conflit entre la fonction du package maths et la fonction du package python. Pour régler le problème il suffit de charger sympy comme ceci :

\begin{pycode}
import sympy
\end{pycode}

et d'utiliser sympy.exp lors de l'appel à la fonction $\exp$.

Ci-dessous un exemple d'utilisation :

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
% Appel du package pythontex 
\usepackage{pythontex}
%

\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{pycode}
from sympy import *
x, y = symbols('x y')
\end{pycode}

\section{Développements, factorisations...} \noindent
Voici une expression : $$x(x + 2y)$$
\begin{pycode}
exp = x*(x + 2*y)
dev_exp = expand(exp)
\end{pycode}
Sympy produit l'expression développée $\py{dev_exp}$ \\
C'est déjà pas mal mais , on peut rendre ça plus joli : $\py{latex(dev_exp)}$\\
Sympy peut aussi factoriser : $x^2-8x+15 = \py{latex(factor(x**2-8*x+15))}$\\


\section{Fractions}
La gestion des nombres rationnels va passer par l'utilisation de la classe Rational.\\
Rational(1,2) produit la fraction $\frac{1}{2}$ et permet de faire des calculs. (additions de fractions ...). Il est possible de raccourcir le code d'appel de la classe Rational avec "R = Rational" :
\begin{pycode}
R = Rational
a=R(1,2)
b=R(1,3)
c=R(1,4)
\end{pycode}

$$\frac{1}{2}+\frac{1}{3}+\frac{1}{4} = \py{latex(a+b+c)}$$

Les fractions avec des lettres ne posent pas de problèmes particuliers.
\begin{pycode}
exp = 1/( (x+2)*(x+1) )
\end{pycode}
\begin{center}
$\frac{1}{(x+2)(x+1)}$ = $\py{latex(apart(exp, x))}$
\end{center}
\begin{pycode}
expr = 1/x + (3*x/2 - 2)/(x - 4)
\end{pycode}
\begin{center}
$\frac{1}{x} + \frac{\frac{3x}{2}}{x-4}$ = $\py{latex(cancel(exp))}$
\end{center}


\section{Limites, dérivées, intégrales ...}\noindent
Ce genre de problème est d'une facilité déconcertante :\\ 
La dérivée de la fonction définie par $\cos(x)$ est : $\py{latex(diff(cos(x), x))}$\\
La dérivée de la fonction définie par $\ln(x^2)$ est : $\py{latex(diff(ln(x**2), x))}$\\
Une primitive de la fonction définie par $\cos(x)$ est : $\py{latex(integrate(cos(x), x))}$\\
La limite de la fonction $\frac{ln(x)}{x}$ en $+\infty$ est : $\py{latex(limit(ln(x)/x, x, oo))}$\\
La limite de la fonction $\frac{1}{x}$ en $0^{+}$ est : $\py{latex(limit(1/x, x, 0, '+'))}$\\[0.5em]
La limite de la fonction $\frac{1}{x}$ en $0^{-}$ est : $\py{latex(limit(1/x, x, 0, '-'))}$\\
\begin{pycode}
import sympy
expr = sympy.exp(sin(x))
\end{pycode}
% Pour utiliser la fonction exponentielle il faut utiliser symp.exp , sinon la fonction entre en conflit avec la fonction exp du package Maths
Développement en série de la fonction $\exp(\sin(x))$ en $x=0$ de rang 4 : 
$\py{latex(expr.series(x, 0, 4))}$\\
L'intégrale $\int_{-\infty}^{+\infty}\int_{-\infty}^{+\infty} \exp(-x^2-y^2) \text{d}x\text{d}y$ vaut : $\py{
latex( integrate(sympy.exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo)) )}$
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

Un des énormes avantage, surtout à l'heure de l'entrée du codage en classe de seconde, est de pouvoir éxécuter du code directement dans LaTeX.

J'ai testé l'usage de variables, boucles et fonctions .

Cerise sur le gateau ! L'environnement \begin{pyconsole} ... \end{pyconsole} permet d'afficher le résultat comme si l'on utilisait IDLE.

Voir l'exemple ci-dessous :

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
% Appel du package pythontex 
\usepackage{pythontex}
%

\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Variables} \noindent
L'environnement pyconsole permet d'afficher le résultat comme dans IDLE !
\begin{pyconsole}
var = 1 + 1
var
\end{pyconsole}

Travail avec les chaines  de caractères :
\begin{pyconsole}
text = 'Salut tout le monde'
text.upper()
print(text[0:5])
print(len(text))
text.replace('Salut','Bonjour')
\end{pyconsole}

Travail avec les listes :
\begin{pyconsole}
noms = ['Joe','Jack','William','Averell']
noms[1]
noms.append('Joseph')
print(noms)
sorted(noms)
import random
noms[random.randint(0,4)]
\end{pyconsole}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

Un des énormes avantage, surtout à l'heure de l'entrée du codage en classe de seconde, est de pouvoir éxécuter du code directement dans LaTeX.

J'ai testé l'usage de variables, boucles et fonctions .

L'environnement \begin{pyverbatim} ... \end{pyverbatim} permet d'afficher le code sans que celui-ci soit interprété.

Voir l'exemple ci-dessous :

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
% Appel du package pythontex 
\usepackage{pythontex}
%

\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Les boucles} \noindent
\subsection{Une boucle "pour" (for pour les anglicistes)}

\begin{pyverbatim}
for i in range(10):
	print(i)	
\end{pyverbatim}


\begin{pycode}
for i in range(10):
	print(i)
	
\end{pycode}


\subsection{Une boucle si (if) :} 

\begin{pyverbatim}
note = 15
if note == 0.0:
    print("C'est en dessous de la moyenne")
    print("... lamentable !")
elif note == 20.0:
    print("J'ai la moyenne")
    print("C'est même excellent !")
elif note < 10.0 and note > 0.0:	# ou bien : elif 0.0 < note < 10.0:
    print("C'est en dessous de la moyenne")
elif note >= 10.0 and note < 20.0:	# ou bien : elif 10.0 <= note < 20.0:
    print("J'ai la moyenne")
else:
    print("Note invalide !")
print("Fin du programme")
\end{pyverbatim}

\begin{pycode}
note = 15
if note == 0.0:
    print("C'est en dessous de la moyenne")
    print("... lamentable !")
elif note == 20.0:
    print("J'ai la moyenne")
    print("C'est même excellent !")
elif note < 10.0 and note > 0.0:	# ou bien : elif 0.0 < note < 10.0:
    print("C'est en dessous de la moyenne")
elif note >= 10.0 and note < 20.0:	# ou bien : elif 10.0 <= note < 20.0:
    print("J'ai la moyenne")
else:
    print("Note invalide !")
print("-- Fin du programme")
\end{pycode}

\subsection{Une boucle tant que :}

\begin{pyverbatim}
table = 0
while table <= 90:
	table = table + 9
	print(table)
	
print('Fin de la table de 9')
\end{pyverbatim}

\begin{pycode}
table = 0
while table <= 90:
	table = table + 9
	print(table)
	
print('-- Fin de la table de 9')
\end{pycode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
% Appel du package pythontex 
\usepackage{pythontex}
%

\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Les fonctions} 

Définir et utiliser une fonction dans pythontex est on ne peut plus simple :

\subsection{La fonction carré :}

\begin{pyverbatim}
def f(exp):
	return exp**2

print(f(-2))
\end{pyverbatim}

\begin{pycode}
def f(exp):
	return exp**2

print(f(-2))
\end{pycode}

\subsection{La fonction salutation:}

\begin{pyverbatim}
def Salutation(nom):
	print(r"Bonjour %s " %nom)
	
Salutation('Léo') 
Salutation('Laura')
Salutation('Louise')
\end{pyverbatim}

\begin{pycode}
def Salutation(nom):
	print(r"Bonjour %s " %nom)
	
Salutation('Léo') 
Salutation('Laura')
Salutation('Louise')
\end{pycode}

\subsection{Le fameux algorithme d'Euclide.}

\begin{pyverbatim}
def pgcd(a,b) : 
	while a%b != 0:
		a, b = b, a%b
	return b

print(pgcd(57,21))
\end{pyverbatim}

\begin{pycode}
def pgcd(a,b) : 
	while a%b != 0:
		a, b = b, a%b
	return b

print(pgcd(57,21))
\end{pycode}

\subsection{Toujours Euclide mais avec un 'bel' affichage.}
\noindent
\begin{pycode}
def pgcd(a,b) : 
	
	a0,b0,i=a,b,1
	while a%b != 0:
		a, b = b, a%b
		print(r"Etape n°%d : a = %d et b = %d \\" %(i,a,b))
		i = i+1
	print(r"Le PGCD de %d et %d est %d" %(a0,b0,b))
	return b

pgcd(57,21)
\end{pycode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

J'utilise TexMaker pour mes documents LaTeX. Si vous ne le connaissez pas je vous encourage à le découvrir. Ce logiciel permet en particulier de créer des "commandes utilisateur". Pensez à créer vos documents en UTF-8 pour assurer la compatibilité avec pythontex.

En particulier je m'en suis servit pour faire une commande PythonTex.

En effet pour que PythonTex fonctionne il faut lancer pdfLatex puis le script pythontex puis encore pdfLatex.

Sur mon PC voici la ligne de commande :

pdflatex --shell-escape -synctex=1 -interaction=nonstopmode %.tex|python E:\texlive\2014\texmf-dist\scripts\pythontex\pythontex.py %.tex|pdflatex --shell-escape -synctex=1 -interaction=nonstopmode %.tex

Il faut que python soit dans le PATH de votre ordinateur. Les dernières versions de python vous proposent de le faire dès l'installation ('je vous le recommande').

Une fois TexMaker configurer, il suffit de faire le fichier .tex et d'appuyer sur Alt+Maj+F1 . L'afficheur pdf ne se met pas à jour tout seul. Il suffit de cliquer sur la flèche à côté de "voir pdf " pour que l'afficheur se mette à jour.

 

Et voilà, j'espère que cet article vous a plu. Le potentiel du couple Latex + Python est immense !

Voici les étapes à réaliser :

  • Installer Pyton (si ce n'est pas déjà fait) et lors de l'installation choisir d'inscrire les exécutables Python au Path (ou les rajouter ensuite ...)
  • Avec pip (par exemple) installer le package Pygments (qui permet de colorer la syntaxe du code Python). Par exemple dans la ligne de commande j'ai entré : pip install Pygments
  • Installer PythonTex avec votre distribution LaTeX. Pour ma part j'ai une distribution texlive et j'utilise TexLiveManager pour installer le package
  • Configurer la ligne de commande de votre éditeur de LaTex , par exemple TexMaker (voir le chapitre précédent)

Voici deux exemples de lignes de commande à adapter suivant votre système :

  • Pour pdfLaTeX : 
    latex --shell-escape -synctex=1 -interaction=nonstopmode %.tex|python C:\texlive\2014\texmf-dist\scripts\pythontex\pythontex.py %.tex|latex --shell-escape -synctex=1 -interaction=nonstopmode %.tex

 

  • Pour LaTeX + dvips + ps2pdf : 
    latex --shell-escape -synctex=1 -interaction=nonstopmode %.tex|python C:\texlive\2014\texmf-dist\scripts\pythontex\pythontex.py %.tex|latex --shell-escape -synctex=1 -interaction=nonstopmode %.tex|dvips -Pdownload35 -o %.ps %.dvi|ps2pdf %.ps