• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Sharing Knowledge: Effective way of coding (Give suggestions)

Enthusiast ,
Mar 14, 2012 Mar 14, 2012

Copy link to clipboard

Copied

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

TOPICS
Scripting

Views

2.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 14, 2012 Mar 14, 2012

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 14, 2012 Mar 14, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 14, 2012 Mar 14, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

And even shorter:

// ...

hours > 12 && (hours-=12);

dd < 10 && (dd='0'+dd);

mm < 10 && (mm='0'+mm);

// ...

@+

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 15, 2012 Mar 15, 2012

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 16, 2012 Mar 16, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 18, 2012 Mar 18, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

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-javascript

which suggests:

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


Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

Personally, I like this answer from that discussion:

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

@Harbs – a bit dangerous.

One have to make sure that:

len !< num.toString().length;

Otherwise we possibly get truncated numbers on return.

Uwe

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

LATEST

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()...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 19, 2012 Mar 19, 2012

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines