User input and do while loop with negation - java

I was trying to make an user input in an do while loop. The loop should continue if the user input is not yes OR not.
When I write:
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String userInput = "";
String yes = "yes";
String no = "no";
do {
System.out.print("Type yes or no: ");
userInput = input.readLine();
} while (userInput.equals(yes) || userInput.equals(no));
If the user type "yes" OR "no" the loop will continue, all other inputs will result the end of the loop.
When I write:
while (!userInput.equals(yes) || !userInput.equals(no));
The loop continues everytime, no matter what the user enters.
Only when I use the AND operator it works.
while (!userInput.equals(yes) && !userInput.equals(no));
Why is that so?
Should it not be the OR operator because I want to say, if the user enters yes OR no stop the loop.

!userInput.equals(yes) || !userInput.equals(no)
Let's say the user enters "hello". You ths have
!false || !false
which is
true || true
which is
true
Let's say the user enters "yes".
You thus have
!true || !false
which is
false || true
which is
true
Let's say the user enters "no".
You thus have
!false || !true
which is
true || false
which is
true
So you see that, whetever the user enters, the condition is always true, and thus the loop continues forever.

Think about the Boolean expressions you are writing. When the users enters 'yes', it evaluates as !true || !false which is equivalent to false||true which is true. Since the condition is satisfied, the loop continues.

Because this is how boolean expressions work. The opposite of A || B is not !A || !B but !(A || B) which is the same as !A && !B.

if( A || B) means either A true or B true. If say A is true then it won't check B it will directly go inside the block. So when you say if(!yes || !no) and if you enter yes then second condition becomes true and when you enter no the first condition becomes true and it continues to execute. And if you enter abdc its again true.

Related

why does it not break out of the loop whatever is the input

whatever the input is, it never breaks the loop i tried.
i tried with the switch same result; i tried with only one condition (!answer.equalsIgnoreCase("y")) without the OR and it worked but nott with two conditions.
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
//checking if the dog is barking
System.out.println("is the dog is barking ?");
String answer;
do {
System.out.println("write 'n' for no and 'y' for yes");
answer = scn.next();
} while( !answer.equalsIgnoreCase("y") || !answer.equalsIgnoreCase("n"));
boolean dogBark=answer.equalsIgnoreCase("y");
i expect it to finish the while loos as soon as i enter 'y' or 'n' but its asks me for input over and over.
While answer is not yes or answer is not no?
If it's yes, then it isn't no. If it's no, then it isn't yes. So the condition is always true and it loops.
You probably want to use the ! operators.
while( !answer.equalsIgnoreCase("y") || !answer.equalsIgnoreCase("n"));
The issue is occurring because the do-while loop is checking both conditions with the OR statement.
Think about it like this, if Answer equals "Y" that condition is met to break the loop but the OR condition "N" is still active therefore the loop will continue.
The do while is only checking to ensure one of the conditions above is false before continuing the loop.
To fix this replace the || with && and the loop will break if either Y or N is entered as the loop will only continue if both conditions are false.

How to make do-loop conditions "when string does not equal"

