宏序列泛化(含羞涩)

宏序列泛化(含羞涩)

我正在尝试采用基于脚本的方式来回答我的常设问题pgfplots 中误差的自动计算,而且我有一个可行的解决方案。

使用 Python,我将给定的数据集转换为对我朋友的领域有意义的内容。如果您对脚本感兴趣,下面将重现该脚本。我能够使用一系列命令在 LaTeX 中简化其使用,理想情况下,我希望使用\newcommand或类似的宏将其本身转换为宏。不幸的是,我遇到了无法解释或解决的错误。我正在使用包tikzpgfplotsbashfulbashful这是给我带来问题的那个。

error.py(完美运行)

def sqrt(n):
    return n**.5

def avg(nums):
    return sum(nums)/len(nums)

def stddev(nums):
    s = sum(nums)
    a = avg(nums)
    s2 = sum([(n - a)**2 for n in nums])
    return sqrt(s2/len(nums))

def stderr(nums):
    return stddev(nums)/sqrt(len(nums))

lines = list()

import sys

with open(sys.argv[1],'r') as f:
    lines = f.readlines()

data = list()

for i in range(len(lines)):
    if lines[i][0].isdigit():
        toks = lines[i].split()
        data.append(map(int,toks))

data = [(data[0][i], [l[i] for l in data[1:]])                 for i in range(len(data[0]))]
for (val, nums) in data:
    print val, avg(map(float,nums)), stderr(map(float,nums))

手动命令

\bash[stdoutFile=plots/mydata.table.digest]
python error.py plots/mydata.table
\END

\newsavebox{\myplot}
\savebox{\myplot}{%
  \begin{tikzpicture}
    \begin{axis}[grid=major]
      \addplot+[smooth,
                error bars/.cd,
                y dir=both,
                y explicit]
      table[x index=0,
            y index=1,
            y error index=2]
      {plots/mydata.table.digest};
    \end{axis}
  \end{tikzpicture}
}

\newcommand{\plotmyplot}{\usebox{\myplot}}

\begin{document}
stuff2 \plotmyplot
\end{document}

尝试概括

\newcommand{\prepareplot}[2]{
\bash[stdoutFile=#2.digest]
python error.py #2
\END

  \expandafter\newsavebox\csname #1\endcsname
  \expandafter\savebox\csname #1\endcsname{%
    \begin{tikzpicture}
      \begin{axis}[grid=major]
        \addplot+[smooth,
                  error bars/.cd,
                  y dir=both,
                  y explicit]
        table[x index=0,
              y index=1,
              y error index=2]
        {#2.digest};
      \end{axis}
    \end{tikzpicture}}
  \expandafter\newcommand\csname plot#1\endcsname\expandafter\usebox\csname #1\endcsname}

错误

! Use of \bashIII doesn't match its definition.
\prepareplot #1#2-> \bash [stdoutFile=#2.digest] 
                                                 python error.py #2 \END \pa...
l.27 \prepareplot{myplotB}{plots/mydata.table}

? 
! Emergency stop.
\prepareplot #1#2-> \bash [stdoutFile=#2.digest] 
                                                 python error.py #2 \END \pa...
l.27 \prepareplot{myplotB}{plots/mydata.table}

!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on plots.log.

完整的 MWE(需要 Python 2.7 和error.py

\documentclass{article}
\usepackage{pgfplots,tikz,bashful}

\newcommand{\prepareplot}[2]{
\bash[stdoutFile=#2.digest]
python error.py #2 | \preparedplotname.digest
\END

  \expandafter\newsavebox\csname #1\endcsname
  \expandafter\savebox\csname #1\endcsname{%
    \begin{tikzpicture}
      \begin{axis}[grid=major]
        \addplot+[smooth,
                  error bars/.cd,
                  y dir=both,
                  y explicit]
        table[x index=0,
              y index=1,
              y error index=2]
        {#2.digest};
      \end{axis}
    \end{tikzpicture}}
  \expandafter\newcommand\csname plot#1\endcsname\expandafter\usebox\csname #1\endcsname}

\pgfplotsset{compat=1.7}

\prepareplot{myplotB}{plots/mydata.table}

\bash[stdoutFile=plots/mydata.table.digest]
python error.py plots/mydata.table
\END

\newsavebox{\myplot}
\savebox{\myplot}{%
  \begin{tikzpicture}
    \begin{axis}[grid=major]
      \addplot+[smooth,
                error bars/.cd,
                y dir=both,
                y explicit]
      table[x index=0,
            y index=1,
            y error index=2]
      {plots/mydata.table.digest};
    \end{axis}
  \end{tikzpicture}
}

\newcommand{\plotmyplot}{\usebox{\myplot}}

\begin{document}
stuff2 \plotmyplotB
\end{document}

答案1

\bash命令更改类别代码,以便附带多行脚本,因此不能在其他命令的参数中使用。

但是,对于单行代码来说,不需要 的全部功能\bash,因此下面的代码应该可以工作:

\makeatletter
\newcommand{\rbash}[2][]{%
  \begingroup
  \setKeys@BL{#1}%
  \begingroup\edef\x{\endgroup
    \noexpand\bashIV{\detokenize{#2}}%
    \noexpand\bashV{\detokenize{#2}}\logBL{bashV: Done!}%
  }\x
  \endgroup}
\makeatother

\rbash[stdoutFile=myls.digest]{ls -l 2>&1 > myls.digest}

我添加了一个命令只是为了测试它。

您的命令可能定义为

\newcommand{\prepareplot}[2]{%
  \rbash[stdoutFile=#2.digest]{python error.py #2 | \preparedplotname.digest}
  \expandafter\newsavebox\csname #1box\endcsname
  \expandafter\sbox\csname #1box\endcsname{%
    \begin{tikzpicture}
      \begin{axis}[grid=major]
        \addplot+[smooth,
                  error bars/.cd,
                  y dir=both,
                  y explicit]
        table[x index=0,
              y index=1,
              y error index=2]
        {#2.digest};
      \end{axis}
    \end{tikzpicture}}
  \expandafter\newcommand\csname plot#1\endcsname{\expandafter\usebox\csname #1box\endcsname}}

相关内容