Fundo

Fundo

Fundo

Olá e agradecemos antecipadamente por todos os insights que todos vocês possam oferecer! Desculpe pela postagem muito longa, mas notei que a maioria dos novos usuários são repreendidos por não compartilharem contexto suficiente. OA versão TLDR é que não consigo descobrir como usar valores de células lidos com pgfplottable dentro de expressões booleanas do etools.

Estou lutando para formatar certos trechos de texto com base nos valores lidos de um csv. Todos os anos tenho que criar um documento com mais ou menos o mesmo contorno, mas com valores diferentes em determinados locais a cada ano. Por exemplo, em 2015, o documento poderia dizer:

A capacidade total nominal para os Estados Unidos em 2015 foi 1.159.748 MW.

mas em 2016 esta frase deve ser atualizada para:

A capacidade total nominal para os Estados Unidos em 2015 foi 1.174.115 MW.

Estamos tentando fazer a transição para um processo mais eficiente com Python + LaTeX, com os dados/figuras reais sendo salvos em csvs com Python e os documentos sendo atualizados automaticamente com leitura de LaTeX nesses csvs, a ideia é que poderíamos recriar todos os documentos com um único script de linha de comando.

Até aqui,com a ajuda desta resposta, não tenho nenhum problema em ler os csvs e imprimi-los 'inline' no LaTeX. MWE:

\documentclass[16pt]{article}

\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}

\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars

\def\getcell#1#2#3{
    \pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval%
}

\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}\% of total installed electricity capacity and \getcell{3}{all_re}\sectionIIvars}\% of total annual generation in the United States}.
\end{document}

O que cospe:

saída de código mostrando csv lidos e impressos corretamente

Posso descobrir uma maneira de compartilhar os csvs reais com você, mas eles são bem simples: a primeira linha é cabeçalho/nomes (por exemplo, você pode ver no código que há uma coluna intitulada 'all_re'). A primeira coluna são apenas nomes (sequências de caracteres) para nos ajudar a controlar qual linha corresponde a qual variável. O resto do csv são apenas números. A função '\getcell{8}{all_re}{\sectionIIvars}' me permite acessar o conteúdo da célula para a linha 8, coluna 'all_re' da tabela predefinida '\sectionIIvars'.

O problema

Os resultados do LaTeX aqui serão passados ​​para uma equipe que os deixará 'prontos para publicação' e muitas vezes precisamos passar para essa equipe múltiplas iterações do documento, pois os números são constantemente atualizados até a publicação final. Para reduzir o tempo que esta equipe externa precisa para atualizar os rascunhos “prontos para publicação”, queremos poder formatar automaticamente os valores que foram alterados entre as iterações. Por exemplo, se o segundo valor no trecho de código acima mudou de 15,55 para 17,56 entre as iterações, queremos que 17,56 apareça em vermelho. Mesmo que nenhum código no arquivo '.tex' tenha sido alterado, apenas no csv subjacente. Veja abaixo:

insira a descrição da imagem aqui

Infelizmente, não consigo fazer isso funcionar! Algumas coisas que tentei sem sucesso:

Látex diferente

Eu descartei isso imediatamente porque, com base no que pude dizer, isso captura apenas alterações nos próprios arquivos '.tex'. Como os arquivos .tex reais não mudam aqui, não seria possível ajudar.

ifboolexpr

A maior parte do meu tempo foi gasto aqui. Tudo isso é baseado em um comando escritonesta resposta. Em cada caso, estou tentando fazer com que a função booleana compare uma resposta em um csv com uma resposta em outro csv. A ideia é que um script Python possa comparar as respostas na tabela '\sectionIIvars' entre as iterações e escrever se a resposta real foi ou não alterada para um segundo csv (vamos chamá-lo de '\booltestsecII'). O Latex poderia então imprimir as respostas em '\sectionIIvars'mas formate-os com base no '\booltestsecII'. O '\booltestsecII' teria o mesmo tamanho e formato de '\sectionIIvars', mas com apenas 0's e 1's (para 'não mudou' e 'alterou!' respectivamente).

Tentativa 1

Primeiro tentei reescrever a função getcell para receber um argumento adicional para comparar a mesma linha e célula entre '\sectionIIvars' e \booltestsecII':

