0

With help from Schrodinger's Cat, I was able to create a macro for making a cube block prism. I also want to be able to have the definitions of width, height, depth initiated in the macro to continue to the calculation in a table. I can't put the table in the macro because I don't always need the calculation(It's blank for students)

Here is my code:

    \documentclass[12pt]{examdesign}
\usepackage{amsmath}
\usepackage[utf8]{inputenc}
\usepackage{tikz,ifthen,tikz-3dplot}
\usepackage{tkz-euclide}
\usetkzobj{all}  %%%because I'm using overleaf
\usetikzlibrary{quotes,angles,decorations}
\usetikzlibrary{shapes.geometric,calc}
\class{Needed for examdesign}

%%%%%%%%%%%%%%%%%%%%%% tikz set for cube%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\cubelength}{0.93}
\tikzset{
  cube/.pic={
    \draw[] (0,0,0) -- (0,\cubelength,0) -- (\cubelength,\cubelength,0) -- (\cubelength,0,0) -- cycle;
    %draw the back-right of the cube
    \draw[] (0,0,0) -- (0,\cubelength,0) -- (0,\cubelength,\cubelength) -- (0,0,\cubelength) -- cycle;
    %draw the back-left of the cube
    \draw[] (0,0,0) -- (\cubelength,0,0) -- (\cubelength,0,\cubelength) -- (0,0,\cubelength) -- cycle;
    %draw the front-right of the cube
    \draw[fill=magenta!50] (\cubelength,0,0) -- (\cubelength,\cubelength,0) -- (\cubelength,\cubelength,\cubelength) -- (\cubelength,0,\cubelength)-- cycle;
    %draw the front-left of the cube
    \draw[fill=orange!50] (0,\cubelength,0) -- (\cubelength,\cubelength,0) -- (\cubelength,\cubelength,\cubelength) -- (0,\cubelength,\cubelength) -- cycle;
    %draw the top of the cube
    \draw[fill=cyan!50] (0,0,\cubelength) -- (0,\cubelength,\cubelength) -- (\cubelength,\cubelength,\cubelength) -- (\cubelength,0,\cubelength) -- cycle;        
            }
        }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %%To draw a cubeblocks object
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Macro for Mystery Hypotenuse cubeblocks
\newcommand{\cubeblocks}[2][]{\resizebox{5cm}{!}{

\begin{tikzpicture}[scale=1,#1,
    cubeblocks/.cd,w/.initial=1,d/.initial=1,unit/.initial=cm,h/.initial=1]
    \tikzset{cubeblocks/.cd,#2}
    \newcommand{\Width}{\pgfkeysvalueof{/tikz/cubeblocks/w}}
    \newcommand{\Depth}{\pgfkeysvalueof{/tikz/cubeblocks/d}}
    \newcommand{\Height}{\pgfkeysvalueof{/tikz/cubeblocks/h}}
\pgfmathsetmacro{\effDepth}{\Depth-1}
\pgfmathsetmacro{\effHeight}{\Height-1}
\pgfmathsetmacro{\effWidth}{\Width-1}
%%%%%draws coordinates
\coordinate (A) at (0,0,0);
\coordinate (B) at (\Width,0,0);
\coordinate (C) at (\Width,0,\Depth);
\coordinate (D) at (0,0,\Depth);
\coordinate (E) at (0,\Height,\Depth);
\coordinate (F) at (0,\Height,0);
\coordinate (G) at (\Width,\Height,0);
\coordinate (H) at (\Width,\Height,\Depth);
\begin{huge}
\draw[<->,blue,>=latex]([xshift=5mm]B)--node[fill=white,xshift=3mm]{$\pgfmathprintnumber\Height\,$\pgfkeysvalueof{/tikz/cubeblocks/unit}}([xshift=5mm]G);
\draw[<->,blue, >=latex]([yshift=-5mm]C)--node[fill=white,yshift=-2mm]{$\pgfmathprintnumber\Width\,$\pgfkeysvalueof{/tikz/cubeblocks/unit}}([yshift=-5mm]D);
\draw[<->,blue]([xshift=5mm,yshift=-2mm]B)--node[xshift=3mm,yshift=-4mm,fill=white]{$\pgfmathprintnumber\Depth\,$\pgfkeysvalueof{/tikz/cubeblocks/unit}}([xshift=5mm,yshift=-2mm]C);
\end{huge}

     \foreach \x in {0,...,\effWidth,\effWidth}{
        \pgfmathifisint{\x}{\pgfmathsetmacro{\myx}{1}}{\pgfmathsetmacro{\myx}{\x-int(\x))}}
     \foreach \y in {0,...,\effHeight,\effHeight}{
        \pgfmathifisint{\y}{\pgfmathsetmacro{\myy}{1}}{\pgfmathsetmacro{\myy}{\y-int(\y))}}
     \foreach \z in {0,...,\effDepth,\effDepth}{
        \pgfmathifisint{\z}{\pgfmathsetmacro{\myz}{1}}{\pgfmathsetmacro{\myz}{\z-int(\z))}}
     \path (\x+1-\myx,\y+1-\myy,\z+1-\myz) 
     pic[z={(-0.5*\myz,-0.5*\myz)},x={(\myx,0)},y={(0,\myy)}] {cube};
    }}}   
    \end{tikzpicture}
    }%%%closes tikzpicture
    }%%%%closes resize box



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \begin{document}
\newcommand{\Width}{3}   %%%%
\newcommand{\Height}{5}
\newcommand{\Depth}{4}
%%\cubeblocks{w=3,d=4,h=5,unit=cm}\\
\pgfmathsetmacro{\baselayer}{\Width*\Depth}
\pgfmathsetmacro{\volume}{\baselayer*\Height}
\renewcommand{\arraystretch}{1}
\hspace{-2cm}\begin{tabular}{|p{4cm}|p{4cm}|}
\hline
    Base Layer Shape and Dimensions &rectangle \\
    \hline
    Base Layer Area & $A=$ \\
    \hline
    Volume of 1 layer & $V=$ \\
    \hline
    Prism Height & Prism height is \\
    \hline
    Volume & $\volume\text {cm}^3$ \\
    \hline
    \end{tabular}

