# Reproducibly generating unique numbers

I'm doing a software specification in LaTeX and it is considered best practice to assign a unique number to each requirement. Chapter numbers are not an option for this, because those numbers have to stay the same even if I new requirements are added in the middle of the existing ones.

The only option I see so far is to assign those numbers manually. But this does not guaranty uniqueness and becomes messy at the point multiple persons are involved.

Do you have any suggestions?

-
If anyone has an idea how to properly tag this question, please do so. –  h0b0 Jun 22 '12 at 6:47
Date plus time? –  Ryan Reich Jun 22 '12 at 7:02
@RyanReich I like the no-tech approach, but this wouldn't prevent to people working on the document at the same time from adding the same key. –  h0b0 Jun 22 '12 at 7:11
Well, if you don't want to do something manually, that is, having some unique key as a parameter, and you can't use the order, then only the requirement itself remains as that by which any algorithm can recognise the requirement. It would certainly be possible to turn the requirement into some kind of hash but that means that the slightest change to it afterwards can change the assigned number, too. You probably don't want that either. So I think what you wish for is as such impossible. You have to ease your wishes somewhere. Of course an external script could do the "manual" part for you. –  Christian Jun 22 '12 at 7:29
If each author has an unique id, you can use a concatenation: id+year+month+day+hour+min+sec. –  Paul Gaborit Jun 22 '12 at 7:31

## Better Solution:

I would recommend that each requirement be manually labelled, and ensure that duplicates are not used. The MWE below produces:

but if you had accidentally used the same environment label (ie, if the last one was used as \begin{Requirement}{1}, this produces:

Package Requirement Error: Duplicate Requirement: 1.

so the author would be made aware that a different requirement label needed to be used.

This version is based on Ulrike Fischer's suggestion:

## Code:

\documentclass{article}
\usepackage{xstring}

\newcommand\CheckForDuplicateRequirement[1]{%
\ifcsname Requirement#1\endcsname %
\PackageError{Requirement}{Duplicate Requirement: #1}{}%
\else%
\expandafter\gdef\csname Requirement#1\endcsname{}%
\fi%
}

\newenvironment{Requirement}[1]{%
\CheckForDuplicateRequirement{#1}%
\textbf{Requirement #1:}%
}{%
}%

\begin{document}

\begin{Requirement}{1}
This is the first requirement
\end{Requirement}

\begin{Requirement}{X}
This is the second requirement
\end{Requirement}

\begin{Requirement}{Z}
This is the third requirement
\end{Requirement}
\end{document}


## Old Solution:

This solution builds a list of the references using How keep a running list of strings and then process them one at a time, and issues a \PackageError if a duplicate requirement label is provided

## Notes:

• With this approach, the labels can be numbers and/or letters but should not contain <, or > as I use that as a delimiter for the strings. This is to ensure that test works properly for labels that are sub-strings of other labels. Previous version would have reported a duplicate if the label was XX was used followed by X.

## Code:

\documentclass{article}
\usepackage{xstring}

\newcommand\RequirementList{}
\newcommand\CheckForDuplicateRequirement[1]{%
\StrPosition{\RequirementList}{<#1>}[\Position]
\IfEq{\Position}{0}{%
\global\edef\RequirementList{\RequirementList<#1>}%
}{%
\PackageError{Requirement}{Duplicate Requirement: #1}{}%
}%
}

\newenvironment{Requirement}[1]{%
\CheckForDuplicateRequirement{#1}%
\textbf{Requirement #1:}%
}{%
}%

\begin{document}

\begin{Requirement}{1}
This is the first requirement
\end{Requirement}

\begin{Requirement}{X}
This is the second requirement
\end{Requirement}

\begin{Requirement}{Z}
This is the third requirement
\end{Requirement}
\end{document}

-
I do find the idea to generate (and go through) a growing list of key names a bit dubious. Why don't you use the way labels test if they are multiply defined: Define \csname requkey@#1\endcsname and test for this. –  Ulrike Fischer Jun 22 '12 at 9:57
@UlrikeFischer: I had tried that before resorting to a list, but had difficulty. I thought it was due to numbers in the \csname, but turns out I was missing the third parameter to \PackageError, but somehow that did not cause any problem in the list version. :-). Thanks for prompting me to look into it further and have provided a solution as per your suggestion. –  Peter Grill Jun 22 '12 at 22:57