0

I would like to implement a worksheet generator in Latex with the following features:

  1. It should contain commands to generate addition, subtraction, multiplication and division exercises with random integers. Division exercises should not contain remainders and brackets should be set automatically if necessary.
  2. Moreover, it should also provide a command to generate multiplication and division exercises with a random decimal and a random multiple of 10 (e. g. 1,52 x 1000).

This is what I have tried so far:

\documentclass{article}
\usepackage{tikz}
\usepackage{tasks}
\settasks{label-width=4ex}
\usepackage{ifthen}
\pgfmathsetseed{\number\pdfrandomseed}

\newcommand*{\NewNumbers}{% \pgfmathsetmacro{\A}{random(-10, 50)} \pgfmathsetmacro{\B}{random(-10, 10)} }

\newcommand{\addition}{ \NewNumbers \setcounter{firstNumber}{\A} \setcounter{secondNumber}{\B} \ifthenelse{\A < 0 \AND \B < 0}{
$(\thefirstNumber) + (\thesecondNumber)$}{} \ifthenelse{\A < 0 \AND \B > 0}{ $(\thefirstNumber) + \thesecondNumber$}{} \ifthenelse{\A > 0 \AND \B < 0}{ $\thefirstNumber + (\thesecondNumber)$}{} \ifthenelse{\A > 0 \AND \B > 0}{ $\thefirstNumber + \thesecondNumber$}{} }

\newcommand{\division}{ \NewNumbers \setcounter{firstNumber}{\A} \setcounter{secondNumber}{\B} \multiply \value{firstNumber} by \value{secondNumber} \ifthenelse{\A < 0 \AND \B < 0}{
$(\thefirstNumber) : (\thesecondNumber)$}{} \ifthenelse{\A < 0 \AND \B > 0}{ $(\thefirstNumber) : \thesecondNumber$}{} \ifthenelse{\A > 0 \AND \B < 0}{ $\thefirstNumber : (\thesecondNumber)$}{} \ifthenelse{\A > 0 \AND \B > 0}{ $\thefirstNumber : \thesecondNumber$}{} }

\newcommand{\subtraction}{ \NewNumbers \setcounter{firstNumber}{\A} \setcounter{secondNumber}{\B} \ifthenelse{\A < 0 \AND \B < 0}{
$(\thefirstNumber) - (\thesecondNumber)$}{} \ifthenelse{\A < 0 \AND \B > 0}{ $(\thefirstNumber) - \thesecondNumber$}{} \ifthenelse{\A > 0 \AND \B < 0}{ $\thefirstNumber - (\thesecondNumber)$}{} \ifthenelse{\A > 0 \AND \B > 0}{ $\thefirstNumber - \thesecondNumber$}{} }

\newcommand{\multiplication}{ \NewNumbers \setcounter{firstNumber}{\A} \setcounter{secondNumber}{\B} \ifthenelse{\A < 0 \AND \B < 0}{
$(\thefirstNumber) \cdot (\thesecondNumber)$}{} \ifthenelse{\A < 0 \AND \B > 0}{ $(\thefirstNumber) \cdot \thesecondNumber$}{} \ifthenelse{\A > 0 \AND \B < 0}{ $\thefirstNumber \cdot (\thesecondNumber)$}{} \ifthenelse{\A > 0 \AND \B > 0}{ $\thefirstNumber \cdot \thesecondNumber$}{} }

\newcounter{firstNumber} \newcounter{secondNumber}

\begin{document} \begin{tasks}(3) \task \multiplication \task \subtraction \task \addition %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \task \division \task \multiplication \task \division %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \task \addition \task \subtraction \task \division \end{tasks} \end{document}

This approach basically meets the first named requirement. However, there is a problem with the aligment of the actual exercise and the labels generated by the task-command. I cannot change the distance between them by using the options which are provided by the tasks package and I actually would like to align every single exercise flush left at the same point.

I do not see a possible solution when it comes to the second requirement since I could not find any possibility to use decimal variables I can calculate with.

