# How to test values in an \ifnum, that are generated from a csv file via \newcommand and \csvreader?

I would like to conditionally print something in a report, based on whether there was a non-zero data point or not (for this example, \DepthOne and \DepthThree are to be tested).

I start by reading values in from a csv table using \csvreader, and then I assign these a label using \newcommand. Then I apply a test on the label using \ifnum. The behaviour in the implementation below is not what I hoped for. For instance, I get missing number, treated as zero errors and weird output preceding the sentence. Also, oddly one of the labels I assigned (\SampleName) doesn't seem to persist.

Is it possible to do what I am attempting, and what is the right way to go about this?

\documentclass[10pt]{report}

\usepackage{csvsimple}
\usepackage{filecontents}

\newcommand*{\ThisRock}{examplecsv}

% Make up some data in a CSV file called examplecsv.csv
\begin{filecontents*}{\ThisRock.csv}
SampleName,Depth1,DepthTwo,Depth3
ROCK001,48,52,0
\end{filecontents*}

% Pick out specific data in the file and create labels for them to be read by latex

\begin{document}
% Show the data (normally this is underwater)
\csvautotabular{examplecsv.csv} \\

% Expect this to print the sentence twice fully (first time is okay, second time incomplete?)
The rock sampled was called \SampleName. \\
The rock sampled was called \SampleName. \\

% Because there is some non-zero data for the first sample, expect this to print the sentence
\ifnum\ifnum\DepthOne>0 1\else0\fi
=1 %
\noindent The first sample hole was drilled to \DepthOne~mm\\
\else
\\
\fi

% Because the data is zero for the third sample, expect this not to print the sentence
\ifnum\ifnum\DepthThree>0 1\else0\fi
=1 %
\noindent The third sample hole was drilled to \DepthThree~mm\\
\else
\\
\fi

\end{document}

• \DepthOne etc. aren't expandable apparently, so \ifnum\Depth... will fail -- it can't evaluate the test,\cvsreader is not expandable since it has an optional first argument, so \DepthOne etc. can't be expanded as well – user31729 Feb 9 '17 at 22:55
• Perhaps the macros \ifcvsstrequal etc. (see the manual please) are more useful? I can't test right now... it's late and I am tired! – user31729 Feb 9 '17 at 22:59
• Perhaps have a look at the readarray package, as an alternative. – Steven B. Segletes Feb 10 '17 at 2:45

What happens when I wish to access the \samplename label outside the \csvreader context?

You can use the \csvreader context for making global assignments after sufficiently expanding local "variables"/macros—in order to obtain the values, the "variables" need to be expanded twice:

% Make up some data in a CSV file
\begin{filecontents*}{\jobname.csv}
SampleName,Depth1,DepthTwo,Depth3
ROCK001,48,52,0
ROCK002,1,2,3
\end{filecontents*}

\documentclass[10pt]{report}
\usepackage{csvsimple}

\newcount\Samplenumber
\newcommand*\GlobalSamplename{}%
\newcommand*\GlobalDepthone{}%
\newcommand*\GlobalDepthtwo{}%
\newcommand*\GlobalDepththree{}%
%
\newcommand*\GlobalSamplenamederrorefault{\texttt{??}}%
\newcommand*\GlobalDepthoneerrorefault{0}%
\newcommand*\GlobalDepthtwoerrorefault{0}%
\newcommand*\GlobalDepththreeerrorefault{0}%
%
\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\expandtwice{}%
\long\def\expandtwice#1#{\innerexpandtwice{#1}}%
\newcommand\innerexpandtwice[2]{%
\expandafter\expandafter\expandafter\PassFirstToSecond
\expandafter\expandafter\expandafter{#2}{#1}%
}%

\makeatletter

\@bsphack
\begingroup
\let\GlobalSamplename=\UndEfINeD
\Samplenumber=0 %
}{%
%
\ifnum#1=\Samplenumber\relax
\fi
}%
\ifx\GlobalSamplename\UndEfINeD
\@latex@error{Row #1 not available}{Seems your sheet of csv data does not have #1 rows.}%
\global\let\GlobalSamplename=\GlobalSamplenamederrorefault
\global\let\GlobalDepthone=\GlobalDepthoneerrorefault
\global\let\GlobalDepthtwo=\GlobalDepthtwoerrorefault
\global\let\GlobalDepththree=\GlobalDepththreeerrorefault
\fi
\endgroup
\@esphack
}%
\makeatother

