The new gnuplot (5.x) has new syntax for logic, but I cannot get the 'else if' statement to work. For example:
if(flag==1){
plot sin(x)
}
else{
plot cos(x)
}
does work, but:
if(flag==1){
plot sin(x)
}
else if(flag==2){
plot cos(x)
}
else if(flag==3){
plot tan(x)
}
does not. I have tried many combinations of {} and placement of 'if' and 'else' to no avail. Does anyone know how to correctly implement 'else if' in gnuplot 5.x?
The gnuplot guide (http://www.bersch.net/gnuplot-doc/if.html) has no examples of the new logic syntax using 'else if' but does have examples using the old syntax, but I would rather avoid the old.
Based on a brief inspection of the source code of command.c in the latest version of Gnuplot, I would say that this feature is not supported. To be more specific, the relevant part can be found on line 1163 (see below). The parser first makes sure that the if is followed by a condition enclosed in parentheses. If the following token is a {, it activates the new syntax, isolates the entire if block enclosed in a pair of matching {} and optionally looks for an else which is however permitted to be followed also only with a {}-enclosed clause. Because of this, a simple script such as:
if(flag == 1){
print 1;
}else if(flag == 2){
print 2;
}
indeed produces the error message expected {else-clause}. One workaround would be to nest the if statements as:
if(flag == 1){
}else{
if(flag == 2){
}else{
if(flag == 3){
}
}
}
which is admittedly slightly more verbose...
void
if_command()
{
double exprval;
int end_token;
if (!equals(++c_token, "(")) /* no expression */
int_error(c_token, "expecting (expression)");
exprval = real_expression();
/*
* EAM May 2011
* New if {...} else {...} syntax can span multiple lines.
* Isolate the active clause and execute it recursively.
*/
if (equals(c_token,"{")) {
/* Identify start and end position of the clause substring */
char *clause = NULL;
int if_start, if_end, else_start=0, else_end=0;
int clause_start, clause_end;
c_token = find_clause(&if_start, &if_end);
if (equals(c_token,"else")) {
if (!equals(++c_token,"{"))
int_error(c_token,"expected {else-clause}");
c_token = find_clause(&else_start, &else_end);
}
end_token = c_token;
if (exprval != 0) {
clause_start = if_start;
clause_end = if_end;
if_condition = TRUE;
} else {
clause_start = else_start;
clause_end = else_end;
if_condition = FALSE;
}
if_open_for_else = (else_start) ? FALSE : TRUE;
if (if_condition || else_start != 0) {
clause = new_clause(clause_start, clause_end);
begin_clause();
do_string_and_free(clause);
end_clause();
}
Related
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.
the printOptimalAlignment function is misbehaving. goto and return will not exit when the function reaches location (1,1)... where it should end, no crash and it stops at seemingly an arbitrary location of (6,6)... because for some reason it increments at the end of the function even though there is no increment-er for the values int yL, int xL, (but I don't follow why it calls itself if it gets to the end of the function without any "hits" on the if statements.
Full code:
https://repl.it/#fulloutfool/Edit-Distance
void printOptimalAlignment(int** arr, string y, string x,int yL, int xL){
int I_weight=1, D_weight=1, R_weight=1;
bool printinfo_allot = 1,printinfo = 1;
if(printinfo_allot){
cout<<"Location: "<<"("<<xL<<","<<yL<<")"<<"-------------------------------\n";
cout<<"Same check Letters: "<<x[xL-2]<<","
<<y[yL-2]<<"("<<(x[xL-2] == y[yL-2])<<")"<<"\n";
cout<<"LL: "<<"("<<xL-1<<","<<yL<<")"
<<":"<<arr[yL][xL-1]
<<":"<<(arr[yL][xL-1]+I_weight)
<<":"<<(arr[yL][xL])
<<":"<<(((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1)
<<":"<<(yL>=1 && xL>=1)<<"\n";
cout<<"xL state:"<<((&x[xL]))<<":"<<(x[xL-1])<<"\n";
cout<<"yL state:"<<((&y[yL]))<<":"<<(y[yL-1])<<"\n";
string tx = &x[xL];
cout<<x.length()<<","<<(tx.length()+1)<<"\n";
}
string tx = &x[xL]; // slopy hotfix
if(x.length()==(tx.length()+1)){
cout<<"return functionality not working?-=-=-=-=-=-=-=-=\n";
cout<<"-> Prep last, current distance = "<<arr[yL][xL] <<"\n";
return;
//printOptimalAlignment(arr,y,x,yL-1,xL-1);
//cant use this goto... but where does it go?
//goto because_Im_a_terrible_person;
throw "how?... breaking rules... make it stop";
}
if(yL>=1 && xL>=1 && (x[xL-2] == y[yL-2]) == 1){
if(printinfo){
cout<<"-> Same (same char), current distance = "<<arr[yL][xL] <<"\n";
}
printOptimalAlignment(arr,y,x,yL-1,xL-1);
}
if(yL>=1 && xL>=1 && (arr[yL-1][xL-1] == arr[yL][xL])){
if(printinfo){
cout<<"-> Swap (same int), current distance = "<<arr[yL][xL] <<"\n";
if(arr[yL-1][xL-1]==0)cout<<"---this is last---\n";
}
printOptimalAlignment(arr,y,x,yL-1,xL-1);
}
if(yL>0 && xL>0 && (arr[yL-1][xL]+D_weight == arr[yL][xL])){
if(printinfo){
cout<<"-> Delete, current distance = "<<arr[yL][xL]<<"\n";
}
printOptimalAlignment(arr,y,x,yL-1,xL);
}
//really weird ((yL>1 && xL>1) && (((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1))
//not true if it is?
bool seperate = (((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1);
if(yL>=1 && xL>=1){
if((((arr[yL][xL-1]+I_weight) == arr[yL][xL])==1) && (true)){
if(printinfo){
cout<<"-> Insert, current distance = "<<arr[yL][xL]<<"\n";
cout<<"Next Location1: "<<"("<<xL-1<<","<<yL<<")"<<"\n";
}
printOptimalAlignment(arr,y,x,yL,xL-1);
return;
//how does it get here... also return gets ignored... prob another stack issue
cout<<"insert function broke?????? # (1,1) ???????????????\n";
//return;
}
}
return;
cout<<"END... Hopefully.. if you see this Something went wrong\n";
because_Im_a_terrible_person:
cout<<"QUIT\n";
}
I suspect your problem is that your function calls itself and you don't appear to be taking into account what should happen next after that call to itself finishes. So you get to your finish condition where you say the return doesn't work, but it does... it just returns to where you left off in the previous call to printOptimalAlignment, which still might do something before returning to its caller, and so on. You have three different sites where you recursively call printOptimalAlignment that aren't immediately followed by a return statement, and at any of these it might be that the code will continue and trigger another of your conditional blocks.
I a newbie C++ programmer trying to test aruments/parameters passed to a program.
Multiple arguments can be passed to the program, however I want to test that if certain arguments are passed then other arguments become invalid.
e.g. PGM accepts arg(1) arg(2) arg(3) arg(4) arg(5) etc...
if arg(1) and arg(2) are supplied then arg(3), arg(4) and arg(5) etc... are invalid and the program should terminate with an error message if they are also supplied along with arg(1) and arg(2).
I've thought that using boolean IF tests would be a good way to check if certain values are true/false.
I searched on stackoverflow but not found an answer that encompasses exactly what i'm trying to do. If someone can point me in the right direction or suggest a far more efficient way of doing this I would be very grateful.
My code currently looks like this:
bool opt1 = false;
bool opt2 = false;
bool opt3 = false;
bool opt4 = false;
bool opt5 = false;
for(int i=1; i<argc; i++) {
char *str = argv[i];
if (strcmp (str, "-opt1:")==0) {opt1 = true;}
else if (strcmp (str, "-opt2:")==0) {opt2 = true;}
else if (strcmp (str, "-opt3:")==0) {opt3 = true;}
else if (strcmp (str, "-opt4:")==0) {opt4 = true;}
else if (strcmp (str, "-opt5:")==0) {opt5 = true;}
}
if((opt1) && (opt2) && (~(opt3)) && (~(opt4)) && (~(opt5)) {
** DO SOMETHING **
} else {
** DISPLAY ERROR MESSAGE AND USAGE TEXT **
}
A good solution would be using operands ! and &&
! denotes "not" (or in such case "not true") while && combines two different logical comparisons (in such case, "logic test 1" and "logic test 2")
Here's an example to do it:
if((opt1 && opt2)&&(!(opt3||opt4||opt5))){
/*
Do something if opt1 and opt2 are true and others are false
*/
}
This is practically the same as #Fareanor's solution above (first solution)
A possible fix could be (if I have well understood your problem):
if(opt1 && opt2) // opt3, opt4 and opt5 are invalid
{
if(!(opt3 || opt4 || opt5))
{
// Do something
}
else
{
// Display error message because at least opt3 or opt4 or opt5 is provided and not requested
}
}
else // opt3, opt4 and opt5 are valid
{
// Do something
}
But I think it could be better to just ignore the obsolete parameters instead of display an error while you can still run your process with only opt1 and opt2. Which could lead us to the simpler code:
if(opt1 && opt2)
{
// Do something without using opt3, opt4 and opt5
}
else
{
// Do something taking into account opt3, opt4 and opt5
}
I hope it is what you was looking for.
I have this little function that is giving me trouble, only part of the function will follow my conditions at one time.
bool trend()
{
//is there a trend?
close1 = iClose(NULL,0,1); //vars
close2 = iClose(NULL,0,2);
close3 = iClose(NULL,0,3);
open1 = iOpen(NULL,0,1);
open2 = iOpen(NULL,0,2);
open3 = iOpen(NULL,0,3);
if(close3 > open3 && close2 > open2 && close1 > open1)
{
return(true); //uptrend
}
else if(close3 < open3 && close2 < open2 && close1 < open1)
{
return(false); //downtrend
}
else return(EMPTY_VALUE);
}
This is how the function gets called, under int start()
trending = trend();
if (trending == true) Order = SIGNAL_BUY; // Rule to ENTER a Long trade
if (trending == false) Order = SIGNAL_SELL; // Rule to ENTER a Short trade
As written above, my sell signal will work following the conditions, but the buy signals don't follow the conditions, and I can't figure out how they are triggering.
If I remove the "else return(EMPTY_VALUE);" then the buy orders start following the condition but the sell orders no longer follow the conditions. The broken sell order seems to behave like the broken buy order was.
Any ideas why my function is behaving like this? Thanks!
Your function is declared as bool trend(), which means that it can return either true or false. In the line else return(EMPTY_VALUE), the constant EMPTY_VALUE (which has the value 0x7FFFFFFF according to the MQL documentation) is implicitly converted to true. This means that your function will return true (which emits your buy signal) if there is no uptrend and no downtrend.
If you leave out the last line else return(EMPTY_VALUE) you have a missing return statement. This leads to undefined behaviour if you try to access the return value of the function, which you do in the line trending = trend().
To sum it up: Your problem is that the trend function can only return one of two values, true or false. But what you need is a function that returns one of three values uptrend, downtrend, no_trend. You could declare an enum with those three values and change the return type accordingly:
enum Trend {
UPTREND,
DOWNTREND,
NONE
}
Trend trend() {
// check if there is a trend
// [...]
if (close3 > open3 && close2 > open2 && close1 > open1) {
return UPTREND;
}
else if (close3 < open3 && close2 < open2 && close1 < open1) {
return DOWNTREND;
}
else {
return NONE;
}
}
and then later
Trend trending = trend();
if (trending == UPTREND) Order = SIGNAL_BUY;
if (trending == DOWNTREND) Order = SIGNAL_SELL;
I am writing a program in which I use an if statement to check some condition; if true I increment a counter. The problem is that as soon as the statement is true the variable either gets incremented endlessly or by random number.
I have been trying to use some clause to break out of this statement if condition meet but with no luck
my code:
if(res_vect_angle >=60 && res_vect_angle <=100 && left_mag_b >100)
{
//line(drawing, *iter_s, *(iter_s -1), Scalar( 255, 255, 255 ), 2,8 );
left_hook_count++;
cout<<"Left Hook:..........................!!! "<<left_hook_count<<endl;
if(left_hook_count++ == true)
{
break;
}
}
The whole chunk of code associated with the issue:
float M1, M2;
float A1, A2;
double left_mag_a, left_mag_b;
double res_vect_angle;
int i = 0;
for(vector<Point>::iterator iter_lh = Leftarm.begin(); iter_lh != Leftarm.end(); ++iter_lh)
{
if(iter_lh->y <=240 && iter_lh->y >=60 && iter_lh->x >=340 && iter_lh->x <=680)
{
left_detect.push_back(*iter_lh);
if(i % 4 == 0)
{
if(left_detect.size()>4)
{
for(vector<Point>::iterator iter_s = left_detect.begin()+3; iter_s != left_detect.end(); ++iter_s, i++)
{
//Resultant Magnetude
M1 = pow((double) iter_s->x + (iter_s -2)->x,2);
M2 = pow((double) iter_s->y + (iter_s -2)->y,2);
left_mag_a = (M1 + M2);
left_mag_b = sqrt(left_mag_a);
//Resultant Angle
A1 = abs(iter_s->x - (iter_s -2)->x);
A2 = abs(iter_s->y - (iter_s -2)->y);
res_vect_angle = abs(atan2(A1,A2) * 180 /PI);
//cout<<"LEFT HOOK ANGLE IS: "<<res_vect_angle<<endl;
if(res_vect_angle >=60 && res_vect_angle <=100 && left_mag_b >100)
{
//line(drawing, *iter_s, *(iter_s -1), Scalar( 255, 255, 255 ), 2,8 );
left_hook_count++;
cout<<"Left Hook:..........................!!! "<<left_hook_count<<endl;
if(left_hook_count++ == true)
{
break;
}
}
}
}
}
}
}
Hope this helps guys ps. left_hook_count++; is a int variable declared on top of my main().
The best solution is probably to invert the test, and make all the rest of the outer if conditional:
if (whatever) {
// do some stuff
if (left_hook_count != true) { // or whatever the test should really be
// do some more stuff
}
}
You could get the program flow you want using goto with a label after the outer if, but you don't want to.
On the other hand, it sounds like perhaps this is in a loop, and you don't want to enter the if block at all if the counter has been incremented? In that case you want:
if (left_hook_count == 0 && whatever) {
// do some stuff
}
you could provide more details so that we can figure out whats happening.
You might not have initialized it?
and checking again
if(left_hook_count++ == true)
it will increment it again unneccessariy and for for first count (0 : it wont happen)
i guess you 're using some recursive function. so check for Break condition (all test cases too).
Don't compare left_hook_count++ to true. In this context, true is equal to 1, and once left_hook_count exceeds 1, this test will fail and the code will never hit the break.
And you don't break out of an if statement. You break out of a loop; a break in an if statement inside the loop is one way of doing this.
You can just negate the condition, instead of trying to break out of the if:
if(...) {
if(!left_hook_count++) {
// Do what you need to do
}
}
my new answer:
:mylabel if (some_condition)
{
//code
if (some_condition) {break mylabel;}
//code
}
my old answer: Replace the if statement with a while statement containing a unconditional break at the end.
(old answer was before I learned of attaching labels to statement blocks.)
In your case:
while(res_vect_angle >=60 && res_vect_angle <=100 && left_mag_b >100)
{
//line(drawing, *iter_s, *(iter_s -1), Scalar( 255, 255, 255 ), 2,8 );
left_hook_count++;
cout<<"Left Hook:..........................!!! "<<left_hook_count<<endl;
if(left_hook_count++ == true)
{
break;
}
break; //this unconditional break makes the while loop act as an if statement
}
However if you don't have code after the conditional break what's the point of having it? I'm assuming you've omitted that code? The way you wrote it it would simply break out of the inner for loop.