I am trying to make a conditional statement with two "ifs", and it works when I input the correct thing, but when I input an incorrect pokemon and a correct level it still works. I am pretty sure that one of the conditions in my while statement is always true (the first part). Here is the code (sorry about the formatting, just know that it is all formatted correctly in the Java environment):
while ((!(Pokemon.equalsIgnoreCase(Pikachu)) || !(Pokemon.equalsIgnoreCase(Charmander)) || !(Pokemon.equalsIgnoreCase(Squirtle)) || !(Pokemon.equalsIgnoreCase(Bulbasaur))) && !((Level <= 15)&&(Level >= 1 ))) {
System.out.println();
System.out.println("Which one would you like? What level should it be?\n1 to 15 would be best, I think.");
Pokemon = sc.next();
Level = sc.nextInt();
if ((Level <= 15) && (Level >= 1)) {
if ((Pokemon.equalsIgnoreCase(Pikachu)) || (Pokemon.equalsIgnoreCase(Charmander)) || (Pokemon.equalsIgnoreCase(Squirtle)) || (Pokemon.equalsIgnoreCase(Bulbasaur))) {
System.out.print("Added level " + Level + " " + Pokemon + " for " + Trainer + ".");
}
else {
System.out.println("Invalid Pokemon!");
}
}
else {
System.out.println("Invalid Level!");
}
}
Pokeman will always be either not X or not Y, it's basic logic since if it's X, then not-Y is true. If it's Y, then not-X is true. If it's neither then both will be true.
Change || to && and think through your logic on paper.
Should be:
while ((!(Pokemon.equalsIgnoreCase(Pikachu)) &&
!(Pokemon.equalsIgnoreCase(Charmander)) &&
!(Pokemon.equalsIgnoreCase(Squirtle)) &&
!(Pokemon.equalsIgnoreCase(Bulbasaur))) &&
!((Level <= 15)&&(Level >= 1 )))
Related
The problem is that, the first condition in the while loop does not get executed at all even if its true. If i remove the Logical OR from the while loop and just write the first condition (selection.compareToIgnoreCase("O") >0) it works fine. But if there are two conditions with Logical OR, it does not work.
I've tried using equals(), I've also tried to negate the logic using
while(!selection.equals("O") || !selection.equals("E")). The second condition works fine but the first does not work at all.
public class OddsOrEvens {
public static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
System.out.println("Let’s play a game called \"Odds and Evens\"");
System.out.println("Whats your name ? ");
String name = sc.nextLine();
System.out.println("Hi "+ name +", which do you choose? (O)dds or (E)vens?");
String selection = sc.nextLine();
System.out.println("selection: " + selection);
while (selection.compareToIgnoreCase("O") >0 || selection.compareToIgnoreCase("E") >0){
System.out.println("Please enter the correct choice. Select 'O' for odds or 'E' for evens");
selection = sc.next();
}
if(selection.equalsIgnoreCase("O")){
System.out.println(name + " has picked Odds! The computer will be evens.");
}else if (selection.equalsIgnoreCase("E")){
System.out.println(name + " has picked Evens! The computer will be Odds.");
}
}
}
Your string comparison is not correct. Compareto returns -1/0/1 for less/equal/greater.
A clearer way to do this is to use toUppercase().equals(....
while (!selection.toUpperCase().equals("O") && !selection.toUpperCase().equals("E")){
That is for not to hold for two cases, one needs !... && ! ... An OR || would have the effect of being always true, as at least one of the cases is false. Alternatively !(... || ...).
while (!selection.equalsIgnoreCase("O") && !selection.equalsIgnoreCase("E")) {
Let's simplify:
!(n == 1) || !(n == 2) // WRONG
n != 1 || n != 2 // WRONG
will always be true, as either n == 1 is false or n == 2 is false: at most one choice can be true, falsifying the others. So on at least on side is !false, true, so the entire expression is true.
!(n == 1) && !(n == 2) // GOOD
n != 1 && n != 2 // GOOD
The mental mistake is that the linguistic OR mostly means EXCLUSIVE OR.
Possible would have been the equivalent:
!(n == 1 || n == 2) <=> n != 1 && n != 2 [De Morgan's law]
int levelP1;
int levelP2;
do {
p1.startTurn(p1, d1);
p2.startTurn(p2, d1);
levelP1 = p1.getLevel();
levelP2 = p2.getLevel();
} while (levelP1 <= 10 || levelP2 <= 10);
if (levelP1 >= 10) {
System.out.println(p1.getName() + " hit LvL " + levelP1 + " and WON the game !");
} else if (levelP2 >= 10) {
System.out.println(p2.getName() + " hit LvL " + levelP2 + " and WON the game !");
}
I have this pieace of code which is not doing what it is intended...
the "startTurn()" method might or might not level up the player, depending of what happens inside of it...
I want it to exit the loop when either player hits level 10 or above... Cannot figured out how. please help
I want it to exit the loop when either player hits level 10 or above.
Use && instead of || :
while (levelP1 < 10 && levelP2 < 10);
In this way, when one of these two conditions is false, you exit.
When I input a string operator whether it be addition(+), subtraction(-), multiplication(*), division(/) or module(%), it still enters the while loop even when I enter a valid input. I don't know what the problem could be because the while loop is working fine where I have to enter an int-value for variable num2.
import java.util.Scanner;
public class PolishNotationCalc {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num1;
int num2;
String operator;
System.out.println("Polish notation calculator");
System.out.print("Please enter an operation(+, -, *, /, %) ");
operator = input.nextLine();
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))
break;
}
System.out.print("");
System.out.print("Please enter the first number ");
num1 = input.nextInt();
System.out.print("Please enter the second number ");
num2 = input.nextInt();
while (num2 == 0 && operator.equals("/")) {
System.out.println("Please pick a non zero number: ");
num2 = input.nextInt();
}
while (num2 == 0 && operator.equals("%")) {
System.out.println("Please pick a non zero number: ");
num2 = input.nextInt();
}
if (operator.equals("+"))
System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
else if (operator.equals("-"))
System.out.println(num1 + " - " + num2 + " = " + (num1 - num2));
else if (operator.equals("*"))
System.out.println(num1 + " * " + +num2 + " = " + (num1 * num2));
else if (operator.equals("/"))
System.out.println(num1 + " / " + num2 + " = " + (num1 / num2));
else if (operator.equals("%"))
System.out.println(num1 + " % " + num2 + " = " + (num1 % num2));
}
}
if you write your boolean selection in english it reads "While the operator does not equal "+" or it does not equal "-" or it does not equal "/" or it does not equal "*" or it does not equal "%" do the loop.
You need it to say "While the operator does not equal "+" AND it does not equal "-" AND it does not equal "/" AND it does not equal "*" AND it does not equal "%" do the loop.
Change || to && and it should work
For a while loop to be enacted all the parameters need to be true. So if one of the parameters is false, the while loop does not activate.
operator is always not equal to at least one of these strings: e.g. if it is equal to +, then it's not equal to -. If you combine one or more true conditions with ||, the overall result will be true.
You need to use && instead of ||, so that the loop breaks if any one of the conditions match:
while (!operator.equals("+") && !operator.equals("-") && ... ) {
You then don't need to check the value of operator again inside the loop; just let the new loop guard check it and break.
A more syntactically concise alternative would be to use a collection:
List<String> allowedOperators = Arrays.asList("+", "-", "*", "/", "%");
while (!allowedOperators.contains(operator)) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
}
Similarly, when you are checking for num2 == 0:
List<String> zeroDenominatorOps = Arrays.asList("/", "%");
if (zeroDenominatorOps.contains(operator)) {
while (num2 == 0) {
// ...
}
}
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))
break;
}
For example when you enter "+" it becomes while(false || true|| true || true). so it always goes into while loop
You should substitute the || (or) with && (and)
SO
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
Becames
while (!operator.equals("+") && !operator.equals("-") && !operator.equals("*") && !operator.equals("/") && !operator.equals("%")) {
EDIT
You need an AND not an OR.
Lets say you input "+",which is a valid operator.
You'll enter the while because "+" NOT EQUALS "-", your second condition. This because the while conditions are in OR.
If you put these conditions in AND (&&), the "+" does not enter the while because one of the conditions is not true ( !operator.equals("+") )
Try this by changing ! to the whole parameters inside the while loop,It will start working
while (!(operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if ((operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%")))
break;
}
It's simple math that sometimes people just forgets.
Lets simplify the cases.
1 OR x = 1;
1 AND x = x;
Lets be more concrete. Let we have some variable, A, B and C.
In the first case, OR, we have:
Which means that if at least one is true, the all expression is true. In you case having one operation that does not appear means that the loop must be true. Therefore, you should put something like this:
Which means not A AND not B AND not C.
I hope I have helped.
Have a nice day. :)
The loop condition has a different meaning than you thought. It's always true for any input string. It's the kind of condition that you will never have to write (hopefully).
To understand this better, let's first define when an operator can be accepted, in English:
An operator is accepted if it's one of the five operators: +, -, *, /, %
"One of" basically means "or". Therefore the corresponding code is
operator.equals("+") ||
operator.equals("-") ||
operator.equals("*") ||
operator.equals("/") ||
operator.equals("%")
And we can wrap it in a method:
private static boolean acceptable(String operator) {
return operator.equals("+") ||
operator.equals("-") ||
operator.equals("*") ||
operator.equals("/") ||
operator.equals("%");
}
Now the read-check-loop logic is very simple:
String operator;
do {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
} while (!acceptable(operator));
#SaclyrBarlonium, this is what I'm talking about. :P
Side Note
IMHO, every programmer should know De Morgan's laws so well that they can instinctively detect logical inconsistencies in the code. The inconsistency in this case is between the loop condition and the if statement in the loop body. If we put them side-by-side, we know that they are not equivalent, according to De Morgan's Law:
!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")
operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%")
But they should be equivalent, because the intent are the same: to continue the loop when the user entered a invalid operator and to terminate otherwise.
do {
grade[y] = JOptionPane.showInputDialog(null, "For student #" + inputGrades.students + " enter grade for course #" + classes);
if (!grade[y].equals("A") || !grade[y].equals("B") || !grade[y].equals("C") || !grade[y].equals("D") || !grade[y].equals("F")) {
grade[y] = JOptionPane.showInputDialog(null, "For student #" + inputGrades.students + " enter grade for course #" + classes);
} else {
validgrade = true;
}
} while (!validgrade);
I'm trying to make a sure a sting equals either A, B, C, D, or F. I get stuck in an infinite loop. Why?
This condition is always true:
if (!grade[y].equals("A") || !grade[y].equals("B") || !grade[y].equals("C") || !grade[y].equals("D") || !grade[y].equals("F"))
grade[y] cannot equal A, B, C, D, and F at the same time. At most one !equals(...) will be false. The remaining four would be true, turning the results of OR into true as well.
You need && instead of ||:
if (!grade[y].equals("A") && !grade[y].equals("B") && !grade[y].equals("C") && !grade[y].equals("D") && !grade[y].equals("F"))
In addition, it is not necessary to call JOptionPane.showInputDialog inside the if conditional. All you need to do is letting the loop continue. So the simplified code could look like this:
do {
grade[y] = JOptionPane.showInputDialog(null, "For student #" + inputGrades.students + " enter grade for course #" + classes);
} while (!grade[y].equals("A") && !grade[y].equals("B") && !grade[y].equals("C") && !grade[y].equals("D") && !grade[y].equals("F"));
As far as I have read so far in my textbook for the class, in the modules for my class and in 2+ hours of searching, I cannot figure out why my code is not working.
The do while loop in the main method is working properly but the do while loops in my get methods are not looping. I put in the wrong number, I get the error message and then instead of asking for the number again, it moves on to the next get method.
I hope it is something simple that I have overlooked but I would appreciate any help I could get on this.
Here is the code for my getHome method:
public static int getHome()
{
int homeNum;
String home;
do
{
home = JOptionPane.showInputDialog(null,"Enter 1(apartment), 2(house),"
+ " or 3(dorm).","Dwelling Type", JOptionPane.QUESTION_MESSAGE);
homeNum = Integer.parseInt(home);
if(!(homeNum == 1) && !(homeNum == 2) && !(homeNum == 3))
{
JOptionPane.showMessageDialog(null, "The value for dwelling type "
+ "must be 1(apartment), 2(house), or 3(dorm)", "Dwelling"
+ "Type Error", JOptionPane.ERROR_MESSAGE);
}
return homeNum;
}
while(homeNum < 0 || homeNum > 3);
And the code in the main method that calls this method:
public static void main(String[] args)
{
String response;
do
{
petRec(getHome(), getHours());
response = JOptionPane.showInputDialog(null, "Do you want to continue?" +
"\nEnter Y for yes and anything else for no.", "Continue?", +
JOptionPane.QUESTION_MESSAGE);
}
while(response.equalsIgnoreCase("y"));
}
Just for clarification here is the petRec method:
public static void petRec(int homeType, double hoursAtHome)
{
String pet;
if(homeType == 1 && hoursAtHome >= 10)
pet = "Cat";
else
if(homeType == 1 && hoursAtHome < 10)
pet = "Hamster";
else
if(homeType == 2 && hoursAtHome >= 18)
pet = "Pot-Bellied Pig";
else
if(homeType == 2 && hoursAtHome >= 10 && hoursAtHome <= 17)
pet = "Dog";
else
if(homeType == 2 && hoursAtHome < 10)
pet = "Snake";
else
if(homeType == 3 && hoursAtHome > 6)
pet = "Fish";
else
if(homeType == 3 && hoursAtHome < 6)
pet = "Ant Farm";
else
pet = "Nothing";
JOptionPane.showMessageDialog(null, "You should get a " + pet + "!",
"Recommended Pet", JOptionPane.INFORMATION_MESSAGE);
}
Last year I took intro to Visual Basic and had infinite loops, this year I'm taking Java and can't get the loop to repeat.
The getHours method is structured almost identical to the getHome method just with different variables and wording in the prompt.
The program is supposed to display the error message when a number that is not 1, 2 or 3 is entered and then loop to ask you for the number again. It displays the error message but then goes on to ask for the hours.
Again I very much appreciate any help that can be offered. This assignment isn't due until Saturday but I only have 2 days off to work on this.
Thank you in advance for your help :)
Move the return statement to outside the loop:
public static int getHome()
{
int homeNum;
String home;
do
{
home = JOptionPane.showInputDialog(null,"Enter 1(apartment), 2(house),"
+ " or 3(dorm).","Dwelling Type", JOptionPane.QUESTION_MESSAGE);
homeNum = Integer.parseInt(home);
if(!(homeNum == 1) && !(homeNum == 2) && !(homeNum == 3))
{
JOptionPane.showMessageDialog(null, "The value for dwelling type "
+ "must be 1(apartment), 2(house), or 3(dorm)", "Dwelling"
+ "Type Error", JOptionPane.ERROR_MESSAGE);
}
}
while(homeNum < 0 || homeNum > 3);
return homeNum;
}
As it is, you are returning from the method at the end of the first loop iteration. You might also want to catch the potential NumberFormatException that can be thrown by the parseInt call.
Also, be aware that this will allow 0 to be entered. Perhaps that's by design; perhaps an oversight. I can't tell.
Welcome to Java:
do
{
...
return homeNum;
}
while(homeNum < 0 || homeNum > 3);
In Java, the following instruction all finish the current statement: the code after will never be executed or you'll get an error. You must move the return outside the loop for it to work correctly (or as intended):
do
{
...
}
while(homeNum < 0 || homeNum > 3);
return homeNum;
return : when you return a value, like in return homeNum, you exit the method in which you are.
continue : when you continue, you'll go to next iteration; this only works in a loop.
break : when you break, you'll end the execution of a loop or a switch statement. For instance, if you had put break; instead of return h omeNum; the loop would have ended here.
throw new Exception("Foobar") : when you throw an error, it will exit the current try .. catch block method up one matching the exception kind.
As an example of break, throw and continue:
public static int getHome()
{
int n = -1;
for (;;) { // infinite loop powered !
try {
String home = JOptionPane.showInputDialog(null,"Enter 1(apartment), 2(house),"
+ " or 3(dorm).","Dwelling Type", JOptionPane.QUESTION_MESSAGE);
int homeRun = Integer.parseInt(home);
if(homeNum != 1 && homeNum != 2) && homeNum != 3) {
// note: this is an example. You should NEVER use exception in these case
throw new IllegalArgumentException("Damn!");
}
n = homeRun;
break;
} catch (NumberFormatException|IllegalArgumentException e) {
JOptionPane.showMessageDialog(null, "The value for dwelling type "
+ "must be 1(apartment), 2(house), or 3(dorm)", "Dwelling"
+ "Type Error", JOptionPane.ERROR_MESSAGE);
continue;
}
}
return n;
}
This is an ugly example showing you the four instructions.
Throwing an exception in this case is bad practise. But it'll go to the catch block because it catches the NumberFormatException (from Integer.parseInt) and the thrown IllegalArgumentException.
The break could be replaced by a return homeRun;
The continue is useless in this case because there is nothing left after the try catch block.
Beside, if you are learning Java, you should perhaps read that because I think you are not doing think right. There exists GUI components that does the cumbersome work of handling input conversion for you.
Or even, instead of JOptionPane, you should rely on System.in and Scanner: it is pretty strange to execute a code in a terminal/console, then being asked in a window on some input, to then come back in the terminal/console.