I am trying to make a test of whether an inputted word is a palindrome or not (the same spelled forward and backward). From what I can see it should work but Eclipse says "The value of the local variable isPalindrome is not used" , but it is used. The problem is that even if the word is not a palindrome it says it is.
import java.util.Scanner;
public class Palindrome {
public static void main(String[] args) {
String phrase;
char[] phraseLetters;
int endChar;
boolean isPalindrome;
Scanner input = new Scanner(System.in);
System.out.println("Enter a word or phrase.");
phrase = input.nextLine();
input.close();
phrase = phrase.toLowerCase();
phrase = phrase.replaceAll(" ","");
phraseLetters = phrase.toCharArray();
endChar = phraseLetters.length - 1;
for (int i = 0; i < phraseLetters.length; i++) {
if (phraseLetters[i] != phraseLetters[endChar]) {
isPalindrome = false;
} else {
isPalindrome = true;
endChar -= 1;
}
}
if (isPalindrome = true) {
System.out.println("This word or phrase entered is a palindrome.");
} else {
System.out.println("This word or phrase is not a palindrome.");
}
}
}
EDIT: I have tried the if statement being
if (isPalindrome == true)
and
if (isPalindrome)
In both cases Eclipse says "The local variable isPalindrome may not have been initialized," in this if condition.
FINAL EDIT:
I have since moved on, and rewritten this code, however I just went back and fixed my original code if anyone still looks at this.
I initialized isPalindrome at the beginning of the code:
Boolean isPalinddrome = True;
I changed the for-loop condition to:
for (int i = 0; (i < phraseLetters.length) && (isPalindrome); i++)
Finally I changed if (isPalindrome = true) to if (isPalindrome)
if (isPalindrome = true) should be if (isPalindrome == true) (or if (isPalindrome) better! Actually this error is another good reason why not asking if someBoolean == true which is a bad style)
By typing if (isPalindrome = true) you're assigning, again, the value true to the variable isPalindrome. And since you're only assigning value to it, the compiler warns you about unused variable.
It's also good to know this:
At run time, the result of the assignment expression is the value of
the variable after the assignment has occurred. The result of an
assignment expression is not itself a variable.
So, when you do if (isPalindrome = true) then the if condition is always satisfied.
You should assing some boolean value to isPalindrome in the main scope.
For example:
boolean isPalindrome = true
You have a typo.
if (isPalindrome = true)
{
System.out.println("This word or phrase entered is a palindrome.");
}
else
{
System.out.println("This word or phrase is not a palindrome.");
}
Look at the if condition. You used = instead of ==. So, you are setting isPalindrome to true, only the true block is executed, and the compiler sees that isPalindrome never matters.
Now, your class has some logic flaws and some programming traps.
If the first and last characters are not equal, isPalindrome is set to false, and then the program continues. Break out of the loop; don't let isPalindrome be set to true later. Incidentally, your version actually cares only about the first and last characters.
Don't write if (x == true). Just write if (x).
Don't name your boolean isAnything. After all, you may do this in a JavaBean class, and then you'll end up with a method named isIsAnything or getIsAnything. This will annoy your readers.
In the future, don't write all your code in the main(String[]) method. Have the main method use the arguments to construct an instance of the class, and use that instance. This way, you can write unit tests for the class; you can't for main. You can break the code into a few methods. One checks for being a palindrome, while another provides the human-readable output.
It's actually a bad idea to use the no-argument forms of String.toLowerCase() and String.toUpperCase() One day, you might need to write an internationalized application, and you will have to deal with the Turkish locale. You might end up mumbling to yourself, “What the heck is a dotless i?”
Don't use i and j as variable names here. Use names that show the variable's purpose. Something like:
for (int start = 0, end = phraseLetters.length - 1; start < end; start++, end--) {
...
}
After all, when start passes end, you're just repeating yourself.
There are an error and bad practice here.
The bad practice is not to initialize the variabale:
boolean isPalindrome = true;
alththough all primitives in java have a default value (for boolean it's false) it's still always better to intialize the varibale explicitly in order enhance code redability.
The error is in the if clause:
if (isPalindrome = true) {
in this line you assign the value and not checking the variabale , all assigment return the value of the assignment meaning that this expression will always return true. Because of this your code always retrun true.
Related
The question is, if I need to chose only from two options in boolean method (Yes or No) how do I put it in IFs?
I try to do like this (see below), it underlines very last brace. If I use default return outside while (but I don't want to), it underlines first return (after first if).
static boolean isAnotherGamer() {
System.out.println("Play another game? Type in Y or N");
Scanner scanner = new Scanner(System.in);
String answer = scanner.nextLine();
while (true) {
if (answer.equalsIgnoreCase("Y")) {
break;
return true;
} else if (answer.equalsIgnoreCase("N")) {
break;
return false;
}
System.out.println("Input mismatch");
} //IDE underline this brace
}
Here is how I would do it. This allows any part of yes or no to be entered. I think it best to pass a Scanner instance rather than creating one each time. Using a regular expression allows for some latitude in the answer.
^$ - beginning and end of string.
(?i) - ignore case
ye?s? - says must have y but e and s are optional.
static boolean isAnotherGamer(Scanner scanner) {
System.out.println("Play another game? Type in Y(es) or N(o)");
while (true) {
String input = scanner.nextLine();
if (input.matches("(?i)^ye?s?$")) {
return true;
}
if (input.matches("(?i)^no?$")) {
return false;
}
System.out.println("Incorrect response, please enter Y(es) or N(o)");
}
}
Why can you not validate the input first, and then after the input is either a yes or no, decide on what to do. If it is not either, you can make the repetition statement continue to run until after you get what you need. The location of your return statement is the problem because if either if or else if statements are not true, the method will not return a boolean as your method signature suggests, and your method will just be an infinite loop.
Your method is declared to return a boolean. There is no return statement in the flow.
Assume you go into the endless loop. At this moment we evaluate what the user entered (why do we do that inside the endless loop? The answer does not change inbetween, does it?)
If it is 'y', we break the loop.
If it is 'n', we break the loop.
In any other case we print something and remain in the loop.
But as soon as the loop was broken -> where is the return statement?
So from my POV, the function should look like this:
static boolean isAnotherGamer() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Play another game? Type in Y or N");
String answer = scanner.nextLine();
if (answer.equalsIgnoreCase("Y")) {
return true;
} else if (answer.equalsIgnoreCase("N")) {
return false;
}
System.out.println("Input mismatch");
}
}
Because you've not set a default return value, if the user doesn't choose either "Y" or "N" then nothing is going to be returned so that's why you're getting an error.
Additionally, you shouldn't be putting any code after your break statements as those lines will be completely ignored (again, nothing returned as your return statements are after your breaks.)
You can just completely remove those break statements if you're just wanting to quit that method once you've got your boolean value or you can update a boolean variable for future use if you're wanting to keep running code inside your method. (I've provided an example of this)
System.out.println("Play another game? Type in Y or N");
Scanner scanner = new Scanner(System.in);
String answer = scanner.nextLine();
//To store the state of the user's answer
boolean providedAnswer = false;
//if the answer was yes, set the boolean's val to true
if(answer.equalsIgnoreCase("Yes")){
providedAnswer = true;
}
//output the boolean's value
System.out.println("User wanted to play again? " + providedAnswer);
//return the boolean value
return providedAnswer;
}```
My code is supposed to keep looping until a valid input is given, ie: if a letter is given it will loop, but if a valid number is given, the code should store it into cSec. Is there anyway to do this?
byte cSec;
boolean contCSec = true;
while(contCSec == true) {
System.out.println("Enter course section: ");
cSec = sc.nextByte();
if(cSec>0)
contCCode = false;
}
cSec can't be used outside the loop.
A rather less verbose form of what you wrote might be:
byte cSec;
do {
System.out.println("Enter course section: ");
cSec = sc.nextByte();
} while (cSec <= 0);
where 'cSec <= 0' denotes an invalid value, per your original, though I imagine there's more to validation than that.
This does not match your title (initialize within loop) since to me that's exactly what you don't want to do.
I think this is clearer than your original since it involved no flag values, and the do...while loop shows up the 'ask then decide to loop' nature a little better.
Adding more validation:
byte cSec;
do {
System.out.println("Enter course section: ");
try {
cSec = sc.nextByte();
}
catch (InputMismatchException ex) {
System.out.println("A number is required");
cSec = -1;
}
} while (cSec <= 0);
In addition to another-dave's wonderful answer, you can suppress the compiler warning by initializing cSec outside of the loop.
byte cSec = 0;
boolean contCSec = true;
while(contCSec == true) {
System.out.println("Enter course section: ");
cSec = sc.nextByte();
if(cSec>0)
contCSec = false;
}
The reason that you get the warning without the first declaration is because, as strange as it sounds, the compiler does not analyze the contents of your boolean in while(contCSec == true). It sees that there is a while loop, and it sees that there will be a boolean resulting from (contCSec == true), but as far as the compiler is concerned, any boolean going into your while condition could be true, or could be false. This means that you could enter the while loop, or you could... not.
As far as the compiler is concerned, anything inside the while loop could happen, or could not happen, and there is no way to know without actually running the code. (If you want to know why this is actually a strict limitation for computers, check out the halting problem.) That means that the compiler has no idea whether cSec = sc.nextByte(); will ever happen or not. Hence, the warning.
I am attempting to validate user input. I have tried some if statements and attempted Boolean. I cant get anything to give the output or rather the validation I am wanting
Users are asked to choose between "red" or "blue" I want them to be required to type either "red" or "blue". I know this could be solved easier through buttons but I am trying to use string input. the code below give an example of where i am.
custColorMsg = "Which color do you want your shirt to be red or blue?";
customerColor = getstringInput(custColorMsg);
String color = null
if( customerColor.equalsIgnoreCase("yes")) {
color = true}
if( customerColor.equalsIgnoreCase("no")) {
color = true}
else if(!customerColor.equalsIgnoreCase("yes" || "no") {
color = false}
I know this last portion is wrong I am just unsure how to go about fixing it. Customers will have three chances to input a valid response then the program will terminate, this portion i can handle. If i can just figure out how to accept "yes" or "no" and refuse anything else.
In terms of the design of this program, I would recommend adding a for loop, that goes from 0 to 2 (this will iterate 3 times). Within the loop, the program can determine what the user's input is. I would also recommend looking at my syntax for the for loop below, I use ifs, else ifs and elses to evaluate the data set more efficiently.
The implementation of the program could be:
for(int i = 0; i < 3; i++)
{
customerColor = getstringInput(custColorMsg);
String color = null
if( customerColor.equalsIgnoreCase("yes")) {
color = true;
break;
}
else if( customerColor.equalsIgnoreCase("no")) {
color = true;
break;
}
else{
color = false;
}
custColorMsg = "Invalid Input, Please Input Again";
}
This will give the user 3 times to input the data, and if they input it correctly, it will stop asking, however, if they do not, it will ask again until they run out of attempts.
There's a few things wrong with your approach.
The semantics of your variable names are a bit off. Which makes the code difficult to read. For example, the variable color which you have defined here as a String, but consistently use as a Boolean is a bit confusing. I'm guessing you mean to define it as a Boolean type and intend to use it as the breaking condition from your loop - it would be more meaningful to name the it as isValidColor or something along those lines.
The following line doesn't do what you think it does:
customerColor.equalsIgnoreCase("yes" || "no")
The method equalsIgnoreCase() takes in a String and not a Boolean like this line of your code will have for an argument. Since the || will resolve to a Boolean value of true or false. Furthermore, those are bad operand types for that operator and the code won't compile.
For your control structure you can use a while loop which will exit when you have reached the max amount of tries or entered a valid response.
Here's a working Console version of what you are trying to accomplish:
String custColorMsg = "Which color do you want your shirt to be red or blue?";
String customerColor;
Boolean validInput = false;
Scanner in = new Scanner(System.in);
int tries = 0;
while (tries < 3 && !validInput)
{
System.out.println(custColorMsg);
customerColor = in.nextLine();
if( customerColor.equalsIgnoreCase("red")) {
validInput = true;
}
else if( customerColor.equalsIgnoreCase("blue")) {
validInput = true;
}
tries++;
}
What the program does: Reads two values from input, asks user whether to add, subtract, or find the product. If user enters one of the three options, it calculates, otherwise the program will loop back to the beginning. The program should STOP after calculation if the user enters one of the three options.
I'm not sure why it keeps on looping. How do I make the script loop only when the user types in a string other than "sum", "difference", or "product"? Also, how can I make the code simpler? Is there any way to loop the program without using do ... while?
import java.util.Scanner;
import java.util.Random;
public class simp_calculator
{
public static void main (String[] args)
{
Scanner scan = new Scanner (System.in);
double a, b;
String response;
boolean noresponse;
do
{
System.out.println ("Please enter first number.");
a = scan.nextDouble();
System.out.println ("Please enter second number.");
b = scan.nextDouble();
System.out.println ("Would you like to find the sum, difference, product?");
response = scan.next();
if (response.equalsIgnoreCase ("sum"))
{
System.out.println (a + b);
}
if (response.equalsIgnoreCase ("difference"))
{
System.out.println (a - b);
}
if (response.equalsIgnoreCase ("product"))
{
System.out.println (a * b);
}
else
{
noresponse = true;
System.out.println ("Starting again...");
}
}
while (noresponse = true);
}
}
You are using the assignment operator, =, so noresponse will always be true. The result of the assignment expression is thus true.
You want to check if it is true, so use the comparison operator ==:
while (noresponse == true);
or, because it's already a boolean:
while (noresponse);
Also, you may be getting a compiler error that noresponse may not have been initialized. You will need to make sure that it's initialized in all cases, and that something sets it to false so the loop will eventually end.
change while (noresponse = true); to while (noresponse == true);.
= is an assignment operation - where as == comparison.
Two errors:
The else applies only to the last if; so for any value, other that "product", noresponse becomes true and the loop goes on. Replace all your ifs from the second on with else ifs.
noresponse should be given the value false at the beginning of the loop.
There are 2 issues:
Currently you are looping while noreponse equals true. So to exit that loop, you need to setnoresponse to false when a particular condition is met :) I could give you the answer, but you should be able to figure it out with the info I've given you. (hint: at some point you need to set noresonse to false).
Also, you are setting noresponse to equal, rather than comparing it. You need to use == to compare.
So make while (noresponse = true); into while (noresponse == true);.
just change while (reponse = true) to while(reponse) and name the variable ..
I am writing a method to search through a dicitionary to find multiple words of the same length that contain the same letter at a set point. I.e. All words of length 5 that have b as their second letter.
I'm writing this method by TDD is eclipse and so far my method is as follows:
private OpenQueue openQueue = new OpenQueue();
private boolean value;
private int lengthOfWord, numberFound;
private File inFile = new File("src/src/WordList"); //This is a text file
public Search(int length) {
this.lengthOfWord = length;
}
public boolean examine2(int crossingPoint, char letter) {
try {
Scanner input = new Scanner(inFile);
while (input.hasNextLine()) { //while there are words left to be read
String word = input.nextLine();
if(word.length() == lengthOfWord) { //if the word is of the right length
while(word.charAt(crossingPoint-1) == letter){
numberFound = numberFound + 1; //number of solutions is increased by one
openQueue.add(word);//word is added to the open queue
value = true; //value is true when at least one solution has been found
}
}
}
} catch (FileNotFoundException e) {
System.out.println("They File was not Found");
e.printStackTrace();
}
System.out.println(numberFound); //returns number of words found
return value; //should return true if there is at least one word
}
For my test I trying to find all five letter words that have a second letter b and there are several words that fit this as I've checked manually. However when I run JUnit it says that it expected true but it was false.
The code runs up to but not past the while(word.charAt(crossingPoint-1) == letter) loop, as previously I added in System.out.println("Here") before this loop to check were the code runs until.
I'm not sure how to fix this in order for the code to run without the test failing. Thanks for your help.
It's hard to look at this code -- arghh! But there appear to be at least one syntax error. I'm not sure whether you just copied it into this question incorrectly, otherwise I don't even see how it can compile. You put parentheses after lengthOfWord which makes it look like a no-argument method or method call, but you appear to want to use it as an integer variable.
Also inFile and numberFound do not appear to be defined. You will have to provide more context.