I adapted Mico's version to use negative numbers, too, and to make sure that brackets are placed if necessary. This leads to the following version which is working quite well:

% !TeX program = lualatex

%% First, some code from the original posting, streamlined. \documentclass[a4paper,landscape,12pt]{article} \usepackage{newpxtext,newpxmath} % newer than mathpazo \usepackage[hmargin=2.5cm, tmargin=1.5cm]{geometry} \usepackage[lastpage]{zref} \usepackage{fancyhdr,background} \backgroundsetup{ contents = , scale = 1, color = black, angle = 0, opacity = 1, position = current page.north west, vshift = -2.02cm, hshift = 5cm } \pagestyle{fancy} \renewcommand\headrulewidth{0pt} \setlength\headheight{14.5pt} \makeatletter \zref@newprop{numpage}{\the\value{page}} \zref@addprop{main}{numpage} \fancyhf{} \fancyfoot[C]{% \ifnum \zref@extractdefault{LastPage}{numpage}{0} > 1 \thepage \fi} \makeatother

%% Now the new material (mostly Lua code)

\usepackage{array,longtable} \newcolumntype{R}{>{$}r<{$}} % right-aligned, math mode \newcolumntype{C}{>{${}}c<{{}$}} % centered, math mode \setlength\extrarowheight{0.85ex} % extra vert. space \setlength\tabcolsep{0pt}

\usepackage{luacode} \begin{luacode} -- First, some variables and auxiliary functions

n1 = 20       -- max integer in addition and subtract. ops
n3 = -30      -- min integer in addition and subtract. ops
n4 = -10      -- min integer in multiplication ops.
n2 = 9       -- max integer in multiplication ops.
n5 = -30      -- min integer in division ops.
n6 = 10       -- max integer in division ops.
nrows = 40    -- number of rows per longtable (20 rows per page)
xtra_sp = &quot;1.5ex&quot; -- extra whitespace after every 5th row

-- What to place at the _end_ of each table cell?
function cell_terminate(i,j) -- i: 1..nrows; j: 1..5
if j&lt;5 then 
tex.sprint ( &quot;&amp;&quot; ) 
elseif i%5==0 then -- extra space after every 5th row
tex.sprint ( &quot;\\\\[&quot; .. xtra_sp .. &quot;]&quot; )
else 
tex.sprint ( &quot;\\\\&quot; )
end
end

-- The following eight functions do the actual work of
-- calculating the cells and outputting them into `longtable` env.'s

-- Addition
function questions_Addition ()
math.randomseed(123456789) -- select a suitable seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;+&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;={}&quot; )
else
tex.sprint ( x1 .. &quot;+&quot; .. x2 ..&quot;={}&quot; ) 
end
cell_terminate(i,j)
end
end
end
function answers_Addition ()
math.randomseed(123456789) -- re-use the same seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;+&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;&amp;=&amp;&quot; .. x1 + x2 )
else
tex.sprint ( x1 .. &quot;+&quot; .. x2 ..&quot;&amp;=&amp;&quot; .. x1 + x2 )
end
cell_terminate(i,j)
end
end
end

-- Subtraction
function questions_Subtraction ()
math.randomseed(123456789) -- select a suitable seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;-&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;={}&quot; )
else
tex.sprint ( x1 .. &quot;-&quot; .. x2 ..&quot;={}&quot; )
end 
cell_terminate(i,j)
end
end
end
function answers_Subtraction ()
math.randomseed(123456789) -- re-use the same seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;-&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;&amp;=&amp;&quot; .. x1 - x2 )
else
tex.sprint ( x1 .. &quot;-&quot; .. x2 ..&quot;&amp;=&amp;&quot; .. x1 - x2 )
end 
cell_terminate(i,j)
end
end
end

