Optimize if else condition with (repeatable actions in branches) - if-statement

I have this code. At first jobDone is false and the program does the first step, then the second and sets the jobDone variable to true stating that all tasks completed successfully.
But I might choose to run this bit of code again and I don't want to do the first step again since it might not be necessary. So if the job has been done at least once and if checkSomething() concludes that everything is OK it should go ahead and do only secondStep();
Otherwise, if checkSomething() finds out that something is wrong then I must repeat the first and as well the second step (like in the initial situation).
jobDone = false;
if (jobDone) {
if (checkSomething()) {
doSecondStep();
} else {
doFirstStep();
doSecondStep();
}
} else {
doFirstStep();
doSecondStep();
jobDone = true;
}
But I feel that i'm repeating myself. Is there a better way of writing this? Thank yoou.

if(jobDone && checkSomething()) {
doSecondStep();
} else {
doFirstStep();
doSecondStep();
jobDone = true;
}

The second step is always executed, I suggest you move that to the end first:
jobDone = false;
if (jobDone) {
if (!checkSomething()) {
doFirstStep();
}
} else {
doFirstStep();
jobDone = true;
}
doSecondStep();
However, there's only one condition that would cause doFirstStep() not to be executed and that's when jobDone == true and checkSomething == false, so we could just check for that.
The whole thing can be summarized to three lines:
if (!(jobDone && !checkSomething())) { doFirstStep(); }
jobDone = !jobDone;
doSecondStep();

Related

How to run main statement and else statement only once, inside loop?

So I'm trying to add controller support to an old game, but am having some trouble with the logic. I need to execute a command once a trigger is pressed, one time. Otherwise I need to execute a command one time if the trigger is released. All inside a while loop, I know I'm missing something obvious. I'm having trouble only sending the -attack command once.
while (true) {
Sleep(100);
bool flag = false;
if ((gamepad.rightTrigger == 1) && (flag == false))
{
SendCommandToConsole(0, 0, "+attack");
flag = true;
}
else if ((gamepad.rightTrigger == 0) && (flag == true))
{
SendCommandToConsole(0, 0, "-attack");
}
}
Let me show you my proposal:
bool flag = false;
while (true) {
Sleep(100);
if ((gamepad.rightTrigger == 1) && (!flag))
{
SendCommandToConsole(0, 0, "+attack");
flag = true;
}
else if ((gamepad.rightTrigger == 0) && flag)
{
SendCommandToConsole(0, 0, "-attack");
}
}
You see three things:
flag is declared outside of the while-loop, which has been proposed before and which is the answer to your question.
Don't check for flag == true or flag == false, just for flag or !flag, this improves the readability of your code.
I removed some obsolete empty lines. It's ok to leave an empty line between different parts of your source code, but it's advised to keep if-, then-, else-loops together, also for readability purposes.

why are my if and else if statements not running?

same as title.
const inputs =document.querySelectorAll('input');
inputs.forEach(function(_inputs){
_inputs.readOnly = !_inputs.readOnly;
if(_inputs.readyOnly == false){
_inputs.classList.remove("readOnlyItem")
_inputs.classList.add("notReadOnly")
}else if(_inputs.readyOnly == true){
_inputs.classList.add("readOnlyItem")
_inputs.classList.remove("notReadOnly")
}
});
As far as I can tell every thing seems right and should be working but the if statments never return true for some reason.

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"));

Stuck with code using if statements

This might be a non-sense question, but i'm kind of stuck so I was wondering if someone can help. I have the following code:
bool while_condition=false;
do{
if(/*condition*/){
//code
}
else if(/*condition*/){
//code
}
else if(/*condition*/){
//code
}
...//some more else if
else{
//code
}
check_for_do_while_loop(while_condition, /*other parameters*/);
}while(while_condition);
the various if and else if exclude with each other but each have other if inside; if a certain condition is met (which can't be specified in a single if statement), then the code return a value and the do while loop is ended. But if, after entering a single else if, the conditions inside aren't met the code exit without actually doing nothing, and the while loop restart the whole.
I want the program to remember where he entered and avoid that part of the code, i.e. to avoid that specific else if he entered without any result, so he can try entering another else if. I thought about associating a boolean to the statements but I'm not quite sure on how to do it. Is there a way which allows me not to modify the code structure too much?
To give an idea of one way of approaching this that avoid loads of variables, here is an outline of how you might data-drive a solution.
class TestItem
{
public:
typedef bool (*TestFuncDef)(const state_type& state_to_test, std::shared_ptr<result_type>& result_ptr);
TestItem(TestFuncDef test_fn_parm)
{
test_fn = test_fn_parm;
already_invoked = false;
}
bool Invoke(const state_type& state_to_test, std::shared_ptr<result_type>& result_ptr)
{
already_invoked = true;
return test_fn(state_to_test, result_ptr);
}
bool AlreadyInvoked() const {return already_invoked; }
private:
TestFuncDef test_fn;
bool already_invoked;
};
std::shared_ptr<result_type> RunTest(std::list<TestItem>& test_item_list, state_type& state_to_test)
{
for(;;) {
bool made_a_test = false;
for (TestItem& item : test_item_list) {
std::shared_ptr<result_type> result_ptr;
if (!item.AlreadyInvoked()) {
made_a_test = true;
if (item.Invoke(state_to_test, result_ptr)) {
return result_ptr;
}
else
continue;
}
}
if (!made_a_test)
throw appropriate_exception("No conditions were matched");
}
}
This is not supposed to be a full solution to your problem but suggests another way of approaching it.
The important step not documented here is to build up the std::list of TestItems to be passed to RunTest. Code to do so might look like this
std::list<TestItem> test_item_list;
test_item_list.push_back(TestItem(ConditionFn1));
test_item_list.push_back(TestItem(ConditionFn2));
The definition of ConditionFn1 might look something like
bool ConditionFn1(const state_type& state_to_test, std::shared_ptr<result_type>& result_ptr)
{
// Do some work
if (....)
return false;
else {
result_ptr.reset(new result_type(some_args));
return true;
}
}

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);