[EDIT]
It seems like moving this piece of code somewhere else would solve my issue, but I can't see to figure out where..
if (numLeaving < MIN_PEOPLE || numEntering < MIN_PEOPLE || totalPeople < MIN_PEOPLE) {
JOptionPane.showMessageDialog(null,"Invalid data");
}
Could someone explain why my 'total people' still gets updated when I enter an invalid value such as a negative number? Also, why would the total people get printed anyway if the user enters invalid input?
final int MAX_PEOPLE = 65;
final int MIN_PEOPLE = 0;
int totalPeople = 0;
int numLeaving = 0;
int numEntering = 0;
boolean invalid = true;
while (invalid) {
String question = JOptionPane.showInputDialog("leaving or entering?");
try {
// Decrease the total if people are leaving
if (question.equalsIgnoreCase("leaving")) {
numLeaving = Integer.parseInt(JOptionPane.showInputDialog("number leaving:"));
totalPeople -= numLeaving;
}
// Increase the total if people are entering
else if (question.equalsIgnoreCase("entering")) {
numEntering = Integer.parseInt(JOptionPane.showInputDialog("number entering:"));
totalPeople += numEntering;
}
else {
JOptionPane.showMessageDialog(null,"'leaving' or 'entering' only");
}
// Prints out current total before capacity is exceeded
if (totalPeople > MAX_PEOPLE) {
invalid = false;
totalPeople = totalPeople - numEntering;
JOptionPane.showMessageDialog(null,"Capacity exceeded\n" + "Total people = " + totalPeople);
}
else {
JOptionPane.showMessageDialog(null,"Total people = " + totalPeople);
}
}
catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null,"numbers only");
}
}
The reason 'totalPeople' is still being updated is because you are not checking if it is a valid input in the beginning your loop. If I were you I would add the following code in the beginning of your while loop:
if(totalPeople < 0){
invalid = false;
break;
}
Also I find it a bit misleading naming a boolean in the negative. Having a boolean named 'invalid' being true would make one question, "Does the true stand for valid or invalid?"
I would name the boolean as 'valid' instead.
Your program doesn't say anywhere that a negative number is invalid input. -= and += operators will just work fine for negative ints.
[Edit]
Suppose you select "leaving" and provide numLeaving =-65 tehn total people will be 0-(-65) = 65. You will enter the if block of below code and not the else blocks which checks for negative inputs.
if (totalPeople > MAX_PEOPLE) {
invalid = false;
totalPeople = totalPeople - numEntering;
JOptionPane.showMessageDialog(null,"Capacity exceeded\n" + "Total people = " + totalPeople);
}
else if (numLeaving < MIN_PEOPLE || numEntering < MIN_PEOPLE || totalPeople < MIN_PEOPLE) {
JOptionPane.showMessageDialog(null,"Invalid data");
}
else {
JOptionPane.showMessageDialog(null,"Total people = " + totalPeople);
}
Related
I have a condition where if the user inputs a negative number or a number which is more than 100, or a string, an error message should be printed "That wasn't a valid percentage, I need a number between 0-100. Try again." and ask the user to reenter a valid number. and if the user decided to just enter, all the input should be calculated and printed the average amount.
public static void main(String[ ] args) {
int count = 0; //count to stop loop
double[ ] aGrade = new double[SIZE];
String input = new String("");
Scanner scan = new Scanner(System.in);
double total = 0;
int gTotal = aGrade.length;
boolean exit = false;
while ((count < SIZE) && (!exit)) {
System.out.print("Enter number " + (count + 1) + ": " + "\n");
try {
input = scan.nextLine();
if (Double.parseDouble(input) > 0 && Double.parseDouble(input) < 100) {
aGrade[count] = Double.parseDouble(input); //put into the array
count++; //only increment count if success
} else
System.out.println("That wasn't a valid percentage,"
+ " I need a number between 0-100. Try again.");
} catch (NumberFormatException nfe) {
exit = true; //exit loop
}
}
System.out.println("number of grades entered: " + count + "\n");
for (int i = 0; i < count; i++) {
// print entered grade
System.out.println("grade " + (i + 1) + ": " + aGrade[i]);
}
for (int i = 0; i < count; i++) {
total += aGrade[i];
}
// calculate and print the average
System.out.println("\n" + "Average grade: " + total /count);
But when I run my code, if I input letters, it won't allow the user to reinput value but prints whatever is calculated. I think it is in my if-else statement, but I am not sure how
When we try to convert String to Double it will throw java.lang.NumberFormatException. So whenever you enter String or char at that time instead of else it will go to catch block. As per your code else block only executed when user enter negative number or grater then 100 number.
I updated your code. Please review it.
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
int count = 0; // count to stop loop
double[] aGrade = new double[3];
String input = new String("");
Scanner scan = new Scanner(System.in);
double total = 0;
int gTotal = aGrade.length;
boolean exit = false;
while ((count < 3) && (!exit)) {
System.out.print("Enter number " + (count + 1) + ": " + "\n");
try {
input = scan.nextLine();
if (Double.parseDouble(input) > 0 && Double.parseDouble(input) < 100) {
aGrade[count] = Double.parseDouble(input); // put into the array
count++; // only increment count if success
} else
System.out
.println("That wasn't a valid percentage," + " I need a number between 0-100. Try again.");
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
exit = true; // exit loop
}
}
if (!exit) {
System.out.println("number of grades entered: " + count + "\n");
for (int i = 0; i < count; i++) {
// print entered grade
System.out.println("grade " + (i + 1) + ": " + aGrade[i]);
}
for (int i = 0; i < count; i++) {
total += aGrade[i];
}
// calculate and print the average
System.out.println("\n" + "Average grade: " + total / count);
}else {
System.out
.println("That wasn't a valid percentage," + " I need a number between 0-100. Try again.");
}
}
}
If you type letter as an input, you will never end up in your else part of the if statement since code inside if throws an exception and you are then inside catch part. Also, you wrote inside catch part, when NumberFormatException happens(when you enter letter instead of number), set exit to true and that is the reason why program don't let you type again after you input letter. Fix those things and it will work. Also, take a look at how to debug your program, learn that skill, it will help you to solve this kind of problems in the future.
Try something like this:
boolean ok = false;
try {
input = scan.nextLine();
if ("".equals(input)) {
ok = true;
exit = true;
} else if (Double.parseDouble(input) >= 0 && Double.parseDouble(input) <= 100) {
aGrade[count] = Double.parseDouble(input); //put into the array
count++; //only increment count if success
ok = true;
}
} catch (NumberFormatException nfe) {
// nothing
}
if (!ok) {
System.out.println("That wasn't a valid percentage,"
+ " I need a number between 0-100. Try again.");
}
I wrote a code about primes and would hear your opinion or any suggestions how i can improve my code. I'm a beginner in Java.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean a;
System.out.println("Please enter a number: ");
int zahl = s.nextInt();
if(zahl <= 0) {
System.out.println("Please enter a positive number without zero.");
return;
}
a = true;
for (int i = 2; i < zahl; i++) {
if (zahl % i == 0) {
a = false;
}
}
if (a == true) {
System.out.println("Is Prim");
}
if (a==false){
System.out.println("Not a prim");
}
}
The easiest thing to do is the following
Instead of
for (int i = 2; i < zahl; i++) {
if (zahl % i == 0) {
a = false;
}
}
change the for loop the
for (int i = 2; i < Math.sqrt(zahl); i++)
If no numbers up to the square root divide zahl, then no numbers beyond the square root will divide it either (they would have been the result of earlier divisions).
Also, for outputing the answer you could do:
System.out.println(zahl + " is " + ((a) ? "prime"
: "not prime"));
That's using the ternary operator ?:
some hints :
You do
System.out.println("Please enter a positive number without zero.");
return;
the println suggests the user can enter a new value, but no, in that case better to say the number was invalid so you exit
When you do a = false; it is useless to continue, no chance for a to be back true
It is useless to try to divide by more than sqrt the number
It is necessary to try to divide by 2 but not by an other even number, so add 2 to i rather than 1
If if (a == true) false it is useless to check if (a==false)
Your code is good. I have made three small improvements:
The input asks at once (and not only after a bad input) for a
positive int.
The input is repeated until correct.
The for loop runs only up to sqrt(zahl) which is sufficient.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean a;
int zahl = 0;
while (zahl <= 0) {
System.out.println("Please enter a positive int without zero.");
zahl = s.nextInt();
}
a = true;
for (int i = 2; i <= Math.sqrt(zahl); i++) {
if (zahl % i == 0) {
a = false;
break;
}
}
if (a == true) {
System.out.println("Is Prim");
} else {
System.out.println("Not a prim");
}
}
So my program asks two questions, directions and miles. A user can enter an infinite input for direction and miles, but once the user is done he would simply type "Done" and the loop would break and show the message and the end. I can't get the loops to break need help. Also when a letter is typed for numOfMiles the program just ends. It's suppose to give the error message and reprompt but i can't seem to get that working.
import javax.swing.JOptionPane;
public class taxiService {
public static void main(String [] args) {
//Declare variables
double fareCharge = 5;
double totalMiles = 0;
double finalFareCharged = 0;
double finalxCoord = 0;
double finalyCoord = 0;
double numOfMiles = 0;
double finalCoord = 0;
String error = "Invalid data, please enter valid data!";
String directions = "";
boolean restart = true;
//Prompt for direction and miles
while(restart){
boolean reprompt = true;
boolean reprompt_SecondQuestion = true;
while (reprompt) {
directions = JOptionPane.showInputDialog(null, "Please enter a direction: ");
if (directions.equalsIgnoreCase("East")) {
finalxCoord = finalxCoord + numOfMiles;
reprompt = false;
}
else if (directions.equalsIgnoreCase("West")) {
finalxCoord = finalxCoord - numOfMiles;
reprompt = false;
}
else if (directions.equalsIgnoreCase("North")) {
finalyCoord = finalyCoord + numOfMiles;
reprompt = false;
}
else if (directions.equalsIgnoreCase("South")) {
finalyCoord = finalyCoord - numOfMiles;
reprompt = false;
}
else {
reprompt = true;
JOptionPane.showMessageDialog(null, error);
}
}
while(reprompt_SecondQuestion)
{
numOfMiles = Double.parseDouble(JOptionPane.showInputDialog(null, "Please enter distance in miles: "));
if (numOfMiles > 0) {
totalMiles += numOfMiles;
reprompt_SecondQuestion = false;
}
else {
JOptionPane.showMessageDialog(null, error);
}
}
//Prompt user to type "done"
//Capture user input
if(directions.equalsIgnoreCase("Done"))
{
//Display direction and miles to user
restart = false;
break;
}
else
{
}
}
finalFareCharged = fareCharge + ((numOfMiles / .25) * 2);
JOptionPane.showMessageDialog(null, "miles: " + totalMiles + "\nDirection :" + directions + "\nFinal Charge: " + finalFareCharged + "\nCoordination: " + finalCoord);
}
}
I was able to use this to stop the looping problem
while(done) {
end = JOptionPane.showInputDialog(null, "Is this your destination?(YES/NO)");
if (end.equalsIgnoreCase("Yes")) {
restart = false;
reprompt = false;
reprompt_SecondQuestion = false;
done = false;
break;
}
else if (end.equalsIgnoreCase("No")) {
restart = true;
done = false;
}
else{
JOptionPane.showMessageDialog(null, error);
done = true;
}
}
i still got a problem with numOfMiles. if a letter is entered the program ends. it doesn't give the error message. i've added reprompt_SecondQestion = true; but no change.
I would use labeled break statement (so the intention would be clear for the future reader of the code). Here is the example which prints s0-1-2-3e:
...
System.out.print("s");
labelName:
while (true) {
for (int i = 0; i < 5; i++) {
System.out.print(i);
if (i == 3) {
break labelName; // the "thing" you are looking for
}
}
System.out.print("-");
}
System.out.print("e");
...
This means that you only need to add the label label: and condition statement:
if (directions.equalsIgnoreCase("Done")) {
break label;
}
Your task now, is just to find a proper places to put the code.
Check the condition of your loop. Something like this would suffice:
if(directions.equalsIgnoreCase("Done"))
{
//Display direction and miles to user
reprompt_SecondQuestion = false;
reprompt = false;
restart = false;
break;
}
Also I cannot tell from the brackets where this block is located, if it is at all within the loop. Please check, as proper formatting will save you hours.
Hi i was trying to create a mock database search and, though it works, whenever i enter an input that is not part of the database, it creates an Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 on line 23. I dont know what else to do as i see no error in the code.
import java.util.*;
public class Database {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
String[] names = new String[4];
boolean found = false;
int i = 0;
names[0] = "Thor";
names[1] = "Ben";
names[2] = "Zoe";
names[3] = "Kate";
System.out.println("Enter Player Name");
String input = scan.nextLine();
while(found != true){
if(input.equals(names[i])){
System.out.println(input + " has been found");
found = true;
} else {
i = i+1;
}
if(i == 3 && found == false){
System.out.println(input + " was not found");
}
}
}
}
You are not leaving the loop after you print that input + " was not found".
Therefore the next iteration of the loop throws ArrayIndexOutOfBoundsException.
You should leave the loop after you finish testing the entire array.
change
while(found != true){
to
while(!found && i < names.length){
Actually you can move the if statement that tests whether the input wasn't found to be after the loop :
while(!found && i < names.length) {
if(input.equals(names[i])){
System.out.println(input + " has been found");
found = true;
} else {
i = i+1;
}
}
if(!found){
System.out.println(input + " was not found");
}
An even better alternative would be to use a for loop :
for (int i = 0; i < names.length && !found; i++) {
if(input.equals(names[i])){
System.out.println(input + " has been found");
found = true;
}
}
if(!found){
System.out.println(input + " was not found");
}
if your input doesn't matches the value of i will keep on incrementing and your length of an array is 4. Obviously ArrayindexoutofException.
To avoid you need to consider the array length also.
Change your while loop to
while (found != true) {
if (input.equals(names[i])) {
System.out.println(input + " has been found");
found = true;
} else {
i = i + 1;
}
if (i == 4 && found == false) { //changed here
System.out.println(input + " was not found");
//or found == true;
break; //and here
}
}
You need to quit the loop if THIS condition is true
i == 4 && found == false
and to actually quit, you must "break" the while condition
found != true
You can do this by setting found=true (but that's not semantically correct) or add the break instruction.
Here is an alternative solution to your while loop:
while (!found && i<4)
if (input.equals(names[i++]))found = true;
System.out.println(input+(found?" has been":" was not")+" found");
You can simply change to
while(i < names.length)
and forget the additional boolean variable. Since you want to keep iterating i until you find the solution, the stop condition will be the max i. When you do find your solution, you can simply breakthe while statement:
if (input.equals(names[i])) {
System.out.println(input + " has been found");
break;
}
I am creating a hangman game. Everything works fine, I have code ready to be used for failing the game and giving -1 to the guesses. Though when adding it to the else statement it gets duplicate equal to the length of the word and it also gives a guess—even though its right? I don't see what's wrong in the code? I believe it's my code when guessing wrong which is not placed right though I see no other way?
This is the code:
private class check implements ActionListener {
public void actionPerformed(ActionEvent ae) {
try {
// Grabs the letter from the guessField and converts it into a char
// which can be used to compare against the word.
guess = guessField.getText();
guessField.setText("");
char guess2 = guess.charAt(0);
// --------------------
// Here is the guessing logic but it's currently
// not working and you can not win since i haven't written code for
// it yet. it's not selecting all the letters. for Example if
// choosing A in a word such as Banana it only selects the first
// a--------------------------- //
String displaySecret = wordField.getText();
if (displaySecret.equals("")) {/* case for fist execution */
displaySecret = "";
for (int i = 0; i < random.length(); i++)
displaySecret += "_ ";
}
String newDisplaySecret = "";
for (int v = 0; v < random.length(); v++) {
if (guess2 == random.charAt(v)) {
newDisplaySecret += random.charAt(v); // newly guessed
// character
} else {
newDisplaySecret += displaySecret.charAt(v); // old state
guesses--;
statusLabel.setText("Guesses left: " + guesses);
missField.setText(missField.getText() + guess);
if (guesses <= 0) {
JOptionPane.showMessageDialog(null,
"Game over! The word was: " + random);
guessField.setEditable(false);
wordField.setText("");
missField.setText("");
guesses = 7;
statusLabel.setText("Guesses left: " + guesses);
}
}
}
displaySecret = new String(newDisplaySecret);
wordField.setText(displaySecret);
if (displaySecret.equals(random)) {
JOptionPane.showMessageDialog(null, "You Won! The Word was: "
+ random);
guesses = 7;
statusLabel.setText("Guesses left: " + guesses);
wordField.setText("");
missField.setText("");
guessField.setEditable(false);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
If randomis your Word, you iterate over each Character of it and then check whether each single character matches the guess you get for each character that doesn't match the guess a -1.
For Example: The Word is Bananaramaand you guess a nyour first and second matches will go to the else clause. then one time the if clause goes again, then the else and so on.
You have to
iterate over all characters, check whether they match or not
if a match occurs, replace the char and increase the counter
check if the counter of correct characters equals 0
if so, decrease the guesses
Some other tips: you should use .toLower() on your input and word string before comparsion to allow insensitivity for case
Some sample code:
int charsGuessedCorrectly;
for ( int i = 0; i < random.length( ); i++ )
{
if ( random.charAt( i ) == guess )
{
charsGuessedCorrectly++;
newDisplaySecret += random.charAt(v); // newly guessed
// character
}
}
if ( charsGuessedCorrectly == 0 )
{
newDisplaySecret += displaySecret.charAt(v); // old state
guesses--;
statusLabel.setText("Guesses left: " + guesses);
missField.setText(missField.getText() + guess);
if (guesses <= 0) {
JOptionPane.showMessageDialog(null,
"Game over! The word was: " + random);
guessField.setEditable(false);
wordField.setText("");
missField.setText("");
guesses = 7;
statusLabel.setText("Guesses left: " + guesses);
}
Here is what you need to check your word and generate "newDisplaySecret":
for (int v = 0; v < random.length(); v++) {
if (guess2 == random.charAt(v)) {
newDisplaySecret += random.charAt(v); // newly guessed
// character
} else {
newDisplaySecret += displaySecret.charAt(v);
}
Here is how you can determine whether the player guessed right or wrong:
if(newDisplaySecret.equals(displaySecret)){
guesses --;
}
This needs to be placed after your check word code. Your code seems to decrement guesses for each letter in the word random.
Update display:
displaySecret = new String(newDisplaySecret);
wordField.setText(displaySecret);
Now that you know what the current state of affairs is for this move you can decide if the person has won or lost or just needs to continue playing:
if(guesses <= 0){
/*place here instructions for loosing scenario*/
}else{
if(displaySecret.equals(random)) {
/*place here instructions for winning scenario*/
}
/*simply do nothing the game is neither lost or won*/
}
Hope this helps