\end{document}

I want to get: cube with table

The problem I get is that it says the commands, width, height and depth are already defined which I get because my macro wants to define them again. What I would like to know is how do I fix my macro to define the width, height, and depth and have those definitions persist for the volume macro in a particular question. Perhaps as Steven suggested, using \let and \relax functions?- but I don't know how to do that.

The reason I feel I have to include the definitions of width, height, depth is that if I don't, \volume seems to have no arguments because I can only guess, it's not able to pull those values from the cubeblocks macro (but I do want them to pull the values from the cubeblocks macro) I should mention that I will be repeating the cubeblocks macro with different values for different student questions.

I am not sure what to do. in Summary: 1. use the cubeblocks macro 2. have the \volume macro work with the width, depth, height values from cubeblocks macro 3. Repeat for other questions with the correct scope.

Thanks all, all advice to fix any of my code is also appreciated.

E.Yu
  • 337
  • In general, you can not \newcommand something that has already been defined. One can use \def rather than \newcommand, which allows redefinitions without error. If you need those values outside of the local group, you can use \gdef for global \def. If you don't like using \def, you can \let them to \relax in your preamble, and then use \renewcommand inside the macro. None of what I said guarantees to fix your issue, if there are other things at work. – Steven B. Segletes Apr 11 '20 at 18:57
  • I appreciate your advice on using \let and \relax but I'm not sure how to do this. Can you help me understand with an example using one of my commands like width? – E.Yu Apr 11 '20 at 19:55
  • I am unable to compile your document without error. But it might be my LaTeX installation. – Steven B. Segletes Apr 11 '20 at 21:23
  • 1
    @StevenB.Segletes You probably just need to comment out the \usetkzobj{all} call (see here)... – frougon Apr 11 '20 at 23:22

