How to use String variables as a condition for looping purpose - java

I was trying to prepare a flow chart of program for my practice where i encounter that following situation is required for me where a user would enter a string value as input either "Yes"or "Y" and "No" or "N" and based on its input the application would either terminate or restart from a certain point till now i have this as an example in my mind
public class ApplicationName {
public static void main(String args[]) {
String restartOperation;
do {
restartOperation = Confirm_Before_Exit();
} while (!restartOperation.equals("No"));
//Rest of code
}
public static void Some_Operation() {
//Executed when called before closing application
}
public static String Confirm_Before_Exit() {
Scanner inputData = new Scanner(System.in);
String answer;
System.out.println("Do you want to perform another operation ?" + " " + "Y" + " " + "N");
answer = inputData.nextLine();
switch (answer) {
case "Y":
case "Yes":
Some_Operation();
break;
default:
System.out.println("Good Bye !");
}
return answer;
}
}
This works till the user has not given input as "No" but obviously it wont work if entered "N" or perhaps small "n" or even "no" but for timing i am only trying for "No" and "N" as input value.

change your do while to the following :
do {
restartOperation = Confirm_Before_Exit();
} while (!restartOperation.equalsIgnoreCase("No") && !restartOperation.equalsIgnoreCase("n"));

I would do something like this. You make your answer lowercase to take into account cases like YEs, NO, etc. You then specify the n and no.The default should be a catch all.
answer = inputData.nextLine().toLowerCase();
switch (answer) {
case "y":
case "yes":
Some_Operation();
break;
case "n":
case "no":
System.out.println("Good Bye !");
break;
default:
System.out.println("Not a valid reponse");
}

You may want to use Regex for text matching (it is contained in the default Java-JDK, not an external library). It is extremely powerful.
You define a needle to search for in Regex-syntax, for example this:
^no?$
It matches text that starts (^) with n and then eventually (?) followed by o (but it does not need to be there), after that the text ends ($). There's also a flag for case insensitive matching /i. You can try Regex at regex101.com. Try this: regex101.com/r/edrehj
Okay, how to use this stuff in Java? Fairly easy:
String input = ...
Pattern pattern = Pattern.compile("^no?$", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
// User want's to cancel
...
} else {
// User want's to continue
...
}
More info at Wikipedia#Regex, Java-API#Pattern and Java-API#Matcher.
You can also put this inside an own method, makes the usage more easy and user friendly to read:
private boolean doesUserWantToCancel(final String textInput) {
Pattern pattern = Pattern.compile("^no?$", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(textInput);
return matcher.find();
}
You then just call the method for your input:
...
} while (!doesUserWantToCancel(restartOperation));
...

If I am understanding your question correctly you want to run Confirm_Before_Exit() when you are restarting an operation?
Here is what I would do. Instead of having string restartOperation you should have boolean restartOperation. This way you either deal with true or false.
In the Confirm_Before_Exit() function I would still add the .toLowerCase() to your inputData to take into account weird cases. I added two booleans answer and inValidAnswer.
You want your answer to be true if you want to perform another operation. If it is false it will exit.
If the user mistypes, inValideAnswer will be set to true and they will get an error saying invalid answer and will get reprompted.
public class ApplicationName {
public static void main(String args[]) {
boolean restartOperation;
do {
restartOperation = Confirm_Before_Exit();
} while (restartOperation);
//Rest of code
}
public static void Some_Operation() {
//Executed when called before closing application
}
public static boolean Confirm_Before_Exit() {
Scanner inputData = new Scanner(System.in);
boolean answer;
boolean validAnswer;
while(inValideAnswer){
System.out.println("Do you want to perform another operation ?" + " " + "Y" + " " + "N");
string userInput = inputData.nextLine().toLowerCase();
switch (userInput) {
case "y":
case "yes":
Some_Operation();
answer = true;
inValideAnswer = false;
break;
case "n":
case "no":
answer = false;
inValideAnswer = false;
System.out.println("Good Bye !");
break;
default:
System.out.println("Not a valid reponse");
inValideAnswer = true;
}
}
return answer;
}
}

Related

Java String replace multiple strings before Boolean.parseBoolean in Scanner?

I am building a java program that tracks bowel function for users. I have a segment of code inside a loop that queries the user via Scanner to answer if they have cramps. I have the following code working:
String cramps = userInput.nextLine();
String replacecramps = cramps.replace("Y","true");
boolean mycramps = Boolean.parseBoolean(replacecramps);
This effectively takes a "Y" answer and replaces it with "true" and then takes the String "true" and changes it to a boolean true (I think - it seems to be working that way, anyway). However, I'd like to change other possible common inputs, such as "y", "yes", "Yes", "yeah", "Yeah", "yep", "Yep", etc as well.
Is there any way to do this? I am very new to Java, so it is proving to be difficult. I have read every single post about it here, and I'm still lost as to how to best go about this.
Here are some code snippets that may be useful:
The branch of the loop this resides in is (I can paste in the full code if necessary, but it is very long):
} else if (myBristol == 7) {
System.out.println("You appear to have severe diarrhea. ");
//Integrate Diarrhea.java class
System.out.println("\nDid you experience cramps or bloating? (Y/N)");
String cramps = userInput.nextLine();
String replacecramps = cramps.replace("Y","true");
boolean mycramps = Boolean.parseBoolean(replacecramps);
System.out.println("Did you experience flatulence? (Y/N)");
String gas = userInput.nextLine();
String replacegas = gas.replace("Y","true");
boolean mygas = Boolean.parseBoolean(replacegas);
Diarrhea b = new Diarrhea(poopColor, poopSize, mycramps, mygas);
//Print data to log file
pw.println(b.toString());
The subclasses it is using:
public class Poop{
protected String color;
protected String size;
public Poop(String poopColor, String poopSize)
{
color=poopColor;
size=poopSize;
}
public void setcolor(String c)
{
color = c;
}
public String getcolor(){
return color;
}
public void setsize(String s)
{
size = s;
}
public String getsize(){
return size;
}
#Override
public String toString() {
String tmp = "This poop's color was: " + this.getcolor() + ". Poop was: " + this.getsize() + ".";
return tmp;
}
}
public class Diarrhea extends Poop{
protected boolean cramps;
protected boolean gas;
public Diarrhea(String poopColor, String poopSize, boolean cramps, boolean gas) {
super(poopColor,poopSize);
this.cramps=cramps;
this.gas=gas;
}
public void setcramps(boolean mycramps) {
cramps=mycramps;
}
public boolean getcramps(){
return cramps;
}
public void setgas(boolean gas) {
gas=this.gas;
}
public boolean getgas(){
return gas;
}
#Override
public String toString() {
String tmp = "This diarrhea's color was: " + this.getcolor() + ". Was this a little or a lot of diarrhea: " + this.getsize() + ". Did you experience cramps or bloating? (true/false) " + this.cramps + ". Did you experience flatulence? (true/false) " + this.gas + ".";
return tmp;
}
}
This is how I have been managing my y/n questions up until this point, which has been working nicely as it only looks for a y or n as the first character, doesn't care what case, and doesn't care about anything else (like typos). It was a little difficult figuring out how to get it to work for a boolean, but I think I'm on the right path - but maybe I'm going about this all wrong.
char answer1 = userInput.next().charAt(0);
answerString = Character.toString(answer1);
userInput.nextLine();
if (answerString.equalsIgnoreCase("Y")) {
//Integrate Poop.java class
System.out.println("Was this a large, medium, small, or average sized bowel movement (describe size): ");
String poopSize = userInput.nextLine();
System.out.println("How would you describe the color of this poop (brown, greenish, light, dark, etc): ");
String poopColor = userInput.nextLine();
Poop a = new Poop(poopColor, poopSize);
//Print data to log file
pw.println(a.toString());
You can use replaceALL with some regex like this :
String input = "you are saying : y yes Yes yeah Yeah yep Yep";
input = input.replaceAll("\\b(?i)y(es|eah|ep)?\\b", "true");
System.out.println(input); //you are saying : true true true true true true true
details about regex :
\b for Word Boundaries
(?i) for case insensitive
y(es|eah|ep)? y followed by one of (es or eah or ep) which are optional ?
Try a case insensitive replace all using the list of positive words you want to target:
String target = "Dogs Yes yes Yeah yeah Yep yep false";
target = target.replaceAll("(?i)\\b(y|yes|yeah|yep)\\b", "true");
System.out.println(target);
Dogs true true true true true true false
Demo

How can I make a java program to understand the user-input "t" as "true" and "f" as "false"(boolean)?

I have to code a program, that's working with boolean operators. The first thing this program should do is to ask the user for an operator by "command:". The user can only enter "&&", "||", "!" and "quit". Quit just shuts down the program. The next thing it does is to ask the user for a boolean variable, but here is my problem: The program works perfectly fine with entering "true" or "false", but the task I've got says, the user can only use "t" for "f" as input. So here is my question: How can I make the program to understand "t" as "true" and "f" as "false"?(by the way if the user enters"!" the program just outputs the negation of the first parameter)
public static void main(String[] args) {
Scanner eingabe = new Scanner(System.in);
System.out.println("Command: ");
String command = eingabe.nextLine();
if(command.equals("quit")) {
System.exit(0);
}
System.out.println("Parameter 1:");
boolean parameter1=eingabe.nextBoolean();
if(command.equals("!")) {
System.out.println(!parameter1);
System.exit(0);
}
System.out.println("Parameter 2:");
boolean parameter2=eingabe.nextBoolean();
if(command.equals("&&")) {
System.out.println(parameter1&&parameter2);
}else if(command.equals("||")) {
System.out.println(parameter1||parameter2);
}
eingabe.close();
}
}
The easiest way would be to write a little method, something like:
boolean customParseBoolean(String input) {
if ("t".equals(input)) {
return true;
} else if ("f".equals(input)) {
return false;
}
// You don't have to throw an exception on invalid input; just an example.
throw new IllegalArgumentException("Invalid input: " + input);
}
and then invoke this something like:
boolean parameter1 = customParseBoolean(eingabe.nextLin());
It doesn't matter which way you do it, but below should work for your example. It just doesn't cover the case when the input is malformed
String parameterString1 = eingabe.next();
boolean parameter1 = !command.equals("f");
String parameterString2 = eingabe.next();
boolean parameter2 = command.equals("t");
you can always cross verify the user input in if() condition. create a boolean value with false by default, if the user types t make that boolean as true and vice versa.
or else u can use switch statements

Input ignores IF statement if default in switch

I am doing a project (based on a tutorial). I have a switch statement and for each case, there's a default in case the user input is invalid, and I write on the console "Sorry, I do not understand your request". However, if the user instead of writing whatever, writes "exit", the program should end without that "I don't understand request" sentence showing up.
This is stated in my IF statement in the beginning. What my current project does at the moment when I type "exit" is showing that line and then stopping. I don't understand how the program completely ignores that IF statement in the beginning.
public class MainGame {
public static GameSave gameSave = new GameSave();
public static String user = "";
public static Scanner scanner = new Scanner(System.in);
public static String question;
public static int relationshipPoints;
public static void main(String[] args) {
Random random = new Random();
question = gameSave.loadGame();
// relationshipPoints = gameSave.loadPoints();
RelationshipPoints points = new RelationshipPoints();
System.out.println("\n\t*** TEXT_GAME: FIRSTDATE ***\n");
System.out.println("-You can exit the game at any time by typing 'exit'.-\n\n");
while (true) {
if (user.equalsIgnoreCase("exit")) {
System.exit(1);
break;
} else {
switch (question) {
[...]
case "2":
switch (user = scanner.next()) {
case "1":
System.out.println("\n\nThe guy you met last night was nice. You want to "
+ "get back into contact with him. Why don't you check your phone for a number?");
question = "2A";
gameSave.saveGame("2A");
break;
case "2":
System.out.println("\n\n");
question = "0";
break;
default:
System.out.println("\nI do not understand your request.\n");
question = "2";
break;
}
break;
case "2A": [...]
Try replacing your while(true) {...} with while ((user = scanner.next() != null) { ... }
It looks like you are trying to access the "user" data without first setting it.
user = scanner.nextLine(); insert this line just after entering in while loop. your problem occurs as you are checking user equal to exit but user has nothing so control goes to else portion.

Java: Labeled Break

I am working on a practice exercise in my online pursuit to learn Java and am stumped!
The gist of my program is I have the user select an option via the input of a single char, then the program proceeds to cases based off of the value. If the default case executes, that means the input was invalid and I want to then return to the user input prompt.
I initial thought was to use a 'goto', however from what I understand, I would probably be stoned to death by anyone besides me reading the code. And then there's the fact that goto doesn't exist in Java... So while Googling, I found 'labeled breaks'. It looked just like what I needed. However, the spot which I have inserted the label is unrecognized, even though it's in the same class as the cases. How should I go about doing this?
String newLine = System.getProperty("line.separator");
restart:
System.out.println("Please select the type of shape you wish to calcuate information for: "
+ newLine + "A: Square" + newLine + "B: Rectangle" + newLine + "C: Circle");
char typeShape = input.next().charAt(0);
String shape = Character.toString(typeShape);
switch (shape.toLowerCase()) {
case "a":
//do something
break;
case "b":
//do something
break;
case "c":
//do something
break;
default:
System.out.println("Invalid selection. Please re-enter shape.");
break restart;
}
I believe you want to label a block. Something like
restart: {
System.out.println("Please select the type of shape you wish to calculate "
+ "information for: " + newLine + "A: Square" + newLine + "B: Rectangle"
+ newLine + "C: Circle");
char typeShape = input.next().charAt(0);
String shape = Character.toString(typeShape);
switch (shape.toLowerCase()) {
case "a":
//do something
break;
case "b":
//do something
break;
case "c":
//do something
break;
default:
System.out.println("Invalid selection. Please re-enter shape.");
break restart;
}
}
I guess a simple approach will be to use the do-while loop. If the condition is not satisfied (invalid input/character), continue the loop, otherwise set the flag to false and come out.
boolean inputFlag;
do {
System.out.println("Please select the type of shape you wish to calcuate information for: "
+ newLine + "A: Square" + newLine + "B: Rectangle" + newLine + "C: Circle");
char typeShape = input.next().charAt(0);
String shape = Character.toString(typeShape);
switch (shape.toLowerCase()) {
case "a":
inputFlag = false;
//do something
break;
case "b":
inputFlag = false;
//do something
break;
case "c":
inputFlag = false;
//do something
break;
default:
System.out.println("Invalid selection. Please re-enter shape.");
inputFlag = true;
}
} while (inputFlag);
Java allows you to label a loop construct (e.g. for, while) and then jump out of the inside one of the loops to an outer level.
The language does not allow you to label arbitrary lines and "goto" them.
UPDATE: Apparently I was wrong. Java supports labeling arbitrary blocks (but not individual statements). See https://stackoverflow.com/a/1940322/14731
Labeled blocks are frowned upon for similar reasons goto is frowned upon: it's not a natural flow.
With that said, you might be wondering how you would manage the behavior you want, which is pretty simple: use a loop
//pseudo-code
while(something) {
repeatCode
}
In your case, you would do something like:
boolean choosing = true;
while(choosing) {
switch(...) {
case "a":
choosing = false;
break;
case "b":
choosing = false;
break;
}
}
You may find this a bit verbose. Instead, you could set choosing to false as soon as you enter the loop, then set it back to true if the user didn't enter a correct name.
Or better yet, use a do-while loop:
boolean choosing = false;
do {
switch(...) {
case "a":
break;
default:
choosing = true;
break;
}
} while(choosing);

How can I check if my string is other than int's, to clarify i need to check it is not a number

... if instead of a number I get a letter, or a symbol, or 2 decimals.
I am making a change maker program in java.
Everything works good, the only thing i am confused about is checking the string to see if is invalid for my use,
I did this for when is left empty;
if (s1.isEmpty()) {
JOptionPane.showMessageDialog(null, "Invalid input! ");
System.exit(0);
}
That works perfect, now how can I do the else to check for letters or dots or symbols, anything that is not a number?
You could use regular expressions.
Here's some sample code to check for digits only (\\d) in your input string.
The code that actually checks is pattern.matcher(in).matches() and it tries to match the regular expression defined by regex
Let me know if you need more explanations
public class HelloWorld{
public static void main(String[] args) {
String regex = "\\d+";
String inputNumber = "2";
String inputDecimal = "2.0";
String inputString = "two";
String[] inputs = {inputDecimal, inputNumber, inputString };
Pattern pattern = Pattern.compile(regex);
for(String in: inputs){
System.out.print( in + " ");
System.out.print( pattern.matcher(in).matches()? "":"does not");
System.out.print( " contain integer numbers" );
System.out.println("---");
}
}
}
If you need to perform all the processing only when the String is integer why not check for integer value in the if clause and let the else clause be common for all the letter, dots, symbols and also empty.
if(s1.isNum){
//all processing here
}
else{
JOptionPane.showMessageDialog(null,"Invalid Input");
System.out.exit(0);
}
Otherwise you could also use try and catch block.
try{
int num= Integer.parseInt(s1);
//rest of the processing
}
catch(Exception e){
JOptionPane.showMessageDialog(null,"Invalid Input");
System.out.exit(0);
}
Use either according to your requirement
You could use a regular expression1 and String.matches(String) which Tells whether or not this string matches the given regular expression. \\d+ should match one or more digits. Something like
System.out.println("12".matches("\\d+"));
Prints
true
1Some people, when confronted with a problem, think
“I know, I'll use regular expressions.” Now they have two problems. --jwz
To test whether it is an integer, parse it to an int like this:
Integer.parseInt(s1)
You might also want to make use of the value returned but I don't show it here. Now you can apply try catch blocks around the method call and catch NumberFormatException like this:
try {
Integer.parseInt(s1);
//The code here will run if s1 is an integer.
} catch (NumberFormatException e) {
//this will be executed when s1 is not an integer
}
You can also extract a method from the above code. A method that returns true when the exception is not thrown. However, a disadvantage of try catch is that throwing an exception needs time and thus, it slows down your program.
To test whether the string is a letter, you loop through all the chars in the string and use one of the methods of the Character class.
boolean isLetter = true;
for (int i = 0 ; i < s1.length() ; i++) {
if (!Character.isLetter(s1.charAt(i))) {
isLetter = false;
break;
}
}
If isLetter is true, it is a letter. Again, you can also extract this as a method.
To check whether it is a symbol, use one of the methods of the Character class (again).
boolean isSymb = true;
for (int i = 0 ; i < s1.length() ; i++) {
if (!Character.isJavaIdentifierStart(s1.charAt(i))) {
isSymb = false;
break;
}
}
To check for dots in a string, just use
s1.contains(".")
Isn't that simple?
Ok, I solved the problem the following way... I took a little bit of every idea lol...
if (s1 == null) {
JOptionPane.showMessageDialog(null, "You must enter a valid integer");
System.exit(0);
}
if (s1.isEmpty()) {
JOptionPane.showMessageDialog(null, "You must enter a valid integer");
System.exit(0);
}
for (int i = 0; i < s1.length(); i = i + 1) {
if (!Character.isDigit(s1.charAt(i))) {
JOptionPane.showMessageDialog(null, "You must enter an integer value");
System.exit(0);
}
}

Categories