\begin{document}

\noindent\csvautotabular{\jobname.csv}

\bigskip

Reading data row number 2 via
using placeholder-macros outside

The rock sampled was called \GlobalSamplename.

The rock sampled was called \GlobalSamplename.

\ifnum\GlobalDepthone>0 %
The first sample hole was drilled to \GlobalDepthone~mm.
\fi

\ifnum\GlobalDepthtwo>0 %
The second sample hole was drilled to \GlobalDepthtwo~mm.
\fi

\ifnum\GlobalDepththree>0 %
The third sample hole was drilled to \GlobalDepththree~mm.
\fi

\noindent\hrulefill\null

Reading data row number 1 via
using placeholder-macros outside

The rock sampled was called \GlobalSamplename.

The rock sampled was called \GlobalSamplename.

\ifnum\GlobalDepthone>0 %
The first sample hole was drilled to \GlobalDepthone~mm.
\fi

\ifnum\GlobalDepthtwo>0 %
The second sample hole was drilled to \GlobalDepthtwo~mm.
\fi

\ifnum\GlobalDepththree>0 %
The third sample hole was drilled to \GlobalDepththree~mm.
\fi

\noindent\hrulefill\null

Reading non-existing data row number 3 via
using placeholder-macros outside

The rock sampled was called \GlobalSamplename.

The rock sampled was called \GlobalSamplename.

\verb|\GlobalSamplename| is assigned the errordefault value \GlobalSamplename.

\verb|\GlobalDepthone| is assigned the errordefault value \GlobalDepthone.

\verb|\GlobalDepthtwo| is assigned the errordefault value \GlobalDepthtwo.

\verb|\GlobalDepththree| is assigned the errordefault value \GlobalDepththree.

\ifnum\GlobalDepthone>0 %
The first sample hole was drilled to \GlobalDepthone~mm.
\fi

\ifnum\GlobalDepthtwo>0 %
The second sample hole was drilled to \GlobalDepthtwo~mm.
\fi

\ifnum\GlobalDepththree>0 %
The third sample hole was drilled to \GlobalDepththree~mm.
\fi

\end{document}


I did some more research based on what @egreg suggested and I figured I can use datatool to do what I want:

\begin{filecontents*}{rockdata.csv}
SampleName,Depth1,DepthTwo,Depth3
ROCK001,48,52,0
\end{filecontents*}

\documentclass[10pt]{report}
\usepackage{datatool}

\begin{document}

% This replaces the \newcommand step
\DTLforeach*{rocks}% database label
{\SampleName=SampleName,\DepthOne=Depth1,\DepthTwo=DepthTwo,\DepthThree=Depth3}% Assignment
{}% Things can be done in here

% But things can also seemingly be done out here too
\noindent The rock sampled was called \SampleName.\\
\dtlifnumeq{\DepthOne}{0}{\\}{The first sample hole was drilled to \DepthOne~mm\\}
\dtlifnumeq{\DepthTwo}{0}{\\}{The second sample hole was drilled to \DepthTwo~mm\\}
\dtlifnumeq{\DepthThree}{0}{\\}{The third sample hole was drilled to \DepthThree~mm\\}

\end{document}


More guru way

Ultimately I can separate the ugly data-collecting machinery into a style file and use the labels created by datatools to run the conditional tests I want:

LaTex file:

\begin{filecontents*}{rockdata.csv}
SampleName,Depth1,DepthTwo,Depth3
ROCK001,48,52,0
\end{filecontents*}

\documentclass[10pt]{report}
\usepackage{datatool}

% User-defined package here

\begin{document}

% But things can also seemingly be done out here too
\noindent The rock sampled was called \SampleName.\\
\dtlifnumeq{\DepthOne}{0}{\\}{The first sample hole was drilled to \DepthOne~mm\\}
\dtlifnumeq{\DepthTwo}{0}{\\}{The second sample hole was drilled to \DepthTwo~mm\\}
\dtlifnumeq{\DepthThree}{0}{\\}{The third sample hole was drilled to \DepthThree~mm\\}

