If-else and default condition in groovy script - if-statement

Is there any way to add default condition into if else loop. If X is true then operation1 executes else operation2. If X is null then default operation gets executed.
if (x)
{ operation1 }
else
{ operation2 }
default
{default operation}

No default null-condition is provided in Java/Groovy as a null is not treated as default case.
You have to check against the null yourself:
if (null)
{ operationNull }
else if (x)
{ operation1 }
else
{ operation2 }

Related

class method not returning value

I have a method inside a class that is not returning a value.
These are the relevant variables that are being used in the method, they are in the private part of the class
int hieght_of_plane = 0 ;
int position_of_plane = 0 ;
bool landing_gear = true ;
bool is_flying = false ;
bool is_alive = true ;
And here is the method that is not returning true or false, it is in the public section of the class.
bool check_for_alive()
{
if (is_flying == false)
{
return true ;
}
if (is_flying == true)
{
if (hieght_of_plane <= 3)
{
if (landing_gear == false)
{
is_alive = false ;
return false ;
}
else if (landing_gear == true)
{
return true ;
}
}
}
}
The method seems to not do anything and then I get the no return value error
warning: control reaches end of non-void function [-Wreturn-type]
I assume that it should return false in this instance because is_flying = false so the method should return false, but it isn't.
The case that falls through is when flying == true and hieght_of_plane is greater than 3.
if (is_flying == true)
{
if (hieght_of_plane <= 3)
{
The 2nd if statement does not have an else, which is necessary for returning a value.
Edit 1: An else clause
The else clause should be used for the "not" case of the if statement.
For example:
if (is_flying == false)
{
return true;
}
else // This means is_flying == true
{
if (hieght_of_plane <= 3)
{
if (landing_gear == false)
{
is_alive = false ;
return false ;
}
else // implies landing_gear == true
{
return true ;
}
else // implies hieght > 3
{
return ????
}
}
You could also reduce this down to one Boolean expression.
Edit 2: Simplification
There are two functionalities here: Return true/false for a combination of conditions and to set is_alive based on a condition.
Let's say that one condition is true, all others is false.
bool check_for_alive()
{
if (is_flying && (height_of_plane <= 3) && (landing_gear == false))
{
is_alive = false;
}
return is_flying && (height_of_plane <= 3) && (landing_gear == true);
}
Note: The above does not consider the case of `(height_of_plane > 3), since this is not specified in the OP's original code.
the control flow would reach the end of the function when is_flying is true and hieght_of_plane is > 3. you MUST return something there.
and one more thing is the you don't always need to check that if (something == true) instead if (something) would enough, I've pointed some more below the code.
bool check_for_alive() {
if (!is_flying)
return true;
// if you reached here is_flying is true no need to check
if (hieght_of_plane <= 3) {
if (!landing_gear) {
is_alive = false;
return false;
} else {
// if you're here landing_gear is false no need to check
return true;
}
}
// what to return if we reach here? yes the control flow could reach
// here when is_flying is true and hieght_of_plane is > 3
// you must return something here.
}

No return evaluation in nested if

After watching carefully the following code I can't see why the compiler is warning me with "warning: control reaches end of non-void function".
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
}
else
{
return false;
}
}
I can't see where is the problem, the else statement should care for returning false in every case which the first if is not true.
Trace the code path when regIOobject::read() is true, but either of permeabilityModelPtr_->read(subDict("permeability")) or magnetizationModelPtr_->read(subDict("magnetization")) is false. In that case, you enter the top if block (excluding the possibility of entering its attached else block), but then fail to enter the nested if block:
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
// Cool, read() was true, now check next if...
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
// Oh no, it was false, now we're here...
}
else
{
// First if was true, so we don't go here...
return false;
}
// End of function reached, where is the return???
}
The minimalist fix is to just remove the else { } wrapping, so any fallthrough ends up at return false;:
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
// Cool, read() was true, now check next if...
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
// Oh no, it was false, now we're here...
}
// Oh, but we hit return false; so we're fine
return false;
}
Alternatively, avoid specifically mentioning true or false at all, since your function is logically just a result of anding three conditions together:
bool Foam::solidMagnetostaticModel::read()
{
// No need to use ifs or explicit references to true/false at all
return regIOobject::read() &&
permeabilityModelPtr_->read(subDict("permeability")) &&
magnetizationModelPtr_->read(subDict("magnetization"));
}
The nested if is the problem.
When that branch is not taken, there is no other paths to take
the else statement should care for returning false in every case which the first if is not true.
Correct, but what if the first if condition is true, but the second if condition is not?
That is: What if regIOobject::read() returns true, but permeabilityModelPtr_->read(subDict("permeability")) returns false?
Then the flow of control enters the first if block, does not return, but does not enter the else block (because the first condition was true), so it just falls off the end of the function without hitting a return statement.
If you want the else { return false; } part to apply to either condition, you could just naively copy/paste it:
if (COND1) {
if (COND2) {
return true;
} else {
return false;
}
} else {
return false;
}
But that's quite a bit of code duplication. A better solution is to replace the nested if by a single condition:
if (COND1 && COND2) {
return true;
} else {
return false;
}
There's still some duplication: Both branches consist of a return statement followed by some expression.
We can factor out the common parts (return) and push the condition into the expression:
return COND1 && COND2 ? true : false;
But ? true : false is redundant: If the condition is true, evaluate to true, else evaluate to false? Well, that's just what the condition itself does:
return COND1 && COND2;
Or with your concrete expressions:
return regIOobject::read()
&& permeabilityModelPtr_->read(subDict("permeability"))
&& magnetizationModelPtr_->read(subDict("magnetization"));

Is the ELSE of an IF (p) statement including a method the "NOT METHOD" (not p)?

If I write a statement:
if(!(method())
{
// do something
}
else
{
//do something
}
And method returns a boolean value, is the else - without writing else if (method() - automatically the opposite of if, i.e. does else have a relationship to the method called in the opening if statement?
Yes, if method on IF return TRUE, as it's negated, ELSE statement will execute.
It's like:
if(!myMethod()) {
//RUN SOMETHING
}
else {
//RUN OTHER THING HERE
}
If MyMethod Returns "TRUE", the if statement will se a "FALSE" because it's inverting it, so as it's not true, will run the ELSE code (//RUN OTHER THING).
Yes - implicitly, IF .. ELSE is a boolean test that essentially looks like this:
IF (condition)
{
<< condition evaluated to TRUE >>
}
ELSE
{
<< condition evaluated to FALSE >>
}

How can I get which part of an if expression is true?

Assume I have code like:
if(condition1 || condition2 || condition 3 || condition4)
{
// this inner part will be executed if one of the conditions is true.
// Now I want to know by which condition this part is executed.
}
I'm sure there are better ways to do this, here's one:
int i = 0;
auto check = [&i](bool b)->bool
{
if (!b) ++i;
return b;
};
if (check(false) || // 0
check(false) || // 1
check(true) || // 2
check(false)) // 3
{
std::cout << i; // prints 2
}
|| is short circuit evaluation, so you can have code like this :
if(condition1 || condition2 || condition 3 || condition4)
{
if (condition1 )
{
//it must be condition1 which make the overall result true
}
else if (condition2)
{
//it must be condition2 which make the overall result true
}
else if (condition3)
{
//it must be condition3 which make the overall result true
}
else
{
//it must be condition4 which make the overall result true
}
// this inner part will executed if one of the condition true. Now I want to know by which condition this part is executed.
}
else
{
}
If the conditions are independent of each other, you need to check them separately, or, if they belong to one variable, you can use a switch statement
bool c1;
bool c2
if ( c1 || c2 )
{
// these need to be checked separately
}
int i; // i should be checked for multiple conditions. Here switch is most appropriate
switch (i)
{
case 0: // stuff
break;
case 1: // other stuff
break;
default: // default stuff if none of the conditions above is true
}
Without a switch you can use only or and if statements:
if(condition1 || condition2 || condition 3 || condition4) {
// this inner part will executed if one of the condition true.
//Now I want to know by which condition this part is executed.
if ( condition1 || condition2 ) {
if ( condition1 )
printf("Loop caused by 1");
else
printf("Loop caused by 2");
else
if ( condition3)
printf("Loop caused by 3");
else
printf("Loop caused by 4");
}
I'm not sure that this is the most efficient thing you've ever seen, but it will identify which of the four conditions caused entry into the if ... block.
If you need to know for programmatic reasons, i.e. run different code depending on which condition is true, you could do something like this
if (condition1)
{
...
}
else if (condition2)
{
...
}
else if (condition3)
{
...
}
else if (condition4)
{
...
}
else
{
...
}
If you only want to know for debugging reasons, just do a printout.
What about the comma operator?
By using that logical operators follow the short circuit evaluation method, the following works fine:
int w = 0; /* w <= 0 will mean "no one is true" */
if ( (w++, cond1) || (w++, cond2) || ... || (w++, condN) )
printf("The first condition that was true has number: %d.\n", w);

C++ Try Catch inside loop

I have this C++ program with the following general structure
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
//condition B == false (supposed to leave 2nd loop and go back to first loop)
I want it to get out of 2nd loop when there's an exception and go back to 1st loop until condition B is tue again. As described above it doesn't work as I expect. What seems to be happening is that code gets stuck in catch and never leaves it.
How can I arrange it to make it work as I need?
Note: condition A is never false.
add the break keyword to the catch
Also notice that you have b == false;
That is checking that b is equal to false, not setting b = false.
bool flag1 = true, flag2 = true;
while (flag1)
{
// some work so that flag2 == true
while (flag2)
{
try
{
}
catch (...) // any exception happens
{
break;
}
}
}
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
{
//condition B == false (supposed to leave 2nd loop and go back to first loop)
break ;
}
Notice: Please do not use, even in examples, things like condition A == true. It is better to use while (condition A).
You can call break within the catch block to escape the second loop:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
while (B) {
try {
B = doSomethingElseThatMayThrow();
} catch (...) {
break;
}
}
}
}
Alternatively, you could place the second loop inside the try block:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
try {
while (B) {
B = doSomethingElseThatMayThrow();
}
} catch (...) {}
}
}