-- Multiplication
function questions_Multiplication ()
math.randomseed(123456789) -- select a suitable seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n4,n2)
x2 = math.random(n4,n2)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;\\cdot&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; .. &quot;={}&quot; )
else
tex.sprint ( x1 .. &quot;\\cdot&quot; .. x2 .. &quot;={}&quot; )
end 
cell_terminate(i,j)
end
end
end
function answers_Multiplication ()
math.randomseed(123456789) -- re-use the same seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n4,n2)
x2 = math.random(n4,n2)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;\\cdot&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; .. &quot;&amp;=&amp;&quot; .. x1*x2 )
else
tex.sprint ( x1 .. &quot;\\cdot&quot; .. x2 .. &quot;&amp;=&amp;&quot; .. x1*x2 ) 
end
cell_terminate(i,j)
end
end
end

-- Division
function questions_Division ()
math.randomseed(123456789) -- select a suitable seed
local x1, x2, y
for i=1,nrows do
for j=1,5 do
x1 = math.random(n5,n6) -- divisor
x2 = math.random(n5,n6) -- quotient (&quot;result&quot;)
y  = x1 * x2
if x1&lt;0 then
tex.sprint ( y..&quot;:&quot;.. &quot;(&quot; .. x1.. &quot;)&quot; ..&quot;={}&quot; )
else
tex.sprint ( y..&quot;:&quot;..x1..&quot;={}&quot; )
end 
cell_terminate(i,j)
end
end
end
function answers_Division ()
math.randomseed(123456789) -- re-use the same seed
local x1, x2, y
for i=1,nrows do
for j=1,5 do
x1 = math.random(n5,n6) -- divisor
x2 = math.random(n5,n6) -- quotient (&quot;result&quot;)
y  = x1 * x2
if x1&lt;0 then
tex.sprint ( y.. &quot;:&quot; .. &quot;(&quot; .. x1 .. &quot;)&quot; .. &quot;&amp;=&amp;&quot; .. x2 )
else
tex.sprint ( y.. &quot;:&quot; .. x1 .. &quot;&amp;=&amp;&quot; .. x2 )
end 
cell_terminate(i,j)
end
end
end

\end{luacode}

