Search code examples
latexlstlisting

Can't put Python listing in LaTeX


I'm trying to put a Python listing into a \fbox\parbox but I always get errors.

Here is my code:

\documentclass[12pt]{article}

% Packages
\usepackage[utf8]{inputenc}    % support for accents
\usepackage[T1]{fontenc}
\usepackage[francais]{babel}   % doc language
\usepackage{lmodern}
\usepackage[a4paper]{geometry} % marges
\usepackage{xcolor}            % text color
\usepackage{sectsty}           % colorize sections
\usepackage{changepage}
\usepackage{moreverb}          % code with indent
\usepackage{listings}          % display code with magnification
\usepackage{amssymb}
\usepackage{amsmath}           % Text into equation
\usepackage{enumitem}          % Continue enumerate numbers
\usepackage{fourier}           % Double brackets

% Python listing
\newcommand\pythonstyle{\lstset{
language=Python,
basicstyle=\sffamily,
keywordstyle=\textbf,
commentstyle=\color{blue},
showstringspaces=false,
frame=tb, numbers=left }}
% Python environment
\lstnewenvironment{python}[1][]{
\pythonstyle \lstset{#1} }{}

\begin{document}
\begin{enumerate}
    \item On suppose qu'on dispose d'une fonction \texttt{binom(n,k)}, prenant en entrée deux entiers, et qui calcule $\binom{n}{k}$. Ecrire en langage \textsc{Python} une fonction \texttt{bernoulli(n)}, qui prend en entrée un entier naturel, et qui renvoie la liste \texttt{[b\_0, b\_1, ..., b\_n]}. \par
        \fbox{\parbox{\linewidth-2\fboxrule-2\fboxsep}{
            La relation précédente donne, pour $n \ge 2$ :
            \[ \binom{n}{n-1} b_{n-1} = - \sum_{j=0}^{n-2} \binom{n}{j} b_j \]
            autrement dit on a la relation de récurrence, pour tout $m \ge 1$ :
            \[ b_m = -\frac{1}{m+1} \sum_{j=0}^{m-1} \binom{n}{j} b_j \]
            On en déduit le code demandé :
        }}
        \fbox{\parbox{\linewidth-2\fboxrule-2\fboxsep}{
            \begin{python}
                def bernoulli(n) :
                     liste_bj = [1]
                     for m in range(1,n+1):
                         b = 0
                         for j in range(m):
                             b -= binom(m+1,j) * liste_bj[j]
                         b /= m+1
                         liste_bj.append(b)
                     return liste_bj
            \end{python}
        }} %err1
    \end{enumerate}

I got the following errors:

  • On documentclass : Emergency stop, Fatal error occured, no output PDF produced!
  • On err1 : Argument of \lst@next has an extra }. Paragraph ended before \lst@next was complete. Extra }, or forgotten \endgroup
  • On \end{enumerate} : \begin{python} ended by \end{enumerate}
  • On \end{document} : \begin{enumerate} ended by \end{document}. You can't use '\end' in internal vertical mode. Missing { inserted

I tried to erase the "python listing" and "python environment" on the preamble and replace \begin{python} with \begin{listings} (same with \end) to reset my LaTeX project with the standard presentation of code, but I still get the same errors. So it seems that LaTeX has trouble to read that my listing closure command is put before closing the enumerate one. Maybe it's because I put the listing into a \fbox\parbox?

The \fbox\parbox works well with text and equations in it, so the issue does not come from there.


Solution

  • You must not use fragile content, such as listings, as argument of other macros.

    Anyway, the fbox\parbox is really superfluous - lstings has a frame option for this:

    \documentclass[12pt]{article}
    
    % Packages
    \usepackage[utf8]{inputenc}    % support for accents
    \usepackage[T1]{fontenc}
    \usepackage[french]{babel}   % doc language
    \usepackage{lmodern}
    \usepackage[a4paper]{geometry} % marges
    \usepackage{xcolor}            % text color
    \usepackage{sectsty}           % colorize sections
    \usepackage{changepage}
    \usepackage{moreverb}          % code with indent
    \usepackage{listings}          % display code with magnification
    \usepackage{amssymb}
    \usepackage{amsmath}           % Text into equation
    \usepackage{enumitem}          % Continue enumerate numbers
    \usepackage{fourier}           % Double brackets
    
    % Python listing
    \newcommand\pythonstyle{\lstset{
    language=Python,
    basicstyle=\sffamily,
    keywordstyle=\textbf,
    commentstyle=\color{blue},
    showstringspaces=false,
    frame=tb, numbers=left }}
    % Python environment
    \lstnewenvironment{python}[1][]{
    \pythonstyle \lstset{#1} }{}
    
    \begin{document}
    \begin{enumerate}
        \item On suppose qu'on dispose d'une fonction \texttt{binom(n,k)}, prenant en entrée deux entiers, et qui calcule $\binom{n}{k}$. Ecrire en langage \textsc{Python} une fonction \texttt{bernoulli(n)}, qui prend en entrée un entier naturel, et qui renvoie la liste \texttt{[b\_0, b\_1, ..., b\_n]}. \par
            \fbox{\parbox{\linewidth-2\fboxrule-2\fboxsep}{
                La relation précédente donne, pour $n \ge 2$ :
                \[ \binom{n}{n-1} b_{n-1} = - \sum_{j=0}^{n-2} \binom{n}{j} b_j \]
                autrement dit on a la relation de récurrence, pour tout $m \ge 1$ :
                \[ b_m = -\frac{1}{m+1} \sum_{j=0}^{m-1} \binom{n}{j} b_j \]
                On en déduit le code demandé :
            }}
    %        \fbox{\parbox{\linewidth-2\fboxrule-2\fboxsep}{
                \begin{python}[frame=single,linewidth=1.035\linewidth]
    def bernoulli(n) :
         liste_bj = [1]
         for m in range(1,n+1):
             b = 0
             for j in range(m):
                 b -= binom(m+1,j) * liste_bj[j]
             b /= m+1
             liste_bj.append(b)
         return liste_bj
                \end{python}
    %        }} %err1
        \end{enumerate}
        \end{document}
    

    enter image description here

    (and \end{document} was obviously missing)