Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Programing : default option when option(string)

    Hello Stata programmers,

    I am programing a routine, where I want the default command to compute a non-normalized index, and let two possibilities to compute (two different) normalized indexes.
    so here's the syntax
    Code:
    program cmd
    syntax    [, Normalize(string) *]
    Where string should idicate the normalization method chosen
    Where I face a problem is that I want that if string is missing, but the normalize option written, add a default choice (e.g, method one), since the use of method one should be more frequent

    To be exhaustive I want :
    Code:
    cmd
    to run the normal command (non normalized)
    Code:
    cmd, n
    cmd,n(one)
    to run the same normalized command method
    And
    Code:
    cmd, n(two)
    to run the second normalized command


    I'd like to find a command that indicates whether the normalized option is on or not (and not what's in its parenthesis), because
    Code:
    if "`normalize'"==""
    indicates that nothing is in the parenthesis, but doesn't indicates whether the normalized option is on or not (as it would be for options without a (string), thus indicates

    Sorry if this isn't very clear,
    Best,
    Charlie

  • #2
    I don't understand the difficulty. There is no default for string arguments, unless you want to say that empty string is.

    I would just use two options, one being the default. Perhaps

    Code:
    syntax [, one two ] 
    
    if "`one'" != "" & "`two'" != "" { 
        di as err "you must choose between one and two" 
        exit 198 
    } 
    else if "`two'" != "" { 
        <code for two> 
    } 
    else { 
        <code for one> 
    }

    Comment


    • #3
      Thanks Nick for your quick answer

      I've though about that, but this corresponds to create two distinct options, while I would prefer a single option where you would indicate a second method.

      This is purely for "beauty" purposes, because I already have many possible option, and those two (one and two method) are related, so I would have loved to include them in a common option.

      I know I could either do two specific options (as you do) or force the user to complete the (string), but I just wanted to know whether the (string) could be indicated by default until another string is written.

      Many thanks anyway.
      Best,
      Charlie

      Comment


      • #4
        You could possibly accomplish what you want using the passthru style of option rather than the string style.

        Comment


        • #5
          Hi Charlie,

          If I understand correctly, this is a problem I have also encountered whilst programming.

          The solution is to include *two* options within the syntax command with the same name: one a simple on/off switch, the other an "option(string)". However, as Stata processes options from right-to-left, the first of these two will never be processed. So you need to have two syntax commands, where in the second instance the options are reversed:

          Code:
          program cmd
          syntax [, Normalize(string) Normalize * ]
          if `"`normalize'"'==`""' syntax [, Normalize Normalize(string) * ]
          disp `"`normalize'"'
          end
          Some examples:
          Code:
          . cmd
          
          
          . cmd, n
          normalize
          
          . cmd, n(one)
          one
          
          . cmd, n(two)
          two
          
          . cmd, n(one) n
          normalize
          
          . cmd, n n(one)
          normalize
          Note that the latter two examples demonstrate that if the user supplies both forms of the option, the program will only ever use the right-most option of the first syntax command, regardless of the order supplied by the user. If this behaviour is important, there are ways of altering it (e.g. by storing the results of each syntax command under different local macro names. This could also be used to give an error message if both forms are supplied.)

          Hope that helps,

          David.

          Comment


          • #6
            I totally understand the "beauty" aspect. Here is how you do this

            Code:
            program cmd
                version 12.1
                
                syntax [ , Normalize42 Normalize(string) ]
                
                if (mi(`"`normalize'"') & ("`normalize42'" != "")) {
                    local normalize "one"
                }
                
                if !inlist(`"`normalize'"', "", "one", "two") {
                    display as err "invalid option normalize()"
                    exit 198
                }
                
                display "`normalize'"
            end
            Demonstration

            Code:
            . cmd
            
            
            . cmd , n
            one
            
            . cmd , n(one)
            one
            
            . cmd , n(two)
            two
            StataCorp usually uses 1 or 2 where I used 42, that obviously does not matter. Note that it is not an error to specify both, normalize and normalize({one|two}). You can change that if you wish. You could also allow abbreviated sub-options like normalize(tw), but this need some additional lines and would perhaps better be done in a subroutine.

            Best
            Daniel

            [edit]
            Crossed with David's response. Note that mine does not depend on the order of options.
            [/edit]

            Comment


            • #7
              Daniel,
              Your solution is indeed an improvement on my own; thanks for sharing!
              Best,
              David.

              Comment


              • #8
                Wao, many thanks Daniel and David for complete example, I'll try that (they both follow the same logic).

                Nice to know it wasn't such a silly question, as you guys have thought about it before (and were more imaginative than I was).

                Best,
                Charlie


                Edit : Daniel's code works perfectly (and easily adaptable to my specific code).
                Last edited by Charlie Joyez; 15 Feb 2017, 05:25.

                Comment


                • #9
                  OK, so why not


                  Code:
                  syntax [, method(str)]
                  
                  // default
                  if "`method'" == "" local method "one"
                  
                  else if !inlist("`method'", "one", "two")  {
                      di as err "must choose one or two"
                      exit 198
                  }
                  Another structure that is good is

                  <command> <subcommand>

                  See e.g. the code for duplicates


                  EDIT: Much overlap with others. Optimistically, that's a feature, not a bug.

                  Comment


                  • #10
                    See also

                    http://www.stata.com/support/faqs/pr...ive-arguments/

                    http://www.stata-journal.com/sjpdf.h...iclenum=pr0048

                    Comment


                    • #11
                      Originally posted by Nick Cox View Post
                      I think the last paragraph describes how I learned about this pretty well. Thanks for pointing to the article.

                      Best
                      Daniel

                      Comment


                      • #12
                        Thanks for sharing this Nick.
                        I was looking for documentation like that, but I missed the right keywords. I'll try to keep in mind the correct vocabulary!

                        Best,
                        Charlie

                        Comment

                        Working...
                        X