\end{document}


Style file LoadRocks.sty:

\ProvidesPackage{LoadRocks}[]

\DTLforeach*{rocks}% database label
{\SampleName=SampleName,\DepthOne=Depth1,\DepthTwo=DepthTwo,\DepthThree=Depth3}% Assignment
{}


You're misunderstanding what \csvreader does.

% Make up some data in a CSV file
\begin{filecontents*}{\jobname.csv}
SampleName,Depth1,DepthTwo,Depth3
ROCK001,48,52,0
ROCK002,1,2,3
\end{filecontents*}

\documentclass[10pt]{report}
\usepackage{csvsimple}

\begin{document}

\csvautotabular{\jobname.csv}

\bigskip

SampleName=\samplename,
Depth1=\depthone,
DepthTwo=\depthtwo,
Depth3=\depththree,
}
{%
The rock sampled was called \samplename.

The rock sampled was called \samplename.

\ifnum\depthone>0
The first sample hole was drilled to \depthone~mm
\fi

\ifnum\depththree>0
The third sample hole was drilled to \depththree~mm
\fi

\bigskip
}

\end{document}


If you want to have all data available in any place of your document, you have to index the rows.

% Make up some data in a CSV file
\begin{filecontents*}{\jobname.csv}
SampleName,Depth1,DepthTwo,Depth3
ROCK001,48,52,0
ROCK002,1,2,3
\end{filecontents*}

\documentclass{article}
\usepackage{csvsimple}
\usepackage{xparse}
\usepackage{siunitx}

\ExplSyntaxOn
\NewDocumentCommand{\rocks}{m}
{
{
\int_gincr:N \g_fejoia_rocks_int
\prop_new:c { g_fejoia_rocks_ \int_to_arabic:n { \g_fejoia_rocks_int } _prop }
\prop_gput:cno
{ g_fejoia_rocks_ \int_to_arabic:n { \g_fejoia_rocks_int } _prop }
{ SampleName } { \csvcoli }
\prop_gput:cno
{ g_fejoia_rocks_ \int_to_arabic:n { \g_fejoia_rocks_int } _prop }
{ DepthOne } { \csvcolii }
\prop_gput:cno
{ g_fejoia_rocks_ \int_to_arabic:n { \g_fejoia_rocks_int } _prop }
{ DepthTwo } { \csvcoliii }
\prop_gput:cno
{ g_fejoia_rocks_ \int_to_arabic:n { \g_fejoia_rocks_int } _prop }
{ DepthThree } { \csvcoliv }
}
}
\int_new:N \g_fejoia_rocks_int
\DeclareExpandableDocumentCommand{\getrock}{mm}
{
\prop_item:cn { g_fejoia_rocks_#1_prop } { #2 }
}
\ExplSyntaxOff

\rocks{\jobname.csv}

\begin{document}

\csvautotabular{\jobname.csv}

\bigskip

\section{First rock}
The rock sampled was called \getrock{1}{SampleName}.

\ifnum\getrock{1}{DepthOne}>0
The first sample hole was drilled to \SI{\getrock{1}{DepthOne}}{\mm}
\fi

\ifnum\getrock{1}{DepthThree}>0
The third sample hole was drilled to \SI{\getrock{1}{DepthThree}}{\mm}
\fi

\section{Second rock}
The rock sampled was called \getrock{2}{SampleName}.

\ifnum\getrock{2}{DepthOne}>0
The first sample hole was drilled to \SI{\getrock{2}{DepthOne}}{\mm}
\fi

\ifnum\getrock{2}{DepthThree}>0
The third sample hole was drilled to \SI{\getrock{2}{DepthThree}}{\mm}
\fi

\end{document}


• What happens when I wish to access the \samplename label outside the \csvreader context? I have the \csvreader in a separate style file and I create labels for each data point, which I intend to access throughout the document. – fejoa Feb 9 '17 at 23:43
• @wryan Probably you want to look at datatool. Do you have different files for each sample? – egreg Feb 9 '17 at 23:48
• I can cause my system to look at one csv file per sample rather than store everything in one csv. This post on using datatool with csv really helped – fejoa Feb 10 '17 at 1:52