2

I am trying to create a mental math practice sheet generator in a latex editor. For the number of questions intended, I require only half of A4 sheet. So the other half I want to print the same set of questions for another student.

In excel we can simply copy the values of a cell into another to duplicate. How do I duplicate all the questions containing randomly generated numbers.

I have the syntax for the questions. Just need help with duplicating part. Thanks.

\tikzset{declare function={randomfixed(\a,\b) = int(random(0,int(\b-\a))+\a);}}

% get random integer
\newcommand\randomint[2]{\bgroup%
  \pgfmathsetmacro\myval{randomfixed(#1,#2)}%
  \pgfmathsetmacro\final{(\myval < 0)?"(\myval)":\myval}%
  \final\egroup%
}

\newcommand{\randnzi}{%random non-zero integer, change random (argument) to increase or decreases range
    \pgfmathsetmacro{\a}{int(ifthenelse(rand > 0, 1, -1)*random(1,9))}%
}

% get random integer for equation - the only diff from \randomint is that this one doesn't generate () for negative numbers
\newcommand\randomeqint[2]{\bgroup%
  \pgfmathsetmacro\myval{randomfixed(#1,#2)}%
  \pgfmathsetmacro\final{(\myval < 0)?"\myval":\myval}%
  \final\egroup%
}
% get random operator
\def\ops{{"+","-","\times","/"}}
\def\pmop{{"+","-"}}
\newcommand\randomop{\bgroup\pgfmathsetmacro\op{\ops[int(rnd*4)]}\op\egroup}

%get random + or - only
\newcommand\randompm{{\bgroup\pgfmathsetmacro\op{\pmop[int(rnd*2)]}\op\egroup}}
% choose random seed
\pgfmathsetseed{\pdfuniformdeviate 10000000}


\begin{document}
\foreach \n in {1,...,5}{
   $\randomint{-10}{10} \randomop{} \randomint{-10}{10} = $\par
   %\par is used in for loop to create a linebreak after each iteration
}
rhlchd
  • 21
  • 2
    save the random number in a macro, or rather set the random seed identically (now that I see it is a whole series you want replicated) –  Jan 14 '19 at 10:34
  • Thanks for the answer @jfbu but I am fairly new to latex. Don't know macro too well. If you could provide me with easy resource to read on macro, I would be very grateful. Thanks. – rhlchd Jan 14 '19 at 16:59
  • "macro" is a generic name, LaTeX "commands" are macros. But what you are lacking is knowledge of \let or \edef which are not described usually in LaTeX books. But this is what is needed here simply to store once and for all a given random seed in a "macro" and use it after, see my answer. –  Jan 14 '19 at 17:04

2 Answers2

6

It would be easier if you had provided a usable test file but if I understand your question you could replace

\foreach \n in {1,...,5}{
   $\randomint{-10}{10} \randomop{} \randomint{-10}{10} = $\par
   %\par is used in for loop to create a linebreak after each iteration
}

by

\sbox0{$\randomint{-10}{10} \randomop{} \randomint{-10}{10} = $}
\foreach \n in {1,...,5}{
   \usebox{0}\par
   %\par is used in for loop to create a linebreak after each iteration
}

To get 5 identical copies.


As jfbu has provided a test file here is the same technique but this time boxing the entire list and re-using. here I used a parbox of width \textwidth for a vertical repetition, you could make the parbox narrower and lay out horizontal copies.

enter image description here

\documentclass{article}

\usepackage{tikz}

\tikzset{declare function={randomfixed(\a,\b) = int(random(0,int(\b-\a))+\a);}}

% get random integer
\newcommand\randomint[2]{\bgroup%
  \pgfmathsetmacro\myval{randomfixed(#1,#2)}%
  \pgfmathsetmacro\final{(\myval < 0)?"(\myval)":\myval}%
  \final\egroup%
}

\newcommand{\randnzi}{%random non-zero integer, change random (argument) to increase or decreases range
    \pgfmathsetmacro{\a}{int(ifthenelse(rand > 0, 1, -1)*random(1,9))}%
}

% get random integer for equation - the only diff from \randomint is that this one doesn't generate () for negative numbers
\newcommand\randomeqint[2]{\bgroup%
  \pgfmathsetmacro\myval{randomfixed(#1,#2)}%
  \pgfmathsetmacro\final{(\myval < 0)?"\myval":\myval}%
  \final\egroup%
}
% get random operator
\def\ops{{"+","-","\times","/"}}
\def\pmop{{"+","-"}}
\newcommand\randomop{\bgroup\pgfmathsetmacro\op{\ops[int(rnd*4)]}\op\egroup}

%get random + or - only
\newcommand\randompm{{\bgroup\pgfmathsetmacro\op{\pmop[int(rnd*2)]}\op\egroup}}
% choose random seed
\pgfmathsetseed{\pdfuniformdeviate 10000000}


\begin{document}


\sbox0{\parbox{\textwidth}{%
\foreach \n in {1,...,5}{
   $\randomint{-10}{10} \randomop{} \randomint{-10}{10} = $\par
   %\par is used in for loop to create a linebreak after each iteration
}
}}

Answer this:

\noindent\usebox{0}

\bigskip

You fool, try again:

\noindent\usebox{0}


\end{document}
David Carlisle
  • 757,742
  • I don't think this is what was asked by OP. –  Jan 14 '19 at 16:02
  • @jfbu I had trouble understanding the question, but anyway the basic technique of putting the random text in a box and re-using the box answers the question even if I duplicated the wrong text. But I'll delete if it's definitely the wrong answer, OP to confirm... – David Carlisle Jan 14 '19 at 16:06
  • In such cases don't moderators automatically hand over a share of your reps to @jfbu ? –  Jan 14 '19 at 16:07
  • Thanks @DavidCarlisle for the effort but you are duplicating a random number 5 times one after another. That solves the problem in strict technical sense. But it does not help in obtaining the duplicate of a random number(s) many lines down the page. Think like this: I need to store the random number in a variable & print the variable in any two different places on the page. And many different variables containing different random numbers are to be printed in different places like a linear equation or algebraic expressions. But two of each question in a single A4 page on either half. – rhlchd Jan 14 '19 at 16:58
  • @rhlchd you can use as many boxes as you like and display the content as often as you need, so you can for example typeset your whole question sheet into a box and then re-use that box multiple times, but as you did not provide a test file just a large but unusable code fragment it wasn't clear to me exactly what you wanted to duplicate. – David Carlisle Jan 14 '19 at 17:25
  • @jfbu no....... – David Carlisle Jan 14 '19 at 17:26
  • terribly unfair, and worse you are not going to delete your answer obviously (after "borrowing" my minimal example) :) –  Jan 14 '19 at 23:04
  • Thank you @DavidCarlisle the box syntax is working like a charm for my requirement. Thanks a ton! Sorry I did not provide the actual use case for this query. The code that I have submitted is just the random number generator. The actual questions are of algebra where we pull in these random numbers to construct linear and quadratic equations and similar tasks for students. – rhlchd Jan 15 '19 at 12:20
2
\documentclass{article}

\usepackage{tikz}

\tikzset{declare function={randomfixed(\a,\b) = int(random(0,int(\b-\a))+\a);}}

% get random integer
\newcommand\randomint[2]{\bgroup%
  \pgfmathsetmacro\myval{randomfixed(#1,#2)}%
  \pgfmathsetmacro\final{(\myval < 0)?"(\myval)":\myval}%
  \final\egroup%
}

\newcommand{\randnzi}{%random non-zero integer, change random (argument) to increase or decreases range
    \pgfmathsetmacro{\a}{int(ifthenelse(rand > 0, 1, -1)*random(1,9))}%
}

% get random integer for equation - the only diff from \randomint is that this one doesn't generate () for negative numbers
\newcommand\randomeqint[2]{\bgroup%
  \pgfmathsetmacro\myval{randomfixed(#1,#2)}%
  \pgfmathsetmacro\final{(\myval < 0)?"\myval":\myval}%
  \final\egroup%
}
% get random operator
\def\ops{{"+","-","\times","/"}}
\def\pmop{{"+","-"}}
\newcommand\randomop{\bgroup\pgfmathsetmacro\op{\ops[int(rnd*4)]}\op\egroup}

%get random + or - only
\newcommand\randompm{{\bgroup\pgfmathsetmacro\op{\pmop[int(rnd*2)]}\op\egroup}}
% choose random seed
\edef\myrandomseed{\pdfuniformdeviate 10000000}

\usepackage{multicol}
\begin{document}
\begin{multicols}2
\pgfmathsetseed{\myrandomseed}
Answer this:\par
  \foreach \n in {1,...,5}{
   $\randomint{-10}{10} \randomop{} \randomint{-10}{10} = $\par
   %\par is used in for loop to create a linebreak after each iteration
}
\columnbreak
\pgfmathsetseed{\myrandomseed}

You fool, try again:\par
\foreach \n in {1,...,5}{
   $\randomint{-10}{10} \randomop{} \randomint{-10}{10} = $\par
   %\par is used in for loop to create a linebreak after each iteration
}
\end{multicols}

\end{document}

enter image description here

  • this looks promising will keep you updated :) Thanks – rhlchd Jan 14 '19 at 17:02
  • @rhlchd the only addition to your code is \edef\myrandomseed{\pdfuniformdeviate 10000000} which defines \myrandomseed and uses it afterwards. –  Jan 14 '19 at 17:04
  • Thanks I borrowed your test file:-) (@rhlchd) – David Carlisle Jan 14 '19 at 19:47
  • Thanks to you too @jfbu for your solution. Will try it too. Multicol looks good to duplicate as a textbook layout. This is promising too :) – rhlchd Jan 15 '19 at 12:46