\documentclass[16pt]{article}

\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}

\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII

\newcommand{\getcell}[4]{
      \ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotsretval}{=}{1}}}
        {\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}
        {\textcolor{red}{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}}
}

\begin{document}

Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}{\booltestsecII}\% of total installed electricity capacity and \getcell{3}{all_re}{\sectionIIvars}{\booltestsecII}\% of total annual generation in the United States}.

\end{document}

Isso produziu um "! Número ausente, tratado como zero." erro (que tende a indicar uma entrada de função necessária ausente), embora eu pensasse ter fornecido todas as entradas necessárias. Se eu tentar prosseguir, produzirá um 'Missing = inserido para \ifnum.' erro. Se eu tentar prosseguir novamente, ele produzirá um '! Você não pode usar `\numexpr' no modo horizontal.'

Tentativa 2

Achei que talvez isso tivesse algo a ver com macros aninhadas, então tentei alterar a definição da função assim (baseado nesta pergunta):

\newcommand{\getcell}[4]{
      \ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{##1}{##2}\of{##4}\pgfplotsretval}{=}{1}}}
        {\pgfplotstablegetelem{##1}{##2}\of{##3}\pgfplotsretval}
        {\textcolor{red}{\pgfplotstablegetelem{##1}{##2}\of{##4}\pgfplotsretval}}
}

Mas isso produziu os mesmos erros.

Tentativa 3

Tentei simplificar um pouco e focar apenas na leitura de um valor de um csv e depois compará-lo com um valor numérico usando 'ifboolexpr', mas também não funcionou:

\documentclass[16pt]{article}

\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}

\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII

\newcommand{\checkchangesecII}[3]{
      \ifboolexpr{ test {\value{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}{=}{1}}}
        {do this}
        {\textcolor{red}{do that}}
}


\begin{document}

\checkchangesecII{0}{solar}{\booltestsecII}

\end{document}

Isso produz um '! \endcsname ausente inserido.' erro e depois um '! \endcsname extra.' erro antes de finalmente imprimir "1 = 1 faça isso":

insira a descrição da imagem aqui

Resumo

Até agora não cheguei a lugar nenhum, mas estou muito interessado em ouvir as teorias de alguém. Eu acho que pode ser que, embora o LaTeX esteja lendo valores numéricos, talvez ele não os reconheça como tal e, portanto, seja incapaz de comparar um 'numérico 1' com uma 'sequência de caracteres 1'? Não sei como verificar ou corrigir isso, por isso estou escrevendo aqui.

Obrigado por todo e qualquer feedback. Desculpe se esta é uma pergunta mal formatada, por favor me avise e eu a editarei da melhor maneira possível.

Responder1

Você estava bem perto:

Na tentativa 1, você usou

\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotsretval}{=}{1}}}

Aqui \pgfplotstablegetelem{#1}{#2}\of{#4}atribui 1or 0to \pgfplotsretvale depois você usa \pgfplotsretval. Por que isso é necessário? Por que não \pgfplotstablegetelem{#1}{#2}\of{#4}fornece diretamente o valor de retorno? O problema é que algumas operações, como atribuições e outras coisas necessárias, \pgfplotstablegetelemnão são "expansíveis". Isso basicamente significa que eles podem ser executados, mas não suportam onde um valor é necessário. Portanto, usar \pgfplotstablegetelemdentro de \testonde o valor que você deseja testar é esperado não funcionaria. É aí que \pgfplotsretvalentra a questão: você pode se movimentar \pgfplotstablegetelemantes da prova e usar apenas o expansível \pgfplotsretvalpor dentro:

\documentclass[16pt]{article}

\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}

\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII

\newcommand{\getcell}[4]{
      \pgfplotstablegetelem{#1}{#2}\of{#4}
      \ifboolexpr{ test {\ifnumcomp{\pgfplotsretval}{=}{1}}}
        {\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}
        {\textcolor{red}{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}}
}

\begin{document}

Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}{\booltestsecII}\% of total installed electricity capacity and \getcell{3}{all_re}{\sectionIIvars}{\booltestsecII}\% of total annual generation in the United States}.

\end{document}

insira a descrição da imagem aqui

informação relacionada