Why is my if statement behaving this way? - java

I ran across this puzzle today. Obviously, this isn't correct style, but I'm still curious as to why no output is coming out.
int x = 9;
int y = 8;
int z = 7;
if (x > 9) if (y > 8) System.out.println("x > 9 and y > 8");
else if (z >= 7) System.out.println("SHOULD OUTPUT THIS x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
The above has no output when run. But, when we add in brackets for the if-statement, suddenly the logic behaves as I expect.
int x = 9;
int y = 8;
int z = 7;
if (x > 9) {
if (y > 8) System.out.println("x > 9 and y > 8");
}
else if (z >= 7) System.out.println("SHOULD OUTPUT THIS x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
This outputs "SHOULD OUTPUT THIS x <= 9 and z >= 7". What is going on here?
Thanks!

If you rewrite the first way like this (which is how it is behaving), it is easier to understand
if (x > 9)
if (y > 8) System.out.println("x > 9 and y > 8");
else if (z >= 7) System.out.println("SHOULD OUTPUT THIS x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
Since x is not > 9, the block never executes.

This:
if (x > 9) ... if (y > 8) ... else if (z >= 7) ... else
is ambiguous, because during parsing the else could be bound to the first if or the second if. (This is called the dangling else problem). The way Java (and many other languages) deals with this is to make the first meaning illegal, so the else clauses always bind to the innermost if statements.

Just fix the indenting on your code and the issue becomes clear:
int x = 9;
int y = 8;
int z = 7;
if (x > 9)
if (y > 8)
System.out.println("x > 9 and y > 8");
else if (z >= 7)
System.out.println("SHOULD OUTPUT THIS x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");

Because you are using the else block in inner most level
Your code is being treated as the following code
if (x > 9) // This condition is false, hence the none of the following statement will be executed
{
if (y > 8)
{
System.out.println("x > 9 and y > 8");
} else if(z >= 7)
{
System.out.println("SHOULD OUTPUT THIS x <= 9 and z >= 7");
}
else
{
System.out.println("x <= 9 and z < 7");
}
}
The first condition specified with the if statement is false and control in not entering into the code associated with that condition and simply reaching the end of the program and printing nothing.
That's why its normal practice is to enclose statements with brackets even if you are writing a single statement.

Related

Is it possible in an "if-statement" to execute the actual statement if the condition is false?

I encountered the code example below in the JavaNotes book. The answer was that after execution the x is equal to 2.
My question is how exactly does this work?
I see it is not an if-else flow, but in the second "if" the boolean expression is false, so X shall not obtain value 2.
How is this happening?
int x;
x = -1;
if (x < 0)
x = 1;
if (x >= 0)
x = 2;
Try rubber duck debugging! Read the comment in the code so you can understand how your code work :
int x;
x = -1;
if (x < 0) { //-1 < 0 = true
x = 1; //enter here -> change x = 1
}//end of the first if
if (x >= 0) {//1 >= 0 = true
x = 2; //enter here -> change x = 2
}//end of the second if
System.out.println(x);//result is 2
If you expect x = 1 then your code should look like this :
if (x < 0) { //-1 < 0
x = 1; //enter here -> change x = 1
} else if (x >= 0) {//1 >= 0
//^^^^------------------------------------------note the else
x = 2; //enter here -> change x = 2
}
x = -1;
first if: x < 0 is true,
so x gets new value 1
second if: x > 0 is true
so x gets new value 2
x = 2;

Error with validation with while loop

im having some trouble with my validation. Here is my code
int a = keyboard.nextInt();
int b = keyboard.nextInt();
while(x < -50 || x > 50 && y < -50 || y > 50)
{
System.out.println("Error " + a + " is out of range");
System.out.println("Error " + b + " is out of range");
System.out.println();
System.out.print("Input two integers in the range [-50, + 50]: ");
a = keyboard.nextInt();
b = keyboard.nextInt();
}
while( x < -50 || x > 50)
{
System.out.println("Error " + a + " is out of range");
System.out.println();
System.out.print("Input two integers in the range [-50, + 50]: ");
a = keyboard.nextInt();
b = keyboard.nextInt();
}
while( y < -50 || y > 50)
{
System.out.println("Error " + b + " is out of range");
System.out.println();
System.out.print("Input two integers in the range [-50, + 50]: ");
a = keyboard.nextInt();
b = keyboard.nextInt();
}
My problem, is that the user input needs to be a & b from [-50, 50]
But when i input -100 and 100 I only get a is out of range or b is out of range not both.
Input: a= -100 b = 100
Output:
System.out.println("Error " + -100 + " is out of range"); // CORRECT
System.out.println("Error " + 23 + " is out of range"); // ? INCORRECT
What am i doing wrong
You're being naughty with your operator precedence.
x <= -50 || x >= 50 && y <= -50 || y > 50
is evaluated as
x <= -50 || (x >= 50 && y <= -50) || y > 50
You need to put in some parentheses:
(x <= -50 || x >= 50) && (y <= -50 || y > 50)
Also, check the precise relationship between a, b, x, and y. Why do you assign to a and b, yet then immediately test x and y?
Use absolute values, remember |a| < x means -x < a < x
so both a and b must meet the criteria, or another way, you will ask as long as **a > 50** or **b > 50**
int a = -100;
int b = -100;
Scanner scan = new Scanner(System.in);
while (Math.abs(a) > 50 || Math.abs(b) > 50) {
System.out.println("need a:");
a = scan.nextInt();
System.out.println("need b:");
b = scan.nextInt();
}
scan.close();
System.out.println("am gone!");
check the while loop.
while( x <= -50 || x >= 50 && y <= -50 || y > 50)
both conditions need to be true to execute succesfully.check the &&
As explained in the comments, you are testing x and y but reading a and b.
Additionally, your code can be simplified:
boolean valid = true;
do {
System.out.print("Input two integers in the range [-50, + 50]: ");
int a = keyboard.nextInt();
int b = keyboard.nextInt();
if ( (a < -50) || (a > 50) ) {
valid = false;
System.out.println("Error " + a + " is out of range");
}
if ( (b < -50) || (b > 50) ) {
valid = false;
System.out.println("Error " + b + " is out of range");
}
} while (!valid);
while( x <= -50 || x >= 50 && y <= -50 || y > 50) Java uses "short circuit evaluation" of logical operators. So if x = -100 and y = 0, the loop will be entered because -100 <= -50 and no other conditions matter because true || anything is always true. Use parentheses to control how logical operations are processed. I suggest putting the Boolean condition controlling the while loop into a nicely named method.
private boolean bothParamsAreOutOfRange(int x, int y) {
boolean rtn = false;
if ((x <= -50 || x >= 50) && (y <= -50 || y > 50)) {
rtn = true;
}
return rtn;
}
while(bothParamsAreOutOfRange(x, y)) {
... as before ...
}

Java control if else statement

I'm using the below free text to learn intro to java and I am having trouble understanding the difference between the code segments:
http://math.hws.edu/eck/cs124/downloads/javanotes7-linked.pdf
Example 1
int x;
x = -1;
if (x < 0)
x = 1;
else
x = 2;
Example 2
int x;
x = -1;
if (x < 0)
x = 1;
if (x >= 0)
x = 2;
In Example 1, x is 1; In Example 2, x is 2.
On the right, if -1 is not > or = to 0 then shouldn't the output be 1? Could someone please explain why the output would instead be 2?
Once the second if statement is evaluated, x the first has already taken effect--so the value of x is now 1.
if (x < 0)
x = 1;
if (x >= 0) //x is 1 because you've already evaluated the above!
x = 2;
The else keyword creates mutually exclusive branches: only one can be executed. So if you had this, the behavior would be as you expected:
if (x < 0)
x = 1;
else if (x >= 0)
x = 2;
In the Example 1, only one of the statements x = 1; or x = 2; will be executed because it uses an if...else statement.
In the Example 2, both statements will be executed because it uses two separate if statements, and because both conditions are true at the time they are evaluated.
In the second example; first you go through the first if condition:
x = -1;
if (x < 0) x = 1;
x is less than 0, so x becomes 1.
When you go to the second if condition:
if (x >= 0) x = 2;
x is still 1, and 1 is greater than 0, so x becomes 2.

JOptionPane error-- Tortoise and Hair race

I am new to my Intro to Java course and am struggling with a program. I have posted about this program before but this is a different question. My program is supposed to model a race between a hare and a tortoise. I think I have everything I need but I am having trouble with my JOptionPane phrase. I think my phrase is Ok, but I am experiencing problems with the while portion of my statement. Here is the error message: cannot find symbol - Variable OK.
I use Blue J to write and compile my program. Is there any reason why its not working? I thought the variable OK was the thing that the program user chooses to start the program. Am I mistaken? Can anyone help with this problem? Is there anything else you see in my program that needs fixing? Thanks
import java.util.Random;
import javax.swing.JOptionPane;
class Race
{
int [] race = new int[70];
int tortoise;
int hare;
Random randomGenerator = new Random();
public boolean again = true;
public void StartRace()
{
tortoise = 1;
hare = 1;
System.out.println("AND THEY'RE OFF!!!!");
while (tortoise < race.length && hare < race.length)
{
moveHare();
moveTortoise();
DisplayCurrentLocation();
String request;
}
if
(tortoise > hare)
{
System.out.println("\n TORTOISE WINS!!");
}
else if
(hare > tortoise)
{
System.out.println("\n HARE WINS!!!");
}
else if
(hare == tortoise)
{
System.out.println("TIE!!!");
}
}
public void moveTortoise()
{
int n = randomGenerator.nextInt(10) + 1;
//fast plod
if ( n > 0 && n< 6)
tortoise += 3;
//slip
else if (n > 10 && n< 11)
tortoise -= 6;
//slow plod
else if (n > 6 && n< 9)
++tortoise;
// protect from going past start
if (tortoise < 1)
tortoise = 1;
// to make sure game ends
else if (tortoise > 70)
tortoise = 70;
}// end tortoise
public void moveHare()
{
int m = randomGenerator.nextInt(10) + 1;
//big hop
if (m > 0 && m<3)
hare += 9;
//big slip
else if (m < 6)
hare -= 12;
// small hop
else if (m > 3 && m< 5)
++hare;
// )small slip
else if (m < 9)
hare -= 2;
else if (m < 11)
hare += 0;
//ensure hare doesn't go past start
if (hare < 1)
hare = 1;
// ensure hare doesnt go past end
else if (hare > 70)
hare = 70;
} // end movehare
public void DisplayCurrentLocation()
{
//this is the location of each on the array
for (int count = 1; count <= 70; count++)
// when at same location
if (count ==tortoise && count ==hare)
{
System.out.println("OUCH");
}
else if (count == hare)
{
System.out.println("H");
}
else if (count == tortoise)
{
System.out.println("T");
}
else
System.out.println();
}
public static void main ( String[] args)
{
Race Application = new Race();
int startRaceRequest;
while(startRaceRequest != JOptionPane.OK_OPTION)
{
JOptionPane.showConfirmDialog(null, "Select OK To Begin the Race!:");
}
do
{
Application.StartRace();
} while(startRaceRequest != JOptionPane.OK_OPTION);
}
}
To your question with the JOptionPane: I suggest you to use
JOptionPane.showConfirmDialog(null, "Message");
instead of
JOptionPane.showMessageDialog(null, "Message");
because it allows you to do this:
int startRaceRequest;
while(startRaceRequest != JOptionPane.OK_OPTION)
JOptionPane.showConfirmDialog(null, "Hit OK to start the race!");
I don't really understand what you mean by "Ok" later on in your code, but if you refer to the confirmed dialog, try using JOptionPane.OK_OPTION wich represents an int.
Also some help with your code: At the beginning you initialize the int[] race with the length of 70. Whenever you check if one of the racers is at or above 70, you do it like this
if(tortoise < 70 && hare < 70){}
wich is called hard-coding and you should try to avoid that as much as possible, to keep your code as dynamic as possible.
If you do this
if(tortoise < race.length && hare < race.length)
you don't have to rewrite half your code just because you changed the length of the race.
Another thing to the methods MoveTortoise and MoveHare. Conventionally the should be named moveTortoise and moveHare because method ins Java begin with lower case (that goes for all your methods!). Within those two methods inside your if conditions you write way too much code. for example this:
if (m == 1 || m == 2)
hare += 9;
else if (m == 6)
hare -= 12;
else if (m == 3 && m == 5) //there is something wrong here, m cant be 5 and 3 ;)
++hare;
else if (m == 7 || m == 8)
hare -= 2;
else if (m == 9 || m == 10)
hare += 0;
could be cut to this:
if(m > 0 && m < 3){ // if a number is > 0 and < 3 -> number is 1 or 2
} else if(m < 6){ // if a number is > 0 and > 3 -> if number is < 6 -> number could be 3, 4 or 5
} else if(m == 6){
} else if(m < 9){ // -> 7 or 8
} else if(m < 11){ // 9 or 10
}
In Addition, you use a random number generator and I think you are aiming for a number between 1 to 10, however this
int m = randomGenerator.nextInt(11);
will return a number from 0 to 10. Instead, try this:
int m = randomGenerator.nextInt(10) + 1;
wich will return a number from 0 to 9, adding one will result in a number between 1 and 10.
Hope this helps. Please remember to give feedback and mark a solution if your question was answered.

The rules of Nested IF conditional statements without using curly braces

This might be an extremely beginner question given that I have about 2 years of programming experience already, however something always bothered me with nested IF conditional statements and how they work without having curly braces on them.
I've always used the braces as to keep my coding organized. For example like this.
public static void main(String[] args)
{
int x = 9;
int y = 8;
int z = 7;
if (x > 9)
{
if (y > 8)
{
System.out.println("x > 9 and y > 8");
}
}
else if (z >= 7)
{
System.out.println("x <= 9 and z >= 7");
}
else
{
System.out.println("x <= 9 and z < 7");
}
}
I've always used this pattern as it has always worked for me.
However, why is it that something written in this format doesn't work the same way?
public static void main(String[] args)
{
int x = 9;
int y = 8;
int z = 7;
if (x > 9)
if (y > 8)
System.out.println("x > 9 and y > 8");
else if (z >= 7)
System.out.println("x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
}
The first code would print out x <= 9 and z >= 7, but the second code would print nothing. (I'm assuming that the else if and else statements are inside the initial if statement).
In other words, what are the rules in how the compiler tests the conditional statements when no curly braces take place like the example above? I've tried looking for information online, but I can't seem to find information and/or I don't know how to specifically call this problem in order to research my doubts.
On second if I put braces on it, It will be like this to the compiler. Because else if or else finds immediate if.
if (x > 9) {
if (y > 8){
System.out.println("x > 9 and y > 8");
}else if (z >= 7) {
System.out.println("x <= 9 and z >= 7");
}else {
System.out.println("x <= 9 and z < 7");
}
}
If you have to replicate you should put at least one braces like:
if (x > 9) {
if (y > 8)
System.out.println("x > 9 and y > 8");
else if (z >= 7)
System.out.println("x <= 9 and z >= 7");
}else
System.out.println("x <= 9 and z < 7");
Now, Last else is off first if statement for sure.
The compiler does not care about indentation. An else clause is always associated with the last if that doesn't already have an else. This:
if (x > 9)
if (y > 8)
System.out.println("x > 9 and y > 8");
else if (z >= 7)
System.out.println("x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
is the same as this:
if (x > 9)
{
if (y > 8)
{
System.out.println("x > 9 and y > 8");
}
else
{
if (z >= 7)
{
System.out.println("x <= 9 and z >= 7");
}
else
{
System.out.println("x <= 9 and z < 7");
}
}
}
Also, notice that else if(...) ... really just means else {if(...) {...}} - it's a combination of else and if, not a special feature.
This isn't really a matter of curly braces, it's a matter of how you've formatted your code. Whitespace doesn't matter in Java (or C++.)
So while you've written this:
if (x > 9)
if (y > 8)
System.out.println("x > 9 and y > 8");
else if (z >= 7)
System.out.println("x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
That doesn't mean it's equivalent to your original code. To illustrate why, here's how this code would be more reasonably formatted:
if (x > 9)
if (y > 8)
System.out.println("x > 9 and y > 8");
else if (z >= 7)
System.out.println("x <= 9 and z >= 7");
else
System.out.println("x <= 9 and z < 7");
I hope that illustrates what's going on here.
Curly braces are, essentially, to keep the compiler on track. If you only have 1 if, and 1 else, such as:
if (x < 3)
// some code here
else
// something else here
When you do math problems in real life, order of operations tells you to do what's in the parentheses first, no? The curly brackets are a grouping symbol used to denote what order of operations the compiler is to take.

Categories