20 Replies Latest reply: Mar 19, 2012 5:33 AM by Harbs. RSS

    Sharing Knowledge: Effective way of coding (Give suggestions)

    Green4ever Community Member

      Hi All,

       

      Assume you have a case that you need to perform a condition check and then add string based on that condition.

       

      Usually we'll (I did) do nested if else conditions. But recently I have came across a code this will avoid multiple if else statements.

       

      Example:

      With Nested IF conditions

       

      if (app.documents.length == 1){
          var inddDoc = app.documents.item(0);
          }
      else{
          if (app.documents.length == 0){
              alert("Please open a document");
              }
          else{
              alert("More than one document is opened\rPlease close other documents");
              }
          }
      

       

      Effective way (according to me)

       

      if (app.documents.length == 1){
          var inddDoc = app.documents.item(0);
          }
      else{
          alert(app.documents.length == 0?"Please open a document":"More than one document is opened\rPlease close other documents");
          }
      

       

      Your sugesstions are welcome, and please do share the similar kind of techniques if anyone have.

       

      Green4ever

       

      Message was edited by: Green4ever

        • 1. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
          [Jongware] CommunityMVP

          The (condition) ? (if true) : (if false) construction is quite powerful, but it sometimes makes it easy to write unmanageable code. If, for example, you start with two conditions, you can use it as you show here. If you have to add a third option, you can even expand it:

           

          (condition¹) ? (true¹) : ((condition²) ? (true²) : (false));

           

          and so on (yeah I find myself doing this at times). If your scripts are meant to be read by someone else, Clarity Rules! And "someone else" may very well be you -- six months later.

           

          Note that nested if/else also tend to get confusing after the third or fourth or so. If you are performing actions based on the number of items, and it's either 1 or 2 (or 0 or 1), you can safely use an if/else. For anything more, you should use a switch:

           

          switch (app.documents.length)

          {

            case 0: alert ("none"); break;

            case 1: okayGoAhead (); break;

            default: alert ("two or more"); break;
          }

           

          That way,  you can easily add 'case 2', 'case 3' etc., or remove 'case 0' if your function can work with it after all.

          • 2. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
            Harbs. CommunityMVP

            The SDK way is like this:

             

            do{

             

            if(condition1 == false)

            break;

            if(condition2 == false)

            break;

            if(condition3 == false)

            break;

            if(condition4 == false)

            break;

             

            // all conditions passed

            doYourStuff()

             

            }while(false)

             

            Harbs

            • 3. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
              Marc Autret MeganK

              To me switch/case is usually the way to go when you have to process various conditions. The code is cleaner and more flexible, I think.

               

              In very specific cases, however, you can directly select a choice—or an action—through a litteral Array.

               

              For example:

               

              alert( ["No document!", "OK (1 document)", "More than one document."][Math.min(2,app.documents.length)] );
              

               

              or:

               

              [myFunc0, myFunc1, myFuncMore][Math.min(2,app.documents.length)]();
              

               

              @+

              Marc

              • 4. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                Green4ever Community Member

                Hi All,

                 

                It is quite interesting and useful to read all the replies.

                 

                Jongware: Yeah, I agree that switch case is more friendly when more than 3 conditions are there. Thanks for your reply.

                 

                Harbs: Thanks for sharing your new idea. But I think SDK way is achieved by the simple if loop as follows

                 

                if((condition1 == true)&&(condition2 == true)&&(condition3 == true)&&(condition4 == true)){
                // all conditions passed
                doYourStuff()
                }
                

                 

                In what way that SDK method is useful. Can you please give an example. Am I making some sense? If not I apologize.

                 

                Marc: Selecting a choice from an array is awesome. Really a great idea though someone may already knew.

                 

                And here is the simple example to show the implementation of what I said,

                 

                function getDate_Time() {
                    var dTime = new Date();
                    var hours = dTime.getHours();
                    var minute = dTime.getMinutes();
                    var period = ((hours > 12)?"PM":"AM");
                    hours = ((hours > 12) ? hours - 12 : hours)
                    
                    var today = new Date();
                    var dd = today.getDate();
                    var mm = today.getMonth()+1; //January is 0!
                    var yyyy = today.getFullYear();
                    if(dd<10){
                        dd='0'+dd
                        } 
                    if(mm<10){
                        mm='0'+mm
                        } 
                    var time_Day = mm+'/'+dd+'/'+yyyy +" @ "+hours + ":" + minute + " " + period
                    return time_Day;
                    }
                

                 

                Thanks,

                Green4ever

                • 5. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                  Marijan Tompa [tomaxxi] MeganK

                  You can shorten it more:

                   

                  function getDate_Time() {
                      var
                          dTime = new Date(),
                          hours = dTime.getHours(),
                          minute = dTime.getMinutes(),
                          period = ((hours > 12)?"PM":"AM"),
                          dd = dTime.getDate(),
                          mm = dTime.getMonth()+1,
                          yyyy = dTime.getFullYear();
                      hours = ((hours > 12) ? hours - 12 : hours);
                      dd<10?dd='0'+dd:0;
                      mm<10?mm='0'+mm:0;
                      var time_Day = mm+'/'+dd+'/'+yyyy+" @ "+hours+":"+minute+" "+period;
                      return time_Day;
                  }
                  

                   

                  --

                  Marijan (tomaxxi)

                  • 6. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                    Marc Autret MeganK

                    And even shorter:

                     

                    // ...
                    hours > 12 && (hours-=12);
                    dd < 10 && (dd='0'+dd);
                    mm < 10 && (mm='0'+mm);
                    // ...
                    

                     

                    @+

                    Marc

                    • 7. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                      Harbs. CommunityMVP

                      If you have a lot of conditions and some of them could be complex, do/while/false is the flattest and easiest-to-read method. You find this code pattern a LOT in the InDesign SDK.

                       

                      Harbs

                      • 8. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                        Green4ever Community Member

                        Hi Marijan (tomaxxi),

                        I justed posted that example from one of my older scrap. Thanks for making it much simpler.

                         

                        Hi Marc,

                        I'll give a try on which you posted. Thanks.

                         

                        Hi Harbs,

                        I am very much eager to learn to SDK. Is there any free debugger available for SDK development. Can you suggest me from where I should begin?

                         

                        Thanks,

                        Green4ever

                        • 9. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                          Pickory Community Member

                          Until I started writing plugins I could not understand why do / while code was used. It really is the best method when you have conditions that rely on the success previous conditions.

                           

                          P.

                          • 10. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                            John Hawkinson CommunityMVP

                            Umm, what language are we talking about here? It looks like ExtendScript.

                            If so, then when Harbs says:

                            If you have a lot of conditions and some of them could be complex, do/while/false is the flattest and easiest-to-read method. You find this code pattern a LOT in the InDesign SDK.

                            I really don't think so at all!

                            It's a pattern that is not seen much outside of C++ and of the SDK, is I really wouldn't suggest it in JavaScript.

                            Instead, I would just chain the ifs and cheat the indentation, like this:

                             

                            if (app.documents.length == 1){
                                var inddDoc = app.documents.item(0);
                            } else if (app.documents.length == 0){
                                alert("Please open a document");
                            } else {
                                alert("More than one document is opened\rPlease close other documents");
                            }
                            

                             

                            You can have as many "else if" blocks as you like, before the final else.

                            It's easy to read, makes sense, and is a very-established pattern.

                             

                            Also, of course, you should be using === not ==, unless you have a very good reason.

                            • 11. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                              John Hawkinson CommunityMVP

                              Sorry, I left out one of the strongest reasons to avoid do { if / break / if / break ... / } while (false).

                              It's easy to forget a 'break' and have your code go completely awry. It's much nicer when the language's syntax conventions encourage you to do the right thing.

                              • 12. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                Harbs. CommunityMVP

                                Horses for courses.

                                 

                                If I have some conditions that cause a need to abort, I'll use if(condition)return; for each one. (no do/while/false)

                                 

                                If I need to do something different for each case, I'll usually use a switch.

                                 

                                switch (app.documents.length){

                                     case 0:

                                          alert("Please open a document");

                                          break;

                                     case 1:

                                          var inddDoc = app.documents.item(0);

                                          break;

                                     default:

                                           alert("More than one document is opened\rPlease close other documents");

                                          break;

                                }

                                 

                                If things are complex and I have just a few conditions I'll use if/else.

                                 

                                If things are really complex, I'll use do/while/false.

                                 

                                For me, the most important aspect of code is readability. Whatever fits the situation...

                                 

                                Harbs

                                • 13. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                  Green4ever Community Member

                                  Hi All,

                                  I'd like to share another simple but useful tip here. I said "useful" because JavaScript doesn't have string.format as an inbuilt function.

                                   

                                  If you want to prepend zeros (zero padding) to your calculations use the following simple method,

                                   

                                  var myValue1 = 1;
                                  var myValue2 = 25;
                                  myValue1 = ("000"+myValue1).slice(-3);
                                  myValue2 = ("000"+myValue2).slice(-3);
                                  alert("myValue1 = "+myValue1+"\rmyValue2 = "+myValue2);
                                  

                                   

                                  Is there any other better way to achieve this.

                                   

                                  Green4ever

                                  • 14. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                    John Hawkinson CommunityMVP

                                    Green4ever:

                                    var myValue1 = 1;
                                    myValue1 = ("000"+myValue1).slice(-3);

                                     

                                    Is there any other better way to achieve this.

                                    This code is not good for several reasons!

                                    Most importantly, it breaks for numbers bigger than 3 digits! That's horrible.

                                    Even if it was unlikely to happen in the original application, when you advertise it like this it's going to be repurposed and someone is going to have a nasty surprise some day! Not good! It's rare that this sort of code needs to run in a tight loop where perfect optimization and performance are more important than correctness. Take the time to do it right!

                                     

                                    Secondarily, you are using a single variable (myValue1) to hold two different kinds of objects, first an Number and later a String. That is usually not a good idea. It's not terrible, but it does tend to lead to confusion about what type the variable is at any given time, and string functions don't work well on numbers and vice versa. Much better to use two different variables.

                                     

                                    I'd probably take the first answer from http://stackoverflow.com/questions/2998784/how-to-output-integers-with-leading-zeros-in-ja vascript

                                    which suggests:

                                     

                                    function pad(num, size) {
                                        var s = num+"";
                                        while (s.length < size) s = "0" + s;
                                        return s;
                                    }


                                    • 15. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                      Harbs. CommunityMVP

                                      There was a discussion on the forum a while back about this.

                                       

                                      slice() is probably the best way to go.

                                       

                                      You can generalize that with the following function (originally posted by Peter Kahrel):

                                       

                                      alert("myValue1 = " + pad(myValue1,3)+"\rmyValue2 = "+ pad(myValue2,3));
                                      function pad (num, len) {
                                          return ("0000000"+num).slice(-len);
                                      }
                                      

                                       

                                      Harbs

                                      • 16. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                        Harbs. CommunityMVP

                                        Personally, I like this answer from that discussion:

                                         

                                        function zfill(num, len) {return (Array(len).join("0") + num).slice(-len);}

                                        • 17. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                          John Hawkinson CommunityMVP

                                          I agree that ithinc's answer with zfill() appears the most elegant. My inclination is to avoid the low-voted answers that look good because oftentimes they have subtle problems. This one looks OK to me, though.

                                           

                                          Of course, it's fairly disappointing to me that none of them properly handle negative numbers, or decimals, or NaN.  Bah!

                                           

                                          One probably doesn't care, but zfill() fails with big large numbers and small roundings, but pad() works ok:

                                           

                                          [04:03:49.850] pad(Number.MAX_VALUE,5)

                                          [04:03:49.852] "1.7976931348623157e+308"

                                          [04:03:54.122] zfill(Number.MAX_VALUE,5)

                                          [04:03:54.124] "e+308"

                                           

                                          If you try hard enough, maybe you can find a case where zfill() works and pad() fails? Or at least where it is faster?

                                          • 18. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                            Laubender CommunityMVP

                                            @Harbs – a bit dangerous.

                                             

                                            One have to make sure that:

                                             

                                            len !< num.toString().length;
                                            

                                             

                                            Otherwise we possibly get truncated numbers on return.

                                             

                                            Uwe

                                            • 19. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                              Green4ever Community Member

                                              Hi John,

                                               

                                              I agree that, the code I posted will only work for non negative 3 digit number. certainly it has its limitations. Need to learn the way, how to implement. Sorry for posting the example

                                              with less clarity. I just showed a way to do that technique. Thanks for you suggestion.

                                               

                                              Now, I Just made few change in the code that you posted, I hope it will now handle the negative numbers.

                                               

                                              function pad(num, size) {
                                                  if (num<0){var negative = true;}
                                                  var s = (Math.abs(num))+"";
                                                  while (s.length < size) s = "0" + s;
                                                  if (negative){
                                                      s = "-"+s;
                                                      }
                                                  return s;
                                              }
                                              

                                               

                                              Suggestions welcome!.....

                                               

                                              Also It is applicable only for integer values.

                                               

                                              Green4ever

                                               

                                              Message was edited by: Green4ever

                                              • 20. Re: Sharing Knowledge: Effective way of coding (Give suggestions)
                                                Harbs. CommunityMVP

                                                Good point.

                                                 

                                                Of course this is all pretty silly unless you are writing a library for public consuption.

                                                 

                                                For personal use, I'd just go with enough zeros as necessary and use a simple slice()...