1 Answers1

0

As everything that is done by \cubeblocks takes place within a \resizebox, which in turn typesets a box within some local scope, while the box itself also forms a local scope, you cannot get away without some global assignments.

You can use \pgfkeysgetvalue{&langle;full key&rangle;}{&langle;macro&rangle;} for redefining/"(re-)initializing" within the current scope/within the current group the macros \Width, \Depth and \Height according to the values of the keys /tikz/cubeblocks/w / ​/tikz/cubeblocks/d / ​/tikz/cubeblocks/h:

\pgfkeysgetvalue{/tikz/cubeblocks/w}{\Width} will (within the curent scope/group) (re)define the macro \Width to expand to the tokens that form the value of the key /tikz/cubeblocks/w.

\pgfkeysgetvalue{/tikz/cubeblocks/d}{\Depth} will (within the curent scope/group) (re)define the macro \Depth to expand to the tokens that form the value of the key /tikz/cubeblocks/d.

\pgfkeysgetvalue{/tikz/cubeblocks/h}{\Height} will (within the curent scope/group) (re)define the macro \Height to expand to the tokens that form the value of the key /tikz/cubeblocks/h.

If you don't mind redefining \Width, \Depth and \Height globally, you can do \global\let\Width=\Width , \global\let\Depth=\Depth and \global\let\Height=\Height for making global assignments from the redefinitions restricted to the current scope/group—global assignments are not restricted to the current scope/group but apply to all super-ordinate scopes/groups also.

(\let&langle;control-sequence-token&rangle;=&langle;token&rangle; assigns &langle;control-sequence-token&rangle; the meaning which &langle;token&rangle; has at the time of performing the \let-assignment. Prefixing with \global yields that the assignment is not restricted to the current scope/group but applies to all super-ordinate scopes/groups also.)

\documentclass[12pt]{examdesign}
\usepackage{amsmath}
\usepackage[utf8]{inputenc}
\usepackage{tikz,ifthen,tikz-3dplot}
\usepackage{tkz-euclide}
\usetkzobj{all}  %%%because I'm using overleaf
\usetikzlibrary{quotes,angles,decorations}
\usetikzlibrary{shapes.geometric,calc}
\class{Needed for examdesign}

%%%%%%%%%%%%%%%%%%%%%%%%%%% tikz set for cube%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\cubelength}{0.93}
\tikzset{%
  cube/.pic={%
    \draw[] (0,0,0) -- 
            (0,\cubelength,0) -- 
            (\cubelength,\cubelength,0) -- 
            (\cubelength,0,0) -- 
            cycle;
    % draw the back-right of the cube
    \draw[] (0,0,0) -- 
            (0,\cubelength,0) -- 
            (0,\cubelength,\cubelength) -- 
            (0,0,\cubelength) -- 
            cycle;
    % draw the back-left of the cube
    \draw[] (0,0,0) -- 
            (\cubelength,0,0) --
            (\cubelength,0,\cubelength) --
            (0,0,\cubelength) --
            cycle;
    % draw the front-right of the cube
    \draw[fill=magenta!50] (\cubelength,0,0) --
                           (\cubelength,\cubelength,0) --
                           (\cubelength,\cubelength,\cubelength) --
                           (\cubelength,0,\cubelength)--
                           cycle;
    % draw the front-left of the cube
    \draw[fill=orange!50] (0,\cubelength,0) --
                          (\cubelength,\cubelength,0) --
                          (\cubelength,\cubelength,\cubelength) --
                          (0,\cubelength,\cubelength) --
                          cycle;
    % draw the top of the cube
    \draw[fill=cyan!50] (0,0,\cubelength) --
                        (0,\cubelength,\cubelength) --
                        (\cubelength,\cubelength,\cubelength) --
                        (\cubelength,0,\cubelength) --
                        cycle;        
  }%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%To draw a cubeblocks object
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  Macro for Mystery Hypotenuse cubeblocks
\newcommand{\cubeblocks}[2][]{%
  \resizebox{5cm}{!}{ %<- The empty line yields \par - do you want that?

    \begin{tikzpicture}[scale=1,
                        #1,
                        cubeblocks/.cd,
                        w/.initial=1,
                        d/.initial=1,
                        unit/.initial=cm,
                        h/.initial=1
                       ]
    \tikzset{cubeblocks/.cd,#2}
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \pgfkeysgetvalue{/tikz/cubeblocks/w}{\Width}%
    \pgfkeysgetvalue{/tikz/cubeblocks/d}{\Depth}%
    \pgfkeysgetvalue{/tikz/cubeblocks/h}{\Height}%
    \global\let\Width=\Width
    \global\let\Depth=\Depth
    \global\let\Height=\Height
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \pgfmathsetmacro{\effDepth}{\Depth-1}
    \pgfmathsetmacro{\effHeight}{\Height-1}
    \pgfmathsetmacro{\effWidth}{\Width-1}
    %%%%%draws coordinates
    \coordinate (A) at (0,0,0);
    \coordinate (B) at (\Width,0,0);
    \coordinate (C) at (\Width,0,\Depth);
    \coordinate (D) at (0,0,\Depth);
    \coordinate (E) at (0,\Height,\Depth);
    \coordinate (F) at (0,\Height,0);
    \coordinate (G) at (\Width,\Height,0);
    \coordinate (H) at (\Width,\Height,\Depth);
    \begin{huge}
    \draw[<->,blue,>=latex]([xshift=5mm]B)--%
         node[fill=white,xshift=3mm]{%
           $\pgfmathprintnumber\Height\,$%
           \pgfkeysvalueof{/tikz/cubeblocks/unit}%
         }([xshift=5mm]G);
    \draw[<->,blue, >=latex]([yshift=-5mm]C)--%
         node[fill=white,yshift=-2mm]{%
           $\pgfmathprintnumber\Width\,$%
           \pgfkeysvalueof{/tikz/cubeblocks/unit}%
         }([yshift=-5mm]D);
    \draw[<->,blue]([xshift=5mm,yshift=-2mm]B)--%
         node[xshift=3mm,yshift=-0mm,fill=white]{%
           $\pgfmathprintnumber\Depth\,$%
           \pgfkeysvalueof{/tikz/cubeblocks/unit}%
         }([xshift=5mm,yshift=-2mm]C);
    \end{huge} %<- The empty line yields \par - do you want that?

    \foreach \x in {0,...,\effWidth,\effWidth}{%
      \pgfmathifisint{\x}{%
        \pgfmathsetmacro{\myx}{1}%
      }{%
        \pgfmathsetmacro{\myx}{\x-int(\x))}%
      }%
      \foreach \y in {0,...,\effHeight,\effHeight}{%
        \pgfmathifisint{\y}{%
          \pgfmathsetmacro{\myy}{1}%
        }{%
          \pgfmathsetmacro{\myy}{\y-int(\y))}%
        }%
        \foreach \z in {0,...,\effDepth,\effDepth}{%
          \pgfmathifisint{\z}{%
            \pgfmathsetmacro{\myz}{1}%
          }{%
            \pgfmathsetmacro{\myz}{\z-int(\z))}%
          }%
          \path (\x+1-\myx,\y+1-\myy,\z+1-\myz) 
                pic[z={(-0.5*\myz,-0.5*\myz)},x={(\myx,0)},y={(0,\myy)}]
                {cube};
        }%
      }%
    }%
    \end{tikzpicture}%
  }%%%%closes \resizebox
}%%%%closes definition-text

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Scratch-macros for width, height and depth; they get redefined by
% \cubeblocks globally:
\newcommand{\Width}{}  
\newcommand{\Height}{}
\newcommand{\Depth}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

%\begingroup    
\cubeblocks{w=3,d=4,h=5,unit=cm}\\
%\show\Width
%\show\Height
%\show\Depth
%\endgroup
%\show\Width
%\show\Height
%\show\Depth
\pgfmathsetmacro{\baselayer}{\Width*\Depth}%
\pgfmathsetmacro{\volume}{\baselayer*\Height}%
\renewcommand{\arraystretch}{1}%
\hspace{-2cm}%
\begin{tabular}{|p{4cm}|p{4cm}|}
\hline
Base Layer Shape and Dimensions &rectangle \\
\hline
Base Layer Area & $A=$ \\
\hline
Volume of 1 layer & $V=$ \\
\hline
Prism Height & Prism height is \\
\hline
Volume & $\volume\text{cm}^3$ \\
\hline
\end{tabular}

\end{document}


If you wish \Width, \Height and \Depth to be redefined within the current scope only, you can globally define a scratch-macro to redefine \Width, \Height and \Depth within the scope where the scratch-macro gets expanded and then call the scratch-macro in the scope where redefining of \Width, \Height and \Depth shall take place.

If you do this, you need to ensure that the values for \Width, \Height and \Depth get expanded properly.

Not using \edef is a precondition according to the subject-line of the question.
Therefore I suggest using \romannunmeral0-expansion as a means of expansion-control.


The gist of \romannunmeral0-expansion is:

\romannueral works as follows: \romannumeral triggers TeX into converting a TeX-&langle;number-quantitiy&rangle; to a sequence of character-tokens of category-code 12(other) which forms a representation of the TeX-&langle;number-quantitiy&rangle; in question in lowercase-roman notation.

In case TeX "finds" that the number to be converted is not positive, e.g., the number 0, the tokens that form the TeX-&langle;number-quantitiy&rangle; in question get silently "swallowed" and no tokens are delivered in return.

TeX will expand expandable tokens while searching for either more digits that belong to the TeX-&langle;number-quantitiy&rangle; in question or something that terminates searching more digits.

Unlike other things that terminate the search for more digits, a space-token terminating a sequence of digits will get discarded silently.

All this implies that you can nicely (ab?)use \romannumeral for triggering a lot of expansion-work and flipping macro-arguments around as long as it is ensured that after all that expansion-work a TeX-&langle;number-quantitiy&rangle; is found whose value is not positive.

I tend to do that as follows: Search for more digts and hereby expanding things gets triggered via \romannumeral0. After all expansion- and argument-flipping-work, the next token in the token-stream will be a space-token. Thus the non-positive number 0 is found, yielding that the TeX-&langle;number-quantitiy&rangle; is silently swallowed without delivering tokens in return. The space-token is discarded.


\documentclass[12pt]{examdesign}
\usepackage{amsmath}
\usepackage[utf8]{inputenc}
\usepackage{tikz,ifthen,tikz-3dplot}
\usepackage{tkz-euclide}
\usetkzobj{all}  %%%because I'm using overleaf
\usetikzlibrary{quotes,angles,decorations}
\usetikzlibrary{shapes.geometric,calc}
\class{Needed for examdesign}

%%%%%%%%%%%%%%%%%%%%%%%%%%% tikz set for cube%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\cubelength}{0.93}
\tikzset{%
  cube/.pic={%
    \draw[] (0,0,0) -- 
            (0,\cubelength,0) -- 
            (\cubelength,\cubelength,0) -- 
            (\cubelength,0,0) -- 
            cycle;
    % draw the back-right of the cube
    \draw[] (0,0,0) -- 
            (0,\cubelength,0) -- 
            (0,\cubelength,\cubelength) -- 
            (0,0,\cubelength) -- 
            cycle;
    % draw the back-left of the cube
    \draw[] (0,0,0) -- 
            (\cubelength,0,0) --
            (\cubelength,0,\cubelength) --
            (0,0,\cubelength) --
            cycle;
    % draw the front-right of the cube
    \draw[fill=magenta!50] (\cubelength,0,0) --
                           (\cubelength,\cubelength,0) --
                           (\cubelength,\cubelength,\cubelength) --
                           (\cubelength,0,\cubelength)--
                           cycle;
    % draw the front-left of the cube
    \draw[fill=orange!50] (0,\cubelength,0) --
                          (\cubelength,\cubelength,0) --
                          (\cubelength,\cubelength,\cubelength) --
                          (0,\cubelength,\cubelength) --
                          cycle;
    % draw the top of the cube
    \draw[fill=cyan!50] (0,0,\cubelength) --
                        (0,\cubelength,\cubelength) --
                        (\cubelength,\cubelength,\cubelength) --
                        (\cubelength,0,\cubelength) --
                        cycle;        
  }%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%To draw a cubeblocks object
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  Macro for Mystery Hypotenuse cubeblocks
\newcommand{\cubeblocks}[2][]{%
  \resizebox{5cm}{!}{ %<- The empty line yields \par - do you want that?

    \begin{tikzpicture}[scale=1,
                        #1,
                        cubeblocks/.cd,
                        w/.initial=1,
                        d/.initial=1,
                        unit/.initial=cm,
                        h/.initial=1
                       ]
    \tikzset{cubeblocks/.cd,#2}
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \pgfkeysgetvalue{/tikz/cubeblocks/w}{\Width}%
    \pgfkeysgetvalue{/tikz/cubeblocks/d}{\Depth}%
    \pgfkeysgetvalue{/tikz/cubeblocks/h}{\Height}%
    \expandafter\gdef\expandafter\globalscratchmacro\expandafter{%
      \romannumeral0%
      \expandafter\Exchange\expandafter{%
        \expandafter\renewcommand\expandafter\Height\expandafter{\Height}%
      }{%
        \expandafter\Exchange\expandafter{%
          \expandafter\renewcommand\expandafter\Depth\expandafter{\Depth}%
        }{%
          \expandafter\Exchange\expandafter{%
            \expandafter\renewcommand\expandafter\Width\expandafter{\Width}%
          }{ }%<-This space terminates \ronannumeral0-expansion.
        }%
      }%
    }%
    %\show\globalscratchmacro
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \pgfmathsetmacro{\effDepth}{\Depth-1}
    \pgfmathsetmacro{\effHeight}{\Height-1}
    \pgfmathsetmacro{\effWidth}{\Width-1}
    %%%%%draws coordinates
    \coordinate (A) at (0,0,0);
    \coordinate (B) at (\Width,0,0);
    \coordinate (C) at (\Width,0,\Depth);
    \coordinate (D) at (0,0,\Depth);
    \coordinate (E) at (0,\Height,\Depth);
    \coordinate (F) at (0,\Height,0);
    \coordinate (G) at (\Width,\Height,0);
    \coordinate (H) at (\Width,\Height,\Depth);
    \begin{huge}
    \draw[<->,blue,>=latex]([xshift=5mm]B)--%
         node[fill=white,xshift=3mm]{%
           $\pgfmathprintnumber\Height\,$%
           \pgfkeysvalueof{/tikz/cubeblocks/unit}%
         }([xshift=5mm]G);
    \draw[<->,blue, >=latex]([yshift=-5mm]C)--%
         node[fill=white,yshift=-2mm]{%
           $\pgfmathprintnumber\Width\,$%
           \pgfkeysvalueof{/tikz/cubeblocks/unit}%
         }([yshift=-5mm]D);
    \draw[<->,blue]([xshift=5mm,yshift=-2mm]B)--%
         node[xshift=3mm,yshift=-0mm,fill=white]{%
           $\pgfmathprintnumber\Depth\,$%
           \pgfkeysvalueof{/tikz/cubeblocks/unit}%
         }([xshift=5mm,yshift=-2mm]C);
    \end{huge} %<- The empty line yields \par - do you want that?

    \foreach \x in {0,...,\effWidth,\effWidth}{%
      \pgfmathifisint{\x}{%
        \pgfmathsetmacro{\myx}{1}%
      }{%
        \pgfmathsetmacro{\myx}{\x-int(\x))}%
      }%
      \foreach \y in {0,...,\effHeight,\effHeight}{%
        \pgfmathifisint{\y}{%
          \pgfmathsetmacro{\myy}{1}%
        }{%
          \pgfmathsetmacro{\myy}{\y-int(\y))}%
        }%
        \foreach \z in {0,...,\effDepth,\effDepth}{%
          \pgfmathifisint{\z}{%
            \pgfmathsetmacro{\myz}{1}%
          }{%
            \pgfmathsetmacro{\myz}{\z-int(\z))}%
          }%
          \path (\x+1-\myx,\y+1-\myy,\z+1-\myz) 
                pic[z={(-0.5*\myz,-0.5*\myz)},x={(\myx,0)},y={(0,\myy)}]
                {cube};
        }%
      }%
    }%
    \end{tikzpicture}%
  }%%%%closes \resizebox
  \globalscratchmacro
}%%%%closes definition-text

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Helpers and scratch-macros:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Argument-exchanging for expansion-trickery:
\newcommand\Exchange[2]{#2#1}
% General-purpose-scratch-macro; gets redefined by \cubeblocks globally:
\newcommand\globalscratchmacro{}%
% Scratch-macros for width, height and depth; they get redefined by
% \cubeblocks locally:
\newcommand{\Width}{}  
\newcommand{\Height}{}
\newcommand{\Depth}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

%\begingroup    
\cubeblocks{w=3,d=4,h=5,unit=cm}\\
%\show\Width
%\show\Height
%\show\Depth
%\endgroup
%\show\Width
%\show\Height
%\show\Depth
\pgfmathsetmacro{\baselayer}{\Width*\Depth}%
\pgfmathsetmacro{\volume}{\baselayer*\Height}%
\renewcommand{\arraystretch}{1}%
\hspace{-2cm}%
\begin{tabular}{|p{4cm}|p{4cm}|}
\hline
Base Layer Shape and Dimensions &rectangle \\
\hline
Base Layer Area & $A=$ \\
\hline
Volume of 1 layer & $V=$ \\
\hline
Prism Height & Prism height is \\
\hline
Volume & $\volume\text{cm}^3$ \\
\hline
\end{tabular}

\end{document}

enter image description here

By the way:
I take \begin{huge}...\end{huge} for your personal way of saying {\huge...}. ;-)

Ulrich Diez
  • 28,770
  • Thank you for your in depth answer. I am still learning how Latex works. Maybe I need to use \edef instead. Is \edef easier? The reason that I wanted to avoid it is that I had read that it is dangerous to define something that may overwrite without warning as \edef does. I appreciate your help. It will take me some time to digest what is going on. – E.Yu Apr 18 '20 at 16:56
  • @E.Yu Like \def \edef is a command for defining a macro. The difference is that with \edef all expandable tokens of the definition-text will be fully expanded before the assignment takes place. In LaTeX you can avoid undesired overwriting of already existing macros via \@ifdefinable: \@ifdefinable\macro{<Tokens in case \macro is not defined>} delivers the same error-message as \newcommand in case the macro is already defined. Otherwise you get <Tokens in case \macro is not defined>. That could be \edef\macro.... If you have more questions don't hesitate to ask. – Ulrich Diez Apr 19 '20 at 07:39
  • Thank you for your help. Can I ask what you would suggest in my case for best practice? I am making a worksheet where there are a lot of questions where I recall the macro for building the figure. Then I use the call again, re-inputting the numbers for the answer key. In examdesign, it's a new environment so I have to reinput everything. It's my rookiness that come across because, I want to know the best way to do this and have started a path that I'm not even sure of that it's the most efficient one. – E.Yu Apr 19 '20 at 23:26