I want to make my do loop run while the input the user made is not equal to the required letters (a-i) For some reason,even when i input the proper letters, it loops forever.
I've tried using switch cases as well as != inside the comparison.
Here is my code:
do {
System.out.println("Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
lL1=in.nextLine();
if (!lL1.equals("a")||!lL1.equals("b")||!lL1.equals("c")||!lL1.equals("d")||!lL1.equals("e")||!lL1.equals("f")||!lL1.equals("g")||!lL1.equals("h")||!lL1.equals("i")){
System.out.println("Invalid Input. Try again.");
}//End if statement
}while(!lL1.equals("a") || !lL1.equals("b") || !lL1.equals("c") || !lL1.equals("d") || !lL1.equals("e") || !lL1.equals("f") || !lL1.equals("g") || !lL1.equals("h") || !lL1.equals("i"));
My skills in Java are limited but this should work, unless i'm missing something obvious. Any help would be amazing!
Instead of using an operator for each case of the input, you might want to create a list of the accepted answers and then your condition will look like:
while answer is not in accepted answers, ask another input
An example would be:
Scanner scanner = new Scanner(System.in);
List<String> acceptedAnswers = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i");
String input;
do {
System.out.println(
"Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
input = scanner.nextLine();
} while (!acceptedAnswers.contains(input));
scanner.close();
System.out.println("Got correct input: " + input);
If you have a negation you need AND to join the conditions not OR.
That's because if you or some not-ed values, they form an and.
Let me explain better.
If you input a, then the first is false (because you not it), and the others are true, so the or condition make the result be true.
You should instead group all the ors and then not it.
e.g.
!(lL1.equals("a") || lL1.equals("b") || lL1.equals("c") || lL1.equals("d") || lL1.equals("e") || lL1.equals("f") || lL1.equals("g") || lL1.equals("h") || lL1.equals("i"))
Please try this:
char lL1;
Scanner scanner = new Scanner(System.in);
do {
System.out.println("Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
lL1=scanner.next().charAt(0);
}while(lL1!='a' && lL1!='b' && lL1!='c' && lL1!='d' && lL1!='e' && lL1!='f' && lL1!='g' && lL1!='h' && lL1!='i');
Since you are only getting a single character, you can check that it does not match either [a to i] characters as shown above. This is the shortest way to do so by making the check as the condition of the loop. If it fails then the loop will be called.

Do while string validation (with multiple strings)

For some reason, when I have multiple correct strings, the statement keeps repeating
do {
System.out.println("Enter Service Code");
Scanner a = new Scanner(System.in);
serviceCode = a.nextLine();
} while (!serviceCode.equals("ORB1") || !serviceCode.equals("ORBH") ||
!serviceCode.equals("ISS5") || !serviceCode.equals("ILLOYDS") ||
!serviceCode.equals("DLAB") || !serviceCode.equals("LEOM7") ||
!serviceCode.equals("MOON2"));
However, when there's just one string that the code checks against. The do while statement works fine and will stop looping when the correct input is entered
do {
System.out.println("Enter Service Code");
Scanner a = new Scanner(System.in);
serviceCode = a.nextLine();
} while (!serviceCode.equals("ORB1"));
If you enter "ORB1", "!serviceCode.equals("ORB1")" will return false but the others will return true; and you are using the "OR" operator. So, this sentence :
!serviceCode.equals("ORB1") || !serviceCode.equals("ORBH") ||
!serviceCode.equals("ISS5") || !serviceCode.equals("ILLOYDS") ||
!serviceCode.equals("DLAB") || !serviceCode.equals("LEOM7") ||
!serviceCode.equals("MOON2")
will always be true. You need to use the "AND" operator
!serviceCode.equals("ORB1") && !serviceCode.equals("ORBH") &&
!serviceCode.equals("ISS5") && !serviceCode.equals("ILLOYDS") &&
!serviceCode.equals("DLAB") && !serviceCode.equals("LEOM7") &&
!serviceCode.equals("MOON2")
Your comparison can never return false. it's either A or B.
so, if you were to say:
if ( !A OR !B ){
--> Input = A => true (because !B returns true)
--> Input = B => true (because !A returns true)
--> Input = C => true (because !A returns true)
Change your OR (||) by AND (&&)
Also: declare and instantiate your Scanner before your loop.
A better approach would be create a Listof string which includes the valid codes and check if that list contains the provided user input.
List<String> validServiceCodes = Arrays.asList("ORB1", "ORBH", "ISS5", "ILLOYDS", "DLAB", "LEOM7", "MOON2" );
do {
System.out.println("Enter Service Code");
Scanner a = new Scanner(System.in);
serviceCode = a.nextLine();
} while (!validCodes.contains(validServiceCodes));

Making a Y/N Condition work

I need help with a SIMPLE Y/N Condition for my program. I don't really get it to work as I want to.
Unfortunately all the other topics I find is very confusing. I'm a very novice student in programming.
I want a Y/N Condition that wont crash and is not CASE SENSITIVE. so if Y or y it goes back to another menu, if n and N is just stop the program and if anything else is typed in it will loop until the Y or N conditions are met.
This is what i wrote:
String input = ScanString.nextLine();
while (!"Y".equals(input) || !"y".equals(input) || !"N".equals(input) || !"n".equals(input)) {
System.out.println("Please enter Y/N (Not case sensitive): ");
input = ScanString.nextLine();
}
if ("Y".equals(input) || "y".equals(input)) {
meny1();
} else if ("N".equals(input) || "n".equals(input)) {
}
When it runs, whatever I put in, it won't break the while loop.
while (!"Y".equals(input) || !"y".equals(input) ||... means "keep looping while the input isn't 'Y' or the input isn't 'y' or...". By definition, one of those conditions will always be true.
The simplest way to do what you're looking for would be a case insensitive comparison, and an and (&&) rather than or operator:
while (!input.equalsIgnoreCase("Y") && !input.equalsIgnoreCase("N")) {
That means "keep looping while the input isn't 'Y' or 'y' and the input isn't 'N' or 'n'.
Or the same in Yoda-speak, since you were using Yoda-speak:
while (!"Y".equalsIgnoreCase(input) && !"N".equalsIgnoreCase(input)) {
Try this
while (!("Y".equalsIgnoreCase(input)) && !("N".equalsIgnoreCase(input))) {
}
Or
String[] validInputs = { "Y", "N" };
while(!Arrays.asList(validInputs).contains(input.toUpperCase())) {
}

confusion between && and || in java

import javax.swing.JOptionPane;
public class Insurance {
final static String INPUT_GENDER = "Please enter your gender: (Male or Female)";
final static String MALE = "male";
final static String FEMALE = "female";
static String gender;
public static void main(String args[])
{
do
{
gender = JOptionPane.showInputDialog(INPUT_GENDER).toLowerCase();
System.out.println(gender);
}
while(!gender.equals(MALE) && !gender.equals(FEMALE));
}
}
The above piece of code is the beginning to a revision assignment, but I came across something I don't understand. The user is asked to enter their gender, as "Male" or "Female", and the program should only continue if the input satisfies one of these inputs. This is done by comparing the input to the final strings for MALE and FEMALE.
What I don't understand is why it only works using && in the while statement. I expected it to need ||, because we want it to continue if the input matches either of the two gender strings. I understood that && should only allow the code to continue if both arguments are true.
TL;DR
while(!gender.equals(MALE) && !gender.equals(FEMALE)); //This works
while(!gender.equals(MALE) || !gender.equals(FEMALE)); //This does not work
while(gender.equals(MALE) || gender.equals(FEMALE)); //This does not work
&& is a logical and operator
|| is the logical or operator
Using De Morgan, the following:
while(!gender.equals(MALE) && !gender.equals(FEMALE))
Can be translated to:
while(!(gender.equals(MALE) || gender.equals(FEMALE)))
(note the additional parenthesis and the placement of the ! before them).
Both the above mean that the gender is neither MALE or FEMALE.
Your other code:
while(!gender.equals(MALE) || !gender.equals(FEMALE))
The above means - gender is not MALE or gender is not FEMALE.
while(gender.equals(MALE) || gender.equals(FEMALE));
Similarly, the above means - gender is MALE or gender is FEMALE.
In English: "when not FEMALE or MALE, do again"
then in Java do{...}while(!(FEMALE || MALE));
and !(A||B) is equal to !A && !B
In your do-while loop you want prompt the user to re-enter his/her gender if the gender entered is neither MALE nor FEMALE.
So the while condition would be that if both gender.equals(MALE) and gender.equals(FEMALE) return false then you would re-prompt the user i.e. the loop will iterate.
That means if not of gender.equals(MALE) and not of gender.equals(FEMALE) both are true then your loop should iterate.
Hence,
while(!(gender.equals(MALE)) && !(gender.equals(FEMALE)))
&& is Java's logical AND operator
|| is Java's logical OR operator
for example:
boolean a = true;
boolean b = false;
boolean c = a && b; // c is false
boolean d = a || c; // d is true
Additionally, ! is Java's logical NOT operator. It is used for negating boolean expressions:
boolean p = true;
boolean q = !p; // q is false
It is also worth noting that x && y will result in the same logical value as !(!x || !y).
Similarly, x || y can be rewritten as !(!x && !y)

Categories