1

I am trying to make a tax calculator for an invoice template and the idea is to pass the variable subcost to the command \taxcalc.

\newcommand*{\taxcalc}[2]{%
  \pgfmathparse{#1/(1.0-#2)-#1}%
  \pgfmathprintnumber{\pgfmathresult}%
}

\newcommand{\vatTotal}{
     & & & {\bf BTW 21\%} & {\bf {\bf \euro\taxcalc{subcost}{0.21}}}
    \\*[1.5ex]
}

The problem is, no matter what I try to do to subcost, the compiler keeps complaining:

Package PGF Math Error: Unknown function `subcost' (in 'subcost/(1.0-0.21)-subcost').'

It works perfectly for the following:

\newcommand*{\total}[1]{\FPdiv{\t}{\arabic{#1}}{1000}\formatNumber{\t}}

\newcommand{\subTotal}{
    & & & {\bf Subtotaal (excl. btw)} & {\bf \euro\total{subcost}}
    \\*[1.5ex]
}

Can anyone help me? I've been googling for hours now in order to find how to correctly pass variables to functions in this language but no matter what I try, it only works if I hardcode a number.

subcost is defined as follows:

\newcounter{hours} \newcounter{subhours}
\newcounter{cost} \newcounter{subcost}
\newcounter{vat}
  • 2
    Where and how have you declared subcost? – Joseph Wright Nov 17 '19 at 16:18
  • 1
    There are no such things as variables in TeX, only macros and maybe some packages that emulate something like variables by setting macros and retrieving the values from their definition. E.g. in pgf you can do \pgfkeyssetvalue{my/variableA}{10} and then do \pgfkeysgetvalue{my/variableA} to get back the 10. – Skillmon likes topanswers.xyz Nov 17 '19 at 16:19
  • The \arabic{#1} looks like you're using a counter for subcost, you can get the value of a LaTeX counter by using \value{<countername>}, e.g., \pgfmathparse{\value{#1}/(1.0-#2)-\value{#1}} could work if the first argument to \taxcalc is always a LaTeX counter. – Skillmon likes topanswers.xyz Nov 17 '19 at 16:25
  • 1
    It looks like you've got two separate accounts, which means you cannot edit your original post or leave comments. The Stack Exchange staff can merge them together for you. – Phelype Oleinik Nov 17 '19 at 16:56
  • It's worth taking a look at the sagetex package which gives you access to a computer algebra system, SAGE which can handle calculations on the fly (e.g. first page of documentation) or calculate statistics easily. SAGE lets you program with the easy to learn Python language, such as in my answer here. – DJP Nov 17 '19 at 17:14
3

Your approach works. You can declare a variable, or parameterless function, with pgf which you seem to be using. In order to be able to redefine the function, you need the starred version, \pgfmathdeclarefunction*. This allows you to define a variable and assign it a value which you can use in any expression that you parse with pgf. For your convenience, I packed the \pgfmathdeclarefunction* stuff in a macro \SetPgfVariable.

\documentclass{article}
\usepackage{pgf}
\newcommand*{\taxcalc}[2]{%
  \pgfmathparse{#1/(1.0-#2)-#1}%
  \pgfmathprintnumber{\pgfmathresult}%
}
\newcommand{\SetPgfVariable}[2]{%
\pgfmathdeclarefunction*{#1}{0}{\pgfmathparse{#2}}}
\begin{document}
\SetPgfVariable{subcost}{0.4}
\taxcalc{subcost}{0.21}

\SetPgfVariable{subcost}{0.5}
\taxcalc{subcost}{0.21}
\end{document}

enter image description here

| improve this answer | |
3

Be aware that the concept of a LaTeX-counter differs from the concept of a mathematical function in PGF-math.

Seems with your first snippet the problem is:

\taxcalc's first and second argument must be numbers or calls to defined PGF-math-functions—i.e., things which can be used for calculations with PGF-math-things.

But by \vatTotal as first argument the sequence subcost is passed to \taxcalc. That sequence does neither denote such a number nor denote a call to such a defined PGF-math-function.

PGF-math-things cannot/do not "know" that the sequence subcost denotes the name of a LaTeX-counter whose value is to be obtained.

PGF-math-things "assume" that subcost denotes the name of a PGF-math-function implemented by means of PGF-math-things for doing PGF-math-things and therefore "complains" that the function "subcost" is undefined.

Another question is: Why \bf twice, opening up two nested local scopes? Seems one local scope and one \bf is sufficient. :-)

You can modify \vatTotal to make sure that the value of the subcost-LaTeX-counter gets expanded "into" \taxcalc's first argument before \taxcalc gets carried out. This way at the time of carrying out \taxcalc the first argument of \taxcalc will not be a character-sequence denoting the name of a LaTeX-counter but will be a number and thus something that is "understood" by the PGF-math-things.

Does

\newcommand*{\taxcalc}[2]{%
  \pgfmathparse{#1/(1.0-#2)-#1}%
  \pgfmathprintnumber{\pgfmathresult}%
}

\newcommand{\vatTotal}{%
    &&&{\bf BTW 21\%}%
    &{\bf\euro\expandafter\taxcalc\expandafter{\number\value{subcost}}{0.21}}%
    \\*[1.5ex]%
}

work?

Perhaps \textbf{..} instead of {\bf...}:

\newcommand*{\taxcalc}[2]{%
  \pgfmathparse{#1/(1.0-#2)-#1}%
  \pgfmathprintnumber{\pgfmathresult}%
}

\newcommand{\vatTotal}{%
    &&&\textbf{BTW 21\%}%
    &\textbf{\euro\expandafter\taxcalc\expandafter{\number\value{subcost}}{0.21}}%
    \\*[1.5ex]%
}

Your second snippet works because here the sequence subcost is wrapped into \arabic{...} by the routine \total while the argument of \arabic must denote the name of a LaTeX-counter.
In other words: Here \total takes into account that subcost denotes the name of a LaTeX-counter by applying \arabic to that phrase for obtaining a number which FP-math-stuff can calculate with.


Summa summarum:

The routine \taxcalc from your first snippet processes two arguments whereof each must denote a number or a call to a defined PGF-math-function which in turn delivers a number.

The name of a LaTeX-counter neither denotes such a number nor denotes the call to a defined PGF-math-function.
Therefore you need steps for obtaining the value/number from the name of the LaTeX-counter.

The routine \total processes one argument which must denote the name of a LaTeX-counter.

\total internally applies \arabic for obtaining a number from that which FP-math-thingies can use for calculating.


By the way:

If PGF-math is in use, then I prefer Schrödinger's cat's approach of not using LaTeX-counters at all for holding values of "variables" but using PGF-math-functions that don't process arguments but always deliver the same number. (Reason: Each LaTeX-counter internally requires allocation of a count-register while the amount of count-registers is limited in LaTeX. Afaik declaring a new PGF-math-function doesn't require allocating another count-register.)

In case a PGF-math-function does not process arguments and always delivers the same number, the name of that PGF-math-function within the context of PGF-math can be taken for a placeholder for that number/for a variable whose value is that number.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.