背景

背景

背景

您好,提前感謝大家提供的任何見解!很抱歉這篇文章很長,但我注意到大多數新用戶都因為沒有分享足夠的上下文而受到懲罰。這TLDR 版本是我無法弄清楚如何使用從 etools 的布林表達式內部使用 pgfplottable 讀取的單元格值

我正在努力根據從 csv 讀取的值來格式化某些文字片段。每年我都必須創建一個大綱大致相同但每年在某些地方具有不同值的文檔。例如,在 2015 年,該文件可能會說:

2015 年美國總銘牌產能為 1,159,748 兆瓦

但在2016年這句話應該更新為:

2015 年美國總銘牌產能為 1,174,115 兆瓦

我們正在嘗試使用 Python + LaTeX 將其轉換為更有效率的流程,使用 Python 將實際資料/圖形保存到 csv,並使用這些 csv 中的 LaTeX 讀取自動更新文檔,我們的想法是我們可以重新創建所有使用單一命令列腳本的文件。

迄今為止,在這個答案的幫助下,我在實際讀取 csv 並將其“內聯”打印到 LaTeX 中時沒有遇到任何問題。微量元素:

\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}

其中吐出:

顯示 csv 正確讀取和列印的程式碼輸出

我可以找到一種與您共享實際 csv 的方法,但它們非常簡單:第一行是標題/名稱(例如,您可以從程式碼中看到有一列標題為“all_re”)。第一列只是名稱(字串),以幫助我們追蹤哪一行對應於哪個變數。 csv 的其餘部分只是數字。 '\getcell{8}{all_re}{\sectionIIvars}' 函數讓我可以存取預定義表 '\sectionIIvars' 中第 8 行、'all_re' 列的儲存格內容。

問題

這裡的 LaTeX 輸出將傳遞給一個團隊,使它們“準備好發布”,我們經常需要向該團隊傳遞文件的多次迭代,因為圖形會不斷更新,直到最終發布。為了減少該外部團隊更新「可發布」草稿所需的時間,我們希望能夠自動格式化迭代之間已更改的值。例如,如果上述程式碼片段中的第二個值在迭代之間從 15.55 更改為 17.56,我們希望 17.56 顯示為紅色。即使「.tex」檔案中的任何程式碼都沒有更改,只是底層 csv 中的程式碼發生了更改。見下文:

在此輸入影像描述

不幸的是,我無法讓它發揮作用!我嘗試了一些無濟於事的事情:

乳膠差異

我立即排除了這一點,因為據我所知,這只捕獲“.tex”文件本身的更改。由於實際的 .tex 檔案在這裡沒有改變,所以它無法提供幫助。

if布林表達式

我的大部分時間都是在這裡度過的。這都是基於編寫的命令在這個答案中。在每種情況下,我都試圖獲取布林函數來將一個 csv 中的答案與另一個 csv 中的答案進行比較。這個想法是,Python 腳本可以在迭代之間比較“\sectionIIvars”表中的答案,並寫入實際答案是否已更改為第二個 csv(我們稱之為“\booltestsecII”)。 Latex 可以在 '\sectionIIvars' 中列印答案但根據 '\booltestsecII' 格式化它們。 '\booltestsecII' 的大小和形狀與 '\sectionIIvars' 相同,但只有 0 和 1(分別表示「未更改」和「已更改!」)。

嘗試1

首先,我嘗試重寫 getcell 函數以取得附加參數,以便它可以比較 '\sectionIIvars' 和 \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}

這產生了“!丟失的數字,被視為零”。錯誤(這往往表示缺少所需的功能輸入),即使我認為我已經提供了所有必要的輸入。如果我嘗試繼續,它會產生“Missing = insert for \ifnum”。錯誤。如果我再次嘗試繼續,它會產生一個“!”您不能在水平模式下使用“\numexpr”。

嘗試2

我想這可能與嵌套宏有關,所以我嘗試像這樣更改函數定義(基於這個問題):

\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}}
}

但這產生了同樣的錯誤。

嘗試3

我嘗試簡化一點,只專注於從 csv 中讀取值,然後使用“ifboolexpr”將其與數值進行比較,但這也不起作用:

\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}

這會產生一個 '!缺少 \endcsname 插入。錯誤,然後是'!額外的\endcsname。最終印出「1=1do that」之前出錯:

在此輸入影像描述

概括

到目前為止,我還沒有任何進展,但我非常有興趣聽到任何人的理論。我認為即使 LaTeX 正在讀取數值,但它可能無法識別它們,因此無法將“數字 1”與“字串 1”進行比較?我不知道如何檢查或糾正這個問題,因此我在這裡寫下這篇文章。

感謝您的任何和所有反饋。抱歉,如果這是一個格式不正確的問題,請告訴我,我會盡力編輯它。

答案1

你非常接近:

在嘗試 1 中,您使用了

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

這裡將or\pgfplotstablegetelem{#1}{#2}\of{#4}分配給,然後使用。為什麼需要這樣做?為什麼不直接給回傳值呢?問題是一些操作,例如賦值和其他必需的操作是不可「擴展的」。這基本上意味著它們可以被執行,但它們不能忍受需要值的地方。因此,在預期要測試的值的內部使用是行不通的。這就是發揮作用的地方:您可以在測試之前移動,並且僅使用內部的可擴展部分:10\pgfplotsretval\pgfplotsretval\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotstablegetelem\pgfplotstablegetelem\test\pgfplotsretval\pgfplotstablegetelem\pgfplotsretval

\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}

在此輸入影像描述

相關內容