%% Latex code for question and answer longtables \newcommand\TableQ[1]{% \begin{longtable}{@{} *{4}{R@{\hspace{2.75cm}}} R @{}} \bigskip\endfirsthead \bigskip\bigskip\endhead \directlua{questions_#1()} \end{longtable}}

\newcommand\TableA[1]{% \begin{longtable}{@{} *{4}{RCR@{\hspace{2.25cm}}} RCR @{}} \bigskip\endfirsthead \bigskip\bigskip\endhead \directlua{answers_#1()} \end{longtable}}

%% Headers above question and answer tables \newcommand\HeaderQ[1]{% \clearpage \noindent Name: \underline{\hspace{10em}}\hfill% {\Huge\textbf{Training -- #1}}\hfill% \phantom{Name: \underline{\hspace{10em}}}}

\newcommand\HeaderA[1]{% \clearpage \begin{center} \Huge\textbf{Answers -- #1} \end{center}}

\begin{document} %% the macros \TableQ and \TableA invoke the Lua functions

%%%% Addition \HeaderQ{Addition} \TableQ{Addition} \HeaderA{Addition} \TableA{Addition}

%%%% Subtraction \HeaderQ{Subtraction} \TableQ{Subtraction} \HeaderA{Subtraction} \TableA{Subtraction}

%%%% Multiplication \HeaderQ{Multiplication} \TableQ{Multiplication} \HeaderA{Multiplication} \TableA{Multiplication}

%%%% Division \HeaderQ{Division} \TableQ{Division} \HeaderA{Division} \TableA{Division}

\end{document}

I also tried to extend the function which generates the division exercises to generate division exercises with decimals and a random multiple of 10. However, since I'm not familiar with Lua at all I can't understand the occuring errors when I use this version:

% !TeX program = lualatex

%% First, some code from the original posting, streamlined. \documentclass[a4paper,landscape,12pt]{article} \usepackage{newpxtext,newpxmath} % newer than mathpazo \usepackage[hmargin=2.5cm, tmargin=1.5cm]{geometry} \usepackage[lastpage]{zref} \usepackage{fancyhdr,background} \backgroundsetup{ contents = , scale = 1, color = black, angle = 0, opacity = 1, position = current page.north west, vshift = -2.02cm, hshift = 5cm } \pagestyle{fancy} \renewcommand\headrulewidth{0pt} \setlength\headheight{14.5pt} \makeatletter \zref@newprop{numpage}{\the\value{page}} \zref@addprop{main}{numpage} \fancyhf{} \fancyfoot[C]{% \ifnum \zref@extractdefault{LastPage}{numpage}{0} > 1 \thepage \fi} \makeatother

%% Now the new material (mostly Lua code)

\usepackage{array,longtable} \newcolumntype{R}{>{$}r<{$}} % right-aligned, math mode \newcolumntype{C}{>{${}}c<{{}$}} % centered, math mode \setlength\extrarowheight{0.85ex} % extra vert. space \setlength\tabcolsep{0pt}

\usepackage{luacode} \begin{luacode} -- First, some variables and auxiliary functions

n1 = 20       -- max integer in addition and subtract. ops
n3 = -30      -- min integer in addition and subtract. ops
n4 = -10      -- min integer in multiplication ops.
n2 = 9       -- max integer in multiplication ops.
n5 = -30      -- min integer in division ops.
n6 = 10       -- max integer in division ops.
nrows = 40    -- number of rows per longtable (20 rows per page)
xtra_sp = &quot;1.5ex&quot; -- extra whitespace after every 5th row

-- What to place at the _end_ of each table cell?
function cell_terminate(i,j) -- i: 1..nrows; j: 1..5
if j&lt;5 then 
tex.sprint ( &quot;&amp;&quot; ) 
elseif i%5==0 then -- extra space after every 5th row
tex.sprint ( &quot;\\\\[&quot; .. xtra_sp .. &quot;]&quot; )
else 
tex.sprint ( &quot;\\\\&quot; )
end
end

-- The following eight functions do the actual work of
-- calculating the cells and outputting them into `longtable` env.'s

-- Addition
function questions_Addition ()
math.randomseed(123456789) -- select a suitable seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;+&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;={}&quot; )
else
tex.sprint ( x1 .. &quot;+&quot; .. x2 ..&quot;={}&quot; ) 
end
cell_terminate(i,j)
end
end
end
function answers_Addition ()
math.randomseed(123456789) -- re-use the same seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;+&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;&amp;=&amp;&quot; .. x1 + x2 )
else
tex.sprint ( x1 .. &quot;+&quot; .. x2 ..&quot;&amp;=&amp;&quot; .. x1 + x2 )
end
cell_terminate(i,j)
end
end
end

-- Subtraction
function questions_Subtraction ()
math.randomseed(123456789) -- select a suitable seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;-&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;={}&quot; )
else
tex.sprint ( x1 .. &quot;-&quot; .. x2 ..&quot;={}&quot; )
end 
cell_terminate(i,j)
end
end
end
function answers_Subtraction ()
math.randomseed(123456789) -- re-use the same seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n3,n1)
x2 = math.random(n3,n1)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;-&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; ..&quot;&amp;=&amp;&quot; .. x1 - x2 )
else
tex.sprint ( x1 .. &quot;-&quot; .. x2 ..&quot;&amp;=&amp;&quot; .. x1 - x2 )
end 
cell_terminate(i,j)
end
end
end

-- Multiplication
function questions_Multiplication ()
math.randomseed(123456789) -- select a suitable seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n4,n2)
x2 = math.random(n4,n2)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;\\cdot&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; .. &quot;={}&quot; )
else
tex.sprint ( x1 .. &quot;\\cdot&quot; .. x2 .. &quot;={}&quot; )
end 
cell_terminate(i,j)
end
end
end
function answers_Multiplication ()
math.randomseed(123456789) -- re-use the same seed
for i=1,nrows do
for j=1,5 do
x1 = math.random(n4,n2)
x2 = math.random(n4,n2)
if x2&lt;0 then
tex.sprint ( x1 .. &quot;\\cdot&quot; .. &quot;(&quot; .. x2 .. &quot;)&quot; .. &quot;&amp;=&amp;&quot; .. x1*x2 )
else
tex.sprint ( x1 .. &quot;\\cdot&quot; .. x2 .. &quot;&amp;=&amp;&quot; .. x1*x2 ) 
end
cell_terminate(i,j)
end
end
end

-- Division
function questions_Division ()
math.randomseed(123456789) -- re-use the same seed
local x1, x2, y, z, w
for i=1,nrows do
for j=1,5 do
w = math.random(0,1)
if w == 1 then
x1 = math.random(n5,n6) -- divisor
x2 = math.random(n5,n6) -- quotient (&quot;result&quot;)
y  = x1 * x2
else
z = math.random(1,5)
x1 = 10^z -- divisor
x2 = math.random(1, 4000) / 10^z -- quotient (&quot;result&quot;)
y  = x1 * x2
if x1&lt;0 then
tex.sprint ( y..&quot;:&quot;.. &quot;(&quot; .. x1.. &quot;)&quot; ..&quot;={}&quot; )
else
tex.sprint ( y..&quot;:&quot;..x1..&quot;={}&quot; )
end
cell_terminate(i,j)
end
end
end
end
function answers_Division ()
math.randomseed(123456789) -- re-use the same seed
local x1, x2, y, z, w
for i=1,nrows do
for j=1,5 do
w = math.random(0,1)
if w == 1 then
x1 = math.random(n5,n6) -- divisor
x2 = math.random(n5,n6) -- quotient (&quot;result&quot;)
y  = x1 * x2
else
z = math.random(1,5)
x1 = 10^z -- divisor
x2 = math.random(1, 4000) / 10^z -- quotient (&quot;result&quot;)
y  = x1 * x2
if x1&lt;0 then
tex.sprint ( y.. &quot;:&quot; .. &quot;(&quot; .. x1 .. &quot;)&quot; .. &quot;&amp;=&amp;&quot; .. x2 )
else
tex.sprint ( y.. &quot;:&quot; .. x1 .. &quot;&amp;=&amp;&quot; .. x2 )
end
cell_terminate(i,j)
end
end
end
end

\end{luacode}

%% Latex code for question and answer longtables \newcommand\TableQ[1]{% \begin{longtable}{@{} *{4}{R@{\hspace{2.75cm}}} R @{}} \bigskip\endfirsthead \bigskip\bigskip\endhead \directlua{questions_#1()} \end{longtable}}

\newcommand\TableA[1]{% \begin{longtable}{@{} *{4}{RCR@{\hspace{2.25cm}}} RCR @{}} \bigskip\endfirsthead \bigskip\bigskip\endhead \directlua{answers_#1()} \end{longtable}}

%% Headers above question and answer tables \newcommand\HeaderQ[1]{% \clearpage \noindent Name: \underline{\hspace{10em}}\hfill% {\Huge\textbf{Training -- #1}}\hfill% \phantom{Name: \underline{\hspace{10em}}}}

\newcommand\HeaderA[1]{% \clearpage \begin{center} \Huge\textbf{Answers -- #1} \end{center}}

\begin{document} %% the macros \TableQ and \TableA invoke the Lua functions

%%%% Addition \HeaderQ{Addition} \TableQ{Addition} \HeaderA{Addition} \TableA{Addition}

%%%% Subtraction \HeaderQ{Subtraction} \TableQ{Subtraction} \HeaderA{Subtraction} \TableA{Subtraction}

%%%% Multiplication \HeaderQ{Multiplication} \TableQ{Multiplication} \HeaderA{Multiplication} \TableA{Multiplication}

%%%% Division \HeaderQ{Division} \TableQ{Division} \HeaderA{Division} \TableA{Division}

\end{document}

0 Answers0