How to fix this non-compiling method? - java

Doing some practice exam questions, and it says to:
assume the statement String pattern = getPattern();. Explain if any flow in the method getPattern(). How would you fix it?
Here's the code:
public static String getPattern() {
Scanner inPattern = new Scanner(System.in);
String pattern = " ";
boolean valid = false;
int i = 0;
while(!valid){
System.out.println("please enter a valid pattern with X or x");
pattern = inPattern.next();
if ( ! (pattern.charAt(i) == 'X' || pattern.charAt(i) == 'x'
|| pattern.charAt(i) == 'r'))
System.out.println("You have entered an invalid pattern");
else if ((i + 1) == pattern.length()) valid = true;
};
inPattern.close();
return pattern;
}
I'm not really sure how I would fix this... obviously this is a smaller part of a bigger code because this doesn't include a main method, personally making it a bit more difficult to see what's wrong.
I'm really not sure exactly what to change here. I've been up for 7+ hours watching youtube videos and attempting to understand this stuff or to do this question but I really cannot figure it out. would anyone be able to provide a good example?

Okey, so first things first. The code you recieved is all you need to run it, its not part of a "bigger program". It tells you to assume its being called like this:
String pattern = getPattern();
So when calling the method "getPattern" from a main method what happens? You get prompted to input a "valid" character, if the character is valid the method returns the character.
The question itself is weirdly designed. But looking at the code, I guess what they're fishing for is that you're being told to input the character 'x' or 'X'. But in the code another valid character is 'r'. So either they want you to change the text given to the user, or remove 'r' as a valid char would be my guess.

Related

Recursive java method to parse a string with condition?

