My question relates to this previous question, but the solutions offered don't address the problem I have outlined below. After a google search I haven't found any code style guidelines that address the specific problem of long conditionals in an if statement like this.
if( isNull(value1) ||
isToLong(value1) ||
hasBadFormat(valule1)){
doSomething();
}else{
doSomethingElse();
}
OR:
if( isNull(value1) || isToLong(value1) || hasBadFormat(valule1) ){
doSomething();
}else{
doSomethingElse();
}
The problem I have with these two styles is it makes it hard for my eye to find the code in the true block and separate it from the conditionals, or it is too difficult for the eye to determine the correct next line after a long conditional on a single line, especially if the if statement is already indented a few tabs inside a function or other if statements.
Would it be preferable to do something like this:
if( isNull(value1) ||
isToLong(value1) ||
hasBadFormat(valule1)){
doSomething();
}else{
doSomethingElse();
}
or would this style be better to indent each new condition in either of these ways:
if( isNull(value1) ||
isToLong(value1) ||
hasBadFormat(valule1)){
doSomething();
}else{
doSomethingElse();
}
if( isNull(value1)
|| isToLong(value1)
|| hasBadFormat(valule1) ){
doSomething();
}else{
doSomethingElse();
}
Does anyone have a coding style guideline (maybe a company coding style policy) that addresses this issue in a different or better way than I've proposed? Which one is preferable and can you find any cons or pros to the solutions I've mentioned?
How about something like this?
bool isValid = isNull(value1) || isToLong(value1) || hasBadFormat(valule1);
if( isValid )
{
doSomething();
}
else
{
doSomethingElse();
}
The conditional gets moved onto another line, which might make it easier to read.
if( isNull(value1) ||
isToLong(value1) ||
hasBadFormat(valule1))
{
doSomething();
}
else
{
doSomethingElse();
}
Now you see the true-block easily I think.
Of course, I prefer:
if( isNull(value1)
|| isToLong(value1)
|| hasBadFormat(valule1))
{
doSomething();
}
else
{
doSomethingElse();
}
:-)
The obvious solution is to move the open-brace onto the next line, just as God intended!
</flamebait>
This is the alternative I prefer:
if(
isValid = isNull(value1) ||
isToLong(value1) ||
hasBadFormat(valule1)
) {
doSomething();
}
else {
doSomethingElse();
}
It really depends on preference and convention of people you work with, but the first two are the two most common forms I have seen. I tend to prefer to move the conditional to multi-lines only if it is so long that it requires left-right scrolling in my ide.
This is how I would write it:
if(isNull(value1) ||
isToLong(value1) ||
hasBadFormat(valule1))
{
doSomething();
}
else
{
doSomethingElse();
}
Unless that conditional is not long enough to force me to scroll to see it all. If not, I'd do this:
if(isNull(value1) || isToLong(value1) || hasBadFormat(valule1))
{
doSomething();
}
else
{
doSomethingElse();
}
And in this case, since it seems short enough, I'd do the latter.
I tend to put the operators at the start of the line so they all up.
So, here's one suggestion:
if(isNull(value1)
|| isTooLong(value1)
|| hasBadFormat(valule1))
{
doSomething();
} /* if */
else
{
doSomethingElse();
} /* else */
Here's another:
if(0
|| isNull(value1)
|| isTooLong(value1)
|| hasBadFormat(valule1))
/* ...etc... */
(For &&, it would be if(1 && a && b), etc.)
Or this:
if
(
isNull(value1)
|| isTooLong(value1)
|| hasBadFormat(valule1)
)
/* ...etc... */
I personally format all my if statements like this, no matter the length:
if (isNull(value1) || isToLong(value1) || hasBadFormat(value1)) {
doSomething();
} else {
doSomethingElse();
}
I'm probably the only one that does it this way. It's called the Horstmann Style but I do it slightly differently.
if (bool) // comment
{ dothis;
andthis;
} else if (bool) // comment
{ dothis;
andthis;
} else // comment
{ dothis;
andthis;
}
Related
Sorry if this is a noobish question (I'm new to programming and stackoverflow) but I'm making something that has to do with pressing a key to do something, and it works but I don't know how to enable it so that it stops doing the command.
function scarf (mode, key, foo) {
if ((mode === 1) && foo) {
$(key).keypress = play(key);
}
}
var a = (false);
function scarf(mode,foo,key,a) {
while ((mode === 1) && foo && b) {
$(key).keypress = play(key);
(a);
}
}
while (a) {
$(key).keypress = stop(key);
(a = false);
}
I've figured it out.
I would like to consider one syntax improvement.
How I can write this better:
IF condition1
IF condition2
{ do something }
ELSE
{ message1 }
ELSE
{ message1 }
There are two IF statements that cannot be joined in one statement, but in both ELSE parts need to be same code (in this example message1).
How this can be written better? I wouldn't like to write same code (in ELSE parts) twice.
TnX in advance!
Nemanja
The obvious solution is to combine the two conditions:
IF condition1 AND condition2
{ do something }
ELSE
{ message1 }
However if the two conditions really can not be combined for some reason, and you are using a C-like language which has a break keyword or equivalent, then you can do something like this:
DO
IF condition1
IF condition2
{ do something }
BREAK
{ message1 }
WHILE FALSE
What about
IF condition1 AND condition2
{ do something }
ELSE
{ message1 }
If you can't join both statements, you can use some sort of GOTO (ps: this is bad practice)
IF condition1
IF condition2
{ do something }
ELSE
GOTO ELSE_CODE
ELSE
:ELSE_CODE
{ message1 }
in case you're talking about a language without short-circuit boolean evaluation, you could manually implement it like
flag = condition1
IF flag
flag = flag AND condition2
IF flag
{ do something }
ELSE
{ message1 }
I searched for this answer and I realized you just need to reorder the statements.
Instead of 2 IF statements with one else like this
{
if(FirstCheck === true){
//run function 1
}
if(SecondCheck === true){
//run function 2
}
}else{
//run this else only when the first 2 IFs are false
// run function 3
}
}
you want to do a IF for the reason why you want to run the function in the else, and then put an else for that IFs, that then runs your original IFs
if(orginalElse !== true){
//run function 3
//this is the orginal else you would want to run, just with a negative if statement
}else{
if(FirstCheck === true){
//run function 1
}
if(SecondCheck === true){
//run function 2
}
}
I cannot get the logic for this down correctly. I am using a wizard with separate views in the controller (no javascript). Based on a selection in Step 2 of the wizard I want to either skip Step 7 or show Step 7. The wizard uses next/back buttons to control where to go.
I was able to "show" Step 7 if the user selected "A" (for example), but when I created the logic to skip Step 7 if either "B" or "C" were selected I either get a "redirect loop / too many redirects error" on Chrome (I cleared out the cookies to no avail) or the "Next" button on the prior step won't work (it just shows the same view).
Step 2 in and of itself is unimportant in terms of the controller, it contains a drop down list with the 3 choices, and based on that choice this is the controller code I have (I leave out serializing the myViewModel code in the Controller, which is decorated with [Serializable]):
// STEP 6:
// Based on selection in Step 2, show or don't show Step 7
public ActionResult Step6(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("Step5");
else if ((nextButton != null) &&
ModelState.IsValid &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.A))
return RedirectToAction("Step7");
else if ((nextButton != null) &&
ModelState.IsValid &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.B) ||
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.C))
return RedirectToAction("Step8");
else
return View("Step6", myViewModel);
}
// STEP 7:
// Only shown if Choice in MyDropDown is "A",
// otherwise if "B" or "C" skipped
public ActionResult Step7(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("Step6");
else if ((nextButton != null) &&
ModelState.IsValid)
return RedirectToAction("Step8");
else
return View("Step7", myViewModel);
}
// STEP 8:
// Arrive here either from Step 6
// (if "B" or "C" chosen),
// or from Step 7 (if "A" chosen)
public ActionResult Step8(string backButton, string nextButton)
{
if ((backButton != null) &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.A))
return RedirectToAction("Step7");
else if ((backButton != null) &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.B) ||
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.C))
return RedirectToAction("Step6");
else if ((nextButton != null) &&
ModelState.IsValid)
return RedirectToAction("Step9");
else
return View("Step8", myViewModel);
}
I know I am just getting the logic down wrong. Any help is much appreciated.
The above code (without the logic I am asking about) works perfectly, as does the code I use to display the DropDown.
Ugh, I should have encapsulated the || logic in its own () to read thusly:
else if ((backButton != null) &&
//Extra opening parenthesis-->
((myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.B) ||
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.C))) //<--extra closing parenthesis
return RedirectToAction("Step6");
During a code review, a senior dev commented on some nesting I had going on in my code. He suggested I set a bool value so that I never have more than one level of nesting. I think my code is more readable but want to get other devs' opinion on this. Which is better style? Is his knee-jerk aversion to nesting founded?
Below are some simplified code examples.
Nested:
If(condition1)
{
If(condition2)
{
if(condition3)
{
return true;
}
else
{
log("condition3 failed");
}
else
{
log("condition2 failed")
}
}
else
{
log("condition1 failed")
}
return false;
or
Bool Driven:
bool bRC = false;
bRC = (condition1);
if(brc)
{
bRC = (condition2);
}
else
{
log("condition1 failed");
return false;
}
if(bRC)
{
bRC = (condition3);
}
else
{
log("condition2 failed");
return false;
}
if(bRC)
{
return true;
}
else
{
log("condition3 failed");
return false;
}
I like yours better, but I'd probably do something like:
if (condition1 && condition2 && condition3)
{
return true;
}
else if (!condition1)
{
log("condition1 failed");
}
else if (!condition2)
{
log("condition2 failed");
}
else
{
log("condition3 failed");
}
return false;
If the conditions are complex expressions then I might assign the expressions to appropriately named variables before evaluating the if statements to avoid having to recompute the values in each if.
This is assuming that the normal mode is that all conditions are true and thus you want to have that check first. If the normal mode is that one or more conditions are false, then I'd reorder it and check each negation in turn and simply return true if all the checks failed. That would also remove the need for temporary variables to take the place of complex expressions.
If you don't have any silly rules about multiple return points, I think this is quite nice (and so does someone else, but they deleted their answer for unknown reasons):
if(!condition1)
{
log("condition1 failed");
return false;
}
if(!condition2)
{
log("condition2 failed");
return false;
}
if(!condition3)
{
log("condition3 failed");
return false;
}
return true;
Maybe this is an equal knee-jerk aversion to super-nesting, but it's certainly cleaner than his crap storing the boolean conditions in certain values. However, it may be less readable in context: consider if one of the conditions was isreadable(). It's clearer to say if(isreadable()) because we want to know if something is readable. if(!isreadable()) suggests if we want to know whether it's not readable, which isn't our intention. It's certainly debatable that there may be situations where one is more readable/intuitive than the other, but I'm a fan of this way myself. If someone gets hung up on the returns, you could do this:
if(!condition1)
log("condition1 failed");
else if(!condition2)
log("condition2 failed");
else if(!condition3)
log("condition3 failed");
else
return true;
return false;
But that's rather underhanded, and less "clear" in my opinion.
I personally find the nested code significantly easier to read.
I generally prefer nested for my conditions; of course, if my nested conditions are getting indented too far to the right, I have to start wondering if there's a better way to go about whatever I'm trying to do (refactoring, redesigning, etc..)
Similar to the nested version, but much cleaner for me:
if not condition1:
log("condition 1 failed")
else if not condition2:
log("condition 2 failed")
else if not condition3:
log("condition 3 failed")
else
return true;
return false;
Beware that each condition is evaluated once.
The second style is absurdly verbose: did he really suggest exactly this? You don't need most of those if statements, because there is a return in the else part.
With the nested example you are relying on not forgetting to include any possible else clauses.
Neither of these seems satisfactory to me.
The bool driven way is confusing. Nesting is fine if required, but you could remove some of the nesting depth by combining the conditions into one statement, or calling a method where some of the further evaluation is done.
I think both ways are possible and have their Pros and Cons. I would use the bool-driven style in cases where i would have really deep nesting (8 or 10 or something like that). In your case with 3 levels, i would choose your style but for the exact sample from above, i would go like that:
void YourMethod(...)
{
if (condition1 && condition2 && consition3)
return true;
if (!condition 1)
log("condition 1 failed");
if (!condition 2)
log("condition 2 failed");
if (!condition 3)
log("condition 3 failed");
return result;
}
... or like that if you prefer a single exit point (like i do) ...
void YourMethod(...)
{
bool result = false;
if (condition1 && condition2 && consition3)
{
result = true;
}
else
{
if (!condition 1)
log("condition 1 failed");
if (!condition 2)
log("condition 2 failed");
if (!condition 3)
log("condition 3 failed");
}
return result;
}
That way, you will get all the failed condition logged in the first run. In your example, you will get only one failed condition logged even if there are more than one failing conditions.
I'd probably go with
if (!condition1) log("condition 1 failed");
else if (!condition2) log("condition 2 failed");
else if (!condition3) log("condition 3 failed");
// -------------------------------------------
return condition1 && condition2 && condition3;
which I believe is equivilent and much cleaner...
Also, once the client decides that all conditions should be evaluated and logged if they fail, not just the first one that fails, this is much easier to modify to do that:
if (!condition1) log("condition 1 failed");
if (!condition2) log("condition 2 failed");
if (!condition3) log("condition 3 failed");
// -------------------------------------------
return condition1 && condition2 && condition3;
This is how I would implement it, provided your implementations actually reflect the desired behavior.
if (!condition1) {
log("condition1 failed");
return false;
}
if (!condition2) {
log("condition2 failed");
return false;
}
if (!condition3) {
log("condition3 failed");
return false;
}
return true;
However, I think it's more likely that every failed condition should be logged.
result = true;
if (!condition1) {
log("condition1 failed");
result = false;
}
if (!condition2) {
log("condition2 failed");
result = false;
}
if (!condition3) {
log("condition3 failed");
result = false;
}
return result;
If the language supports exception handling, I'd go with the following:
try {
if (!condition1) {
throw "condition1 failed";
}
if (!condition2) {
throw "condition2 failed";
}
if (!condition3) {
throw "condition3 failed";
}
return true;
} catch (e) {
log(e);
return false;
}
EDIT From charles bretana: Please see Using Exceptions for control flow
I don't like either way. When you have so much nests something is wrong. In the case of a form validation or something that does indeed require something like this try to figure something out that's more modular or compact.
An example would be an array holding the conditions, through which you'll iterate with a while, and print/break as needed.
There are too many implementations depending on your needs so creating an example code would be pointless.
As a rule of thumb, when your code looks too complicated, it sucks :). Try rethinking it. Following coding practices most of the times makes the code turn out a lot more aesthetic and short; and obviously, also smarter.
Code shall restate the problem in a language given. Therefore I maintain that either snippets can be "better". It depends on the problem being modeled. Although my guess is that neither of the solutions will parallel the actual problem. If you put real terms instead of condition1,2,3 it might completely change the "best" code.
I suspect there is a better (3d) way to write that all together.
if( condition1 && condition2 && condition3 )
return true;
log(String.Format("{0} failed", !condition1 ? "condition1" : (!condition2 ? "condition2" : "condition3")));
return false;
That way, you don't have to see many lines of code just for logging. And if all your conditions are true, you don't waste time evaluating them in case you have to log.
This is related to a chapter from beautiful code.
And in that chapter I read about the nested ifs.
The author was talking about deeply nested ifs as originator of bugs and less readable.
And he was talking about replacing nested ifs with case statements and decision tables.
Can anybody illustrate how to remove nested ifs with case (select case) and decision tables ?
Well, not directly an answer to your question since you specifically ask about switch/case statements, but here is a similar question.
Invert “if” statement to reduce nesting
This talks about replacing nested if's with guard-statements, that return early, instead of progressively checking more and more things before settling on a return value.
One example I always try to do is replace heavily nested if's like this (actually this one's not too bad but I've seen them up to 8 or 9 levels deep in the wild):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
with this:
switch (i) {
case 1:
// action 1
break;
case 2:
// action 2
break;
case 3:
// action 3
break;
default:
// action 4
break;
}
I also try to keep the actions as small as possible (function calls are best for this) to keep the switch statement compressed (so you don't have to go four pages ahead to see the end of it).
Decision tables, I believe, are simply setting flags indicating what actions have to be taken later on. The "later on" section is simple sequencing of actions based on those flags. I could be wrong (it won't be the first or last time :-).
An example would be (the flag-setting phase can be complicated if's since its actions are very simple):
switch (i) {
case 1:
outmsg = "no paper";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
case 2:
outmsg = "no ink";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
default:
outmsg = "unknown problem";
genmsg = true;
mailmsg = true;
phonemsg = true;
break;
}
if (genmsg)
// Send message to screen.
if (mailmsg)
// Send message to operators email address.
if (phonemsg)
// Hassle operators mobile phone.
How about chained ifs?
Replace
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
with
if (condition1) {
do1;
} else if (condition2) {
do2;
} else if (condition3) {
do3;
}
This is much like switch statement for complex conditions.
Make the condition into booleans and then write boolean expression for each case.
If the code was:
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
One can write it as:
bool cond1=condition1;
bool cond2=condition2;
bool cond3=condition3;
if (cond1) {do1;}
if (!cond1 and cond2) {do2;}
if (!cond1 and cond3) {do2;}
For decision tables, please see my answer to this question, or better still read chapter 18 in Code Complete 2.
You can just break once a part of the validation failed for example.
function validate(){
if(b=="" || b==null){
alert("Please enter your city");
return false;
}
if(a=="" || a==null){
alert("Please enter your address");
return false;
}
return true;
}
Decision tables are where you store the conditional logic in a data structure rather than within the code itself.
So instead of this (using #Pax's example):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
you do something like this:
void action1()
{
// action 1
}
void action2()
{
// action 2
}
void action3()
{
// action 3
}
void action4()
{
// action 4
}
#define NUM_ACTIONS 4
// Create array of function pointers for each allowed value of i
void (*actions[NUM_ACTIONS])() = { NULL, action1, action2, action3 }
// And now in the body of a function somewhere...
if ((i < NUM_ACTIONS) && actions[i])
actions[i]();
else
action4();
If the possibilities for i are not low-numbered integers then you could create a lookup table instead of directly accessing the ith element of the actions array.
This technique becomes much more useful than nested ifs or switch statements when you have a decision over dozens of possible values.
If and switch statements are not purely OO. They are conditional procedural logic, but do a very good job! If you want to remove these statements for a more OO approach, combine the 'State' and 'Descriptor' patterns.
You might also consider using the Visitor pattern.
Nested if are equivalent to the logical operator AND
if (condition1)
{
if (function(2))
{
if (condition3)
{
// do something
}
}
}
Equivalent code:
if (condition1 && function(2) && condition3)
{
// do something
}
In both cases, when an expression evaluates false, the subsequent expression will not be evaluated. For example, if condition1 is false, the function() will not be called, and condition3 won't be evaluated.
Another example some languages allow is this
switch true{
case i==0
//action
break
case j==2
//action
break
case i>j
//action
break
}