3

I read LaTeX \if condition and How to write if and then in algorithm?, but so far it did not ring a bell for me.

I am trying to create a command named dottedSkill like below. The logic behind it is:

  • receive two parameters
  • iterate over the counter x from 1 to #2
  • if my counter filled is > 0, I draw a full dot and decrement the counter
  • else I draw an empty dot
\newcommand{\dottedSkill}[2]{
    %parameter 1 the filled dots
    %parameter 2 the max dots
\newcounter{x}
\newcounter{filled}
\setcounter{filled}{#1}
\forloop{x}{1}{\value{x} <= #2}
{
    \ifnum \filled<1
        \Circle
    \else
        \CIRCLE
        \addtocounter{filled}{-1}
    \fi
}

}%

I am not sure if the problem is with the command definition or someplace else, but when I call it on my file I get:

  • Undefined control sequence. \dottedSkill{2}{9}.
  • Missing number, treated as zero. \dottedSkill{2}{9}
  • Undefined control sequence. \dottedSkill{2}{9}.
  • Missing number, treated as zero. \dottedSkill{2}{9}

Is my function properly written?

4 Answers4

6

The current problem with your setup is that you're defining the filled counter every time you run \dottedSkill. You should pull these definitions out of your \dottedSkill command.

Also, you should just draw the filled circles, followed by the empty circles:

enter image description here

\documentclass{article}

\usepackage{multido}

\newcommand{\Circle}{\textbullet} \newcommand{\CIRCLE}{$\circ$}

\newcommand{\dottedSkill}[2]{% %parameter 1 the filled dots %parameter 2 the max dots
\multido{\ix=1+1}{#1}{\Circle}% \ifnum#1<#2 \multido{\ix=#1+1}{\numexpr#2-#1}{\CIRCLE}\fi }%

\begin{document}

\dottedSkill{2}{9}

\dottedSkill{0}{9}

\dottedSkill{10}{9}

\dottedSkill{5}{9}

\end{document}

multido works similar to forloop to iterate over some value.

Werner
  • 603,163
  • It works although I had to do tiny changes since the textbullet is not the same type as circ.

    So I did that \newcommand{\EmptyDot}{\Circle} \newcommand{\FilledDot}{$\CIRCLE$}

    \newcommand{\dottedSkill}[2]{% %parameter 1 the filled dots %parameter 2 the max dots
    \multido{\ix=1+1}{#1}{\FilledDot}% \ifnum#1<#2 \multido{\ix=#1+1}{\numexpr#2-#1}{\EmptyDot}\fi }%

    – Daniel Ferreira Castro Jan 06 '24 at 22:59
  • 2
    @DanielFerreiraCastro: Sure. You never disclosed what \Circle and \CIRCLE are defined as, hence me taking some liberty to define something similar. – Werner Jan 07 '24 at 03:45
4
\documentclass{article}
\usepackage{forloop}
\newcounter{x}
\newcounter{filled}
\newcommand{\dottedSkill}[2]{%
    %parameter 1 the filled dots
    %parameter 2 the max dots
    \setcounter{filled}{#1}%
    \forloop{x}{0}{\value{x} < #2}%
    {%
        \ifnum \thefilled < 1 
            $\circ$%\Circle
        \else 
            $\bullet$%\CIRCLE 
            \addtocounter{filled}{-1}%
        \fi
    }%
}%
\begin{document}
\dottedSkill{2}{9}
\end{document}

enter image description here

2

The first question to me if you need really the conditional. Only in case of XY problem (the true problem is not of make the loop works, but make a score with a macro with two arguments) here is a simpler approach:

mwe

\documentclass{article}
\newcommand\score[2][10]{
\makebox[#2em]{\cleaders\hbox to 1em{\Large\hss$\bullet$\hss}\hfill}%
\makebox[\dimexpr#1em-#2em]{\cleaders\hbox to 1em{\Large\hss$\circ$\hss}\hfill}\par} 
\begin{document}
\score[5]{0} 
\score[5]{1}
\score[5]{3}
\score[5]{5}
\score{0} 
\score{3} 
\score{6}
\score{10}
\end{document}
Fran
  • 80,769
1

Thanks to all of you I was able to fine tune my solution to that.

I used as reference for the types of circle this link: https://aneescraftsmanship.com/circle-symbols%E2%97%8B%E2%97%8F%E2%97%8D%E2%97%97%E2%97%94%E2%97%99%E2%A6%BF-in-latex/

\usepackage{wasysym}

\newcommand{\EmptyDot}{\Circle} \newcommand{\FilledDot}{$\CIRCLE$}

\newcommand{\dottedSkill}[2]{% %parameter 1 the filled dots %parameter 2 the max dots
\multido{\ix=1+1}{#1}{\FilledDot}% \ifnum#1<#2 \multido{\ix=#1+1}{\numexpr#2-#1}{\EmptyDot}\fi }%