Fairly new to java and programming.
Wrote this recursive method, with the objective of asking for a valid string that is both an integer and greater than 0:
private int getDimension(String tableElement){
Integer Input= 0;
System.out.println("Define table rows "+tableElement+"'s."
+"Enter an integer >= 1:");
if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
return getDimension(tableElement);
return Input;
}
I'd like to stick to using a short and recursive method. It seems to handle the >= 0 logic fine, but blows up when i pass it something other than an integer.
Can someone explain why does that happen to me please?
hasNextInt() doesn't actually consume your input, so you're stuck with the same non-int input on your next call.
Simply spoken, your code doesn't make much (any?) sense.
First of all, there is not really a point in using a recursive method that asks the user for input; and that does not at all do anything about the argument passed to it!
private int getDimension(String tableElement){
Integer Input= 0;
Bad: you keep up mixing int and `Integer. They are not the same. And - read about java coding style guides. Variable names start lower case!
if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
The first condition gives:
true: when there is NO int ...
false: when there is an int
true leads to: calling your method again without retrieving a value from the reader.
false leads to parsing an int; and checking its value for <= 0.
In one case, you are doing a recursive call; completely ignoring the input you got from the reader; in the other case, you returning 0; or that value in input.
Solution: do something like:
while (true) {
if (reader.hasNextInt()) {
input = reader.nextInt();
break;
}
// there is no number!
read.nextLine(); // consume & throw away non-number!
print "Enter a number"
}
instead.
But seriously: start with throwing away this code.
Final side note: you do Input.parseInt() ... but that is a static method on the Integer class. Just call that as Integer.parseInt() instead! But as said; throw away your code; and learn how to properly use that Scanner class; start reading here.
Because the user can enter anything, you must always read in the line, then compare it:
String num = Reader.nextLine();
return num.matches("[1-9][0-9]*") ? Integer.parseInt(num) : getDimension(tableElement);
Here I've use regex to figure out if it's a positive number; the expression means "a 1-9 char followed by 0 or more of 0-9 chars"

Java Do While Statement with two conditions

I'm trying to learn java but I'm stuck trying to do a single program which concerns Do While Statement with two conditions. Specifically, I want a method to run until the user write "yes" or "no". Well, down there is my thing, what is wrong with it?
String answerString;
Scanner user_input = new Scanner(System.in);
System.out.println("Do you want a cookie? ");
do{
answerString = user_input.next();
if(answerString.equalsIgnoreCase("yes")){
System.out.println("You want a cookie.");
}else if(answerString.equalsIgnoreCase("no")){
System.out.println("You don't want a cookie.");
}else{
System.out.println("Answer by saying 'yes' or 'no'");
}while(user_input == 'yes' || user_input == 'no');
}
}}
I'd do something similar to Tim's answer. But to do things the way you were trying to do them, you have a lot of problems that need to be fixed:
(1) String literals in Java are surrounded by double quote marks, not single quote marks.
(2) user_input is a Scanner. You can't compare a scanner to a string. You can only compare a String to another String. So you should be using answerString in your comparison, not user_input.
(3) Never use == to compare strings. StackOverflow has 953,235 Java questions, and approximately 826,102 of those involve someone trying to use == to compare strings. (OK, that's a slight exaggeration.) Use the equals method: string1.equals(string2).
(4) When you write a do-while loop, the syntax is do, followed by {, followed by the code in the loop, followed by }, followed by while(condition);. It looks like you put the last } in the wrong place. The } just before the while belongs to the else, so that doesn't count; you need another } before while, not after it.
(5) I think you were trying to write a loop that keeps going if the input isn't yes or no. Instead, you did the opposite: you wrote a loop that keeps going as long as the input is yes or no. Your while condition should look something like
while (!(answerString.equals("yes") || answerString.equals("no")));
[Actually, it should be equalsIgnoreCase to be consistent with the rest of the code.] ! means "not" here, and note that I had to put the whole expression in parentheses after the !, otherwise the ! would have applied only to the first part of the expression. If you're trying to write a loop that does "Loop until blah-blah-blah", you have to write it as "Loop while ! (blah-blah-blah)".
I might opt for a do loop which will continue to take in command line user input until he enters a "yes" or "no" answer, at which point the loop breaks.
do {
answerString = user_input.next();
if ("yes".equalsIgnoreCase(answerString)) {
System.out.println("You want a cookie.");
break;
} else if ("no".equalsIgnoreCase(answerString)) {
System.out.println("You don't want a cookie.");
break;
} else {
System.out.println("Answer by saying 'yes' or 'no'");
}
} while(true);

String Input (Only outputs the first word said)

I'm trying to make a piece of code that will yell out anything I input.
So the command is 'yell'
I want to be able to type 'yell (whatever i want here)' and it will yell it out. I've managed to get this working with a help of a friend. But for some reason it will only yell the first word that's been output. So I can't type a sentence because it will only say the first word of a sentence.
Here's the piece of code, I hope you can help.
case "npcyell":
for (NPC n : World.getNPCs()) {
if (n != null && Utils.getDistance(player, n) < 9) {
String sentence = "";
for (int i = 1; i < cmd.length; i++) {
sentence = sentence + " " + cmd[i];
}
n.setNextForceTalk(new ForceTalk("[Alert] "
+ Utils.getFormatedMessage(sentence)));
}
}
return true;
Well I did something similar a while ago. You said that you wanted to be able to say "yell(text)" and have it output whatever the text was. I have a different way of implementing it than you do, but the general result is the same, but it can be adapted to however you are using it in this context. This is also assuming that you are running this program as a console project only. if not change the scanner with whatever you are using to input text into and replace the text assignment to text = textInputArea.getText().toString(); and change the output statement to System.out.println(text.getText().toString().substring(6,text.getText().toString().length() - 1));
Scanner s = new Scanner(System.in);
String text = s.nextLine();
if (text.startsWith("yell(") && text.endsWith(")")){
System.out.println(text.substring(6,text.length() - 1));
}
I hope this works for you. And I honestly hope that this is adaptable towards the program you are making.

Java - appending & passing values

I'm having trouble with passing a string and double to another class because it keeps on crashing at double cost = input.nextDouble();. Also, i was wondering if i am correct with the appending method used in public boolean addPARTDETAILS(String partDESCRIPTION, double partCOST).
For example. If the user enters the parts and cost, i want it to store that in a list and print it out with the cost appended.
Parts used:
brake pads ($50.00)
brake fluids ($25.00)
Note. Assuming that i have declared all variables and the array.
System.out.print("Enter registration number of vehicle");
String inputREGO = input.next();
boolean flag = false;
for(int i=0; i<6; i++){
if(inputREGO.equalsIgnoreCase(services[i].getregoNUMBER())){
System.out.print("Enter Part Description: ");
String parts = input.nextLine();
double cost = input.nextDouble();
services[i].addPARTDETAILS(parts, cost);
//System.out.println(services[i].getregoNUMBER());
flag = true;
}
}if(flag==false);
System.out.println("No registration number were found in the system.");
public boolean addPARTDETAILS(String partDESCRIPTION, double partCOST){
if(partDESCRIPTION == "" || partCOST <= 0){
System.out.println("Invalid input, please try again!");
return false;
}
else{
partCOST=0;
StringBuffer sb = new StringBuffer(40);
String[] parts = new String[50];
for (int i=0;i<parts.length;i++){
partDESCRIPTION = sb.append(partCOST).toString();
}
System.out.println(partDESCRIPTION);
totalPART+=partCOST;
return true;
}
}
it keeps on crashing at double cost = input.nextDouble();.
It is highly unlikely that your JVM is crashing. It is far more likely that you are getting an Exception which you are not reading carefully enough and have forgotten to include in your question.
It is far more likely your code is incorrect as you may have mis-understood how scanner works. And so when you attempt to read a double, there is not a double in the input. I suspect you want to call nextLine() after readDouble() to consume the rest of the the line.
I suggest you step through the code in your debugger to get a better understanding of what it is really doing.
Just to expand a bit on Joop Eggen's and Peter Lawrey's answers because I feel some may not understand.
nextLine doesn't play well with others:
nextDouble is likely throwing a NumberFormatException because:
next, nextInt, nextDouble, etc. won't read the following end-of-line character, so nextLine will read the rest of the line and nextDouble will read the wrong thing.
Example: (| indicates current position)
Start:
|abc
123
def
456
After nextLine:
abc
|123
def
456
After nextDouble:
abc
123|
def
456
After nextLine (which reads the rest of the line, which contains nothing):
abc
123
|def
456
Now nextDouble tries to read "def", which won't work.
If-statement issues:
if(flag==false);
or, rewritten:
if(flag==false)
;
is an if statement with an empty body. Thus the statement following will always execute. And no need to do == false, !flag means the same. What you want:
if (!flag)
System.out.println("No registration number were found in the system.");
String comparison with ==:
partDESCRIPTION == ""
should be:
partDESCRIPTION.equals("")
or better:
partDESCRIPTION.isEmpty()
because == check whether the strings actually point to the exact same object (which won't happen unless you assign the one to the other with = at some point, either directly or indirectly), not just whether the have the same text (which is what equals is for).
Data dependent error.
if(flag==false);
System.out.println("No registration number were found in the system.");
should be (because of the ;):
if (!flag) {
System.out.println("No registration number was found in the system.");
}
And
partDESCRIPTION == ""
should be:
partDESCRIPTION.isEmpty()

Efficent way to replace underscore with char or string

I have researched this topic for a while, but without much success. I did find the StringBuilder and it works wonders, but that's as far as I got. Here is how I got my hangman program to work like it should:
if(strGuess.equalsIgnoreCase("t")){
mainword.replace(0,1,"T");
gletters.append('T');
}
else if(strGuess.equalsIgnoreCase("e")){
mainword.replace(1,2,"E");
gletters.append('E');
}
else if(strGuess.equalsIgnoreCase("c")){
mainword.replace(2,3,"C");
gletters.append('C');
}
else if(strGuess.equalsIgnoreCase("h")){
mainword.replace(3,4,"H");
gletters.append('H');
}
else if(strGuess.equalsIgnoreCase("n")){
mainword.replace(4,5,"N");
gletters.append('N');
}
else if(strGuess.equalsIgnoreCase("o")){
mainword.replace(5,6,"O");
mainword.replace(7,8,"O");
gletters.append('O');
}
else if(strGuess.equalsIgnoreCase("l")){
mainword.replace(6,7,"L");
gletters.append('L');
}
else if(strGuess.equalsIgnoreCase("g")){
mainword.replace(8,9,"G");
gletters.append('G');
}
else if(strGuess.equalsIgnoreCase("y")){
mainword.replace(9,10,"Y");
gletters.append('Y');
}
else{
JOptionPane.showMessageDialog(null, "Sorry, that wasn't in the word!");
errors++;
gletters.append(strGuess.toUpperCase());
}
SetMain = mainword.toString();
GuessedLetters = gletters.toString();
WordLabel.setText(SetMain);
GuessedLabel.setText(GuessedLetters);
GuessText.setText(null);
GuessText.requestFocusInWindow();
However, I can't do this for EVERY letter for EVERY word, so is there a simple and efficient way to do this? What I want is to have a loop of some sort so that I would only have to use it once for whatever word. So the word could be technology (like it is above) or apple or pickles or christmas or hello or whatever.
I have tried using a for loop, and I feel the answer lies in that. And if someone could explain the charAt() method and how/where to use it, that'd be good. The closest I got to being more efficient is:
for(i = 0; i < GuessWord.length(); i++) {
if (GuessWord.charAt(i) == guess2) {
mainword.replace(i,i,strGuess.toUpperCase());
}
So if you could use that as a basis and go off of it, like fix it? Or tell me something I haven't thought of.
It's a good question. There's clearly repeated code, so how do you replace all that with something reusable. Actually, you can dispense with all of your code.
That whole code block can be replaced by just one line (that works for every word)!
String word = "TECHNOLOGY"; // This is the word the user must guess
mainword = word.replaceAll("[^" + gletters + "]", "_");
This uses replaceAll() with a regex that means "any letter not already guessed" and replaces it with a underscore character "_". Note that Strings are immutable, and the replaceAll() method returns the modified String - it doesn't modify the String called on.
Here's some test code to show it in action:
public static void main(String[] args) {
String word = "TECHNOLOGY"; // what the user must guess
StringBuilder gletters = new StringBuilder("GOTCHA"); // letters guessed
String mainword = word.replaceAll("[^" + gletters + "]", "_");
System.out.println(mainword);
}
Output:
T_CH_O_OG_

Categories

Resources