My programs purpose is to calculate the average, maximum, and minimum of the test scores entered by a user.
Here is the problem I keep running into: My program is built to deny test scores entered that are either below zero or above 100, which it does, but for example, if the user inputed 108, it would say "ERROR: Not a valid test score. " BUT even when the score is denied, it still adds that score to the count, and 108 would be the maximum. If an invalid score is entered, I need for it to be completely excluded from the program.
Can anyone explain how to fix this?
Here is my code.
import java.util.Scanner;
import java.io.*;
import java.text.DecimalFormat;
public class hw {
public static void main(String[] args) {
int maxGrade = Integer.MIN_VALUE;
int minGrade = Integer.MAX_VALUE;
int count = 0;
int total = 0;
final int SENTINEL = -1;
int score;
Scanner scan = new Scanner(System.in);
System.out.println("To calculate the class average, enter each test
score.");
System.out.println("When you are finished, enter a -1.");
System.out.print("Enter the first test score > ");
score = scan.nextInt();
while (score != SENTINEL)
{
total += score;
//add one to the count
count++;
//calculate the maximum and the minimum
if (score > maxGrade) {
maxGrade = score;
}
if (score < minGrade) {
minGrade = score;
}
if (score < 0 || score> 100)
System.out.print("ERROR: Not a valid test score. ");
System.out.println(" Enter the next test score > ");
score = scan.nextInt();
}
if (count != 0) {
DecimalFormat oneDecimalPlace = new DecimalFormat("0.0");
System.out.println("\nThe class average is "
+ oneDecimalPlace.format((double) (total) / count));
System.out.println("The minimum value is " + minGrade);
System.out.println("The maximum value is " + maxGrade);
} else {
System.out.println("\nNo grades were entered");
}
}
}
You have to add to total, calculate max and min only if 0 < input < 100
import java.util.Scanner;
import java.io.*;
import java.text.DecimalFormat;
public class hw {
public static void main(String[] args) {
int maxGrade = Integer.MIN_VALUE;
int minGrade = Integer.MAX_VALUE;
int count = 0;
int total = 0;
final int SENTINEL = -1;
int score;
Scanner scan = new Scanner(System.in);
System.out.println("To calculate the class average, enter each test score.");
System.out.println("When you are finished, enter a -1.");
System.out.print("Enter the first test score > ");
score = scan.nextInt();
while (score != SENTINEL)
{
if (score < 0 || score> 100)
{
System.out.print("ERROR: Not a valid test score. ");
}
else
{
//add one to the count
count++;
//calculate the maximum and the minimum
if (score > maxGrade) {
maxGrade = score;
}
if (score < minGrade) {
minGrade = score;
}
total += score;
}
System.out.println(" Enter the next test score > ");
score = scan.nextInt();
}
if (count != 0) {
DecimalFormat oneDecimalPlace = new DecimalFormat("0.0");
System.out.println("\nThe class average is "
+ oneDecimalPlace.format((double) (total) / count));
System.out.println("The minimum value is " + minGrade);
System.out.println("The maximum value is " + maxGrade);
} else {
System.out.println("\nNo grades were entered");
}
}
}
Because if you enter 108 as your first input it will go into While Loop as 108!=sentinel and will add 108 to total.
To avoid this just add this as first statement inside While Loop :
If(score>108 || score <0)
{
System.out.println("Invalid score");
continue;
}
So if the score is invalid it will ignore the subsequent lines of code and return to start of While Loop again .
Related
public static void main(String[] args) {
// Defining the constants for min and max range
final int minValue = -1;
final int maxValue = 100;
String message = "Welcome to Simple Gradebook!";
promptForInt(message, minValue, maxValue);
// Declaring variables for the loop & the sentinel variable
int score = 0;
boolean doneYet = false;
do {
// Input Validation
if (score < minValue || score > maxValue) {
System.err.printf(
"Invalid value. The acceptable range is" + " between %d and %d\n" + "Please try again\n",
minValue, maxValue);
score = promptForInt(message, minValue, maxValue);
} else {
doneYet = true;
}
} while (doneYet == false);
}
public static int promptForInt(String message, int minValue, int maxValue) {
// Declaring variables for the loop & the sentinel variable
int sum = 0;
int numStudents = 0;
int score = 0;
System.out.println(message);
// Creating the sentinel loop
do {
System.out.printf("Enter the score for student #%d" + "(or -1 to quit): ", numStudents);
Scanner keyboard = new Scanner(System.in);
score = Integer.parseInt(keyboard.nextLine());
if (score != -1) {
sum += score;
numStudents += 1;
}
} while (score != -1);
double avgScore = (double) sum / numStudents;
// Passing method to this method to convert grade to letter
convertToLetter(avgScore);
System.out.println("The average score is: " + avgScore + " which equates to a " + avgScore);
return 0;
}
How can I get my input validation to work so anything outside range -1 - 100 will display the error message? I want to use the "do-while" loop and thought I was doing it all correctly. If a user enters a value outside the defined range, it should display the error message and prompt again for the score. What am I missing?
A good place to do the validation is inside the method, promptForInt.
Since there is no use of the value returned from method, promptForInt, it's better to declare it as void.
Do not instantiate the Scanner object inside the loop.
The following code has incorporated all these comments:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// Defining the constants for min and max range
final int minValue = -1;
final int maxValue = 100;
String message = "Welcome to Simple Gradebook!";
promptForInt(message, minValue, maxValue);
}
public static void promptForInt(String message, int minValue, int maxValue) {
// Declaring variables for the loop & the sentinel variable
int sum = 0;
int numStudents = 0;
int score = 0;
boolean valid;
Scanner keyboard = new Scanner(System.in);
System.out.println(message);
// Loop to continue getting score for students until -1 is entered to quit
do {
System.out.printf("Enter the score for student #%d" + "(or -1 to quit): ", numStudents);
// Loop for getting input of score for the current student
do {
valid = true;
score = Integer.parseInt(keyboard.nextLine());
// Input Validation
if (score < minValue || score > maxValue) {
System.err.printf(
"Invalid value. The acceptable range is" + " between %d and %d\n" + "Please try again\n",
minValue, maxValue);
valid = false;
}
} while (!valid);
if (score != -1) {
sum += score;
numStudents += 1;
}
} while (score != -1);
double avgScore = (double) sum / numStudents;
// Passing method to this method to convert grade to letter
convertToLetter(avgScore);
System.out.println("The average score is: " + avgScore + " which equates to a " + convertToLetter(avgScore));
}
public static char convertToLetter(double avg) {
char gradeLetter;
// Identifying the ranges for the grade letter
if (avg >= 90) {
gradeLetter = 'A';
} else if (avg >= 80) {
gradeLetter = 'B';
} else if (avg >= 70) {
gradeLetter = 'C';
} else if (avg >= 60) {
gradeLetter = 'D';
} else {
gradeLetter = 'F';
}
return gradeLetter;
}
}
A sample run:
Welcome to Simple Gradebook!
Enter the score for student #0(or -1 to quit): -2
Invalid value. The acceptable range is between -1 and 100
Please try again
-4
Invalid value. The acceptable range is between -1 and 100
Please try again
45
Enter the score for student #1(or -1 to quit): 50
Enter the score for student #2(or -1 to quit): -1
The average score is: 47.5 which equates to a F
My code is supposed to ask for a name, ask for a number between one and ten, print the numbers from 1 to the number the user entered except every third number should
be the user's name that was entered at the beginning of the program, print the even numbers, continually ask the user for numbers until the user enters the sentinel, and then print the total of the numbers entered. (I know, that's a lot.) My code is running fine, the only problem I am having is with the last part. Even when the user enters the sentinel, which in this case is -1, the program still asks for another entry.
Did I do something wrong when declaring the variable or can someone explain how to fix my problem? Here is my code.
import java.util.Scanner;
/**
*
* #author Home
*/
public class NewClass1 {
public static void main(String[] args) {
int number;
Scanner scan = new Scanner( System.in);
System.out.print( "Enter your name: ");
String name = scan.nextLine();
System.out.print( "Please enter a number between 1 and 10: ");
number = scan.nextInt();
//asks for a number between one and ten until I get number within that range,
while (number < 1 || number > 10) {
System.out.print( "No, between 1 and 10: ");
number = scan.nextInt();
}
for (int i = 1; i <= number; i++) {
if (i % 3 == 0) {
System.out.print(name + " ");
} else {
System.out.print(i + " ");
}
}
System.out.println();
for(int i =2; i<=number; i+=2)
System.out.print(i + " ");
System.out.print("are the even numbers.");
final int SENTINEL = -1;
int inputNumber;
int total = 0;
System.out.println(" Enter a number or -1 to finish. " );
inputNumber = scan.nextInt();
while ( inputNumber != SENTINEL )
{
total += number;
System.out.print("Enter the next number or '-1' to finish. ");
number = scan.nextInt();
}
System.out.println( "The total is " + total);
}
}
Solution:
You get input from user and saving that input in varible called number but you are checking your while against inputNumber.
while ( inputNumber != SENTINEL )
{
total += number;
System.out.print("Enter the next number or '-1' to finish. ");
inputNumber = scan.nextInt(); <<< not number should be inputNumber
}
public class NewClass1 {
public static void main(String[] args) {
int number;
Scanner scan = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scan.nextLine();
System.out.print("Please enter a number between 1 and 10: ");
number = scan.nextInt();
//asks for a number between one and ten until I get number within that range,
while (number < 1 || number > 10) {
System.out.print("No, between 1 and 10: ");
number = scan.nextInt();
}
for (int i = 1; i <= number; i++) {
if (i % 3 == 0) {
System.out.print(name + " ");
} else {
System.out.print(i + " ");
}
}
System.out.println();
for (int i = 2; i <= number; i += 2) {
System.out.print(i + " ");
}
System.out.print("are the even numbers.");
final int SENTINEL = -1;
int inputNumber;
int total = 0;
do {
System.out.println(" Enter a number or -1 to finish. ");
inputNumber = scan.nextInt();
if(inputNumber!= SENTINEL){
total+=inputNumber;
}
} while (inputNumber != SENTINEL);
System.out.println("The total is " + total);
}
}
The exercise asked me to calculate the average, maximum, and minimum. My code fulfills that purpose, however I need to include somewhere in my code that the exam grades entered by the user MUST be between 0 and 100. What is the best way to include this?
Here is my code.
import java.util.Scanner;
import java.io.*;
import java.text.DecimalFormat;
public class hw
{
public static void main ( String[] args )
{
int maxGrade = Integer.MIN_VALUE;
int minGrade = Integer.MAX_VALUE;
int count=0;
int total=0;
final int SENTINEL = -1;
int score;
Scanner scan = new Scanner( System.in);
System.out.println( "To calculate the class average, enter each test
score.");
System.out.println( "When you are finished, enter a -1.");
System.out.print( "Enter the first test score > ");
score = scan.nextInt();
while (score != SENTINEL )
{
total += score;
count ++;
if( score > maxGrade)
maxGrade = score;
if( score < minGrade)
minGrade = score;
System.out.print("Enter the next test score > ");
score = scan.nextInt();
}
if (count != 0)
{
DecimalFormat oneDecimalPlace = new DecimalFormat("0.0");
System.out.println( "\nThe class average is "
+ oneDecimalPlace.format( (double) (total) / count ));
System.out.println( "The minimum value is " + minGrade);
System.out.println( "The maximum value is " + maxGrade);
}
else
System.out.println("\nNo grades were entered");
}
}
Thank you!
Create a nested loop that will stop executing once the user has met the criteria. Something like this:
while (score < 0 || score > 100)
{
System.out.println("please enter a number between 0 and 100.");
while(!scan.hasNextInt())
{
scan.next();
}
score = scan.nextInt();
}
Note that this code has not been tested, this is just an idea of what it should look like.
So I've used System.out.print("Enter more test scores? (y/n): "); yet when I run it and all the scores are summarizes the user isn't given the chance to do it again here is my code. Do you guys think I may have put it in the wrong place.
public class TestScoreApp
{
public static void main(String[] args) {
// display operational messages
System.out.println("Please enter the number of test scores to be entered");
System.out.println("To end the program enter 999.");
System.out.println(); // print a blank line
int scoreTotal = 0;
int scoreCount = 0;
int testScore = 0;
int min = 100;
int max = 0;
int counter = 0;
int setNumber = 0;
String userAnswer = "n";
Scanner sc = new Scanner(System.in);
// get a series of test scores from the user
outerLoop:
do {
// user enters number of test scores to be entered
System.out.print("Enter the number of test scores to be entered: ");
setNumber = sc.nextInt();
if (setNumber > 0 && setNumber != 999)
{
while (setNumber > 0)
{
// user enters test scores
System.out.print("Enter score: ");
testScore = sc.nextInt();
// accumulate score count and score total
if (testScore <= 100)
{
scoreCount += 1;
scoreTotal += testScore;
setNumber --;
} //Added for Exercise 2-2, #4 modified if statement
else if (testScore > 100 || testScore < 0) {
System.out.println("Invalid entry, score not counted");
} else if (testScore == 999) {
System.out.println("Average test score complete");
}
if (testScore > max && testScore <= 100) {
max = testScore;
}
if (testScore < min && testScore >= 0) {
min = testScore;
}
if (setNumber == counter)
{
break outerLoop;
}
//End of test scores while loop
}
userAnswer = sc.next();
}
}// end of do loop
while(userAnswer.compareTo("y") == 0 );
System.out.print("Enter more test scores? (y/n): ");
// display the score count, score total, and average score
// Added casting from int ot double Exercise 3-2 #5
double averageScore = (double) scoreTotal / (double) scoreCount;
// Added number formatting ( 1 decimal place)
NumberFormat number = NumberFormat.getNumberInstance();
number.setMaximumFractionDigits(1);
String message = "\n"
+ "Score count: " + scoreCount + "\n"
+ "Score total: " + scoreTotal + "\n"
+ "Average score: " + averageScore + "\n"
//Added for Exercise 3-2 #4 add min/max
+ "Max score: " + max + "\n"
+ "Min score: " + min + "\n";
System.out.println(message);
}
}
I dont know what exactly you want to do, if you want to ask if the user want to add more scores after the default scores (that user set on beggining) so this is the answer:
import java.text.NumberFormat;
import java.util.Scanner;
public class TestScoreApp {
public static void main(String[] args) {
// display operational messages
System.out.println("Please enter the number of test scores to be entered");
System.out.println("To end the program enter 999.");
System.out.println(); // print a blank line
// declarations
int scoreTotal = 0;
int scoreCount = 0;
int testScore = 0;
int min = 100;
int max = 0;
int counter = 0;
int setNumber = 0;
String userAnswer = "n";
Scanner sc = new Scanner(System.in);
// get a series of test scores from the user
// outerLoop:
// do {
// user enters number of test scores to be entered
System.out.print("Enter the number of test scores to be entered: ");
setNumber = sc.nextInt();
if (setNumber > 0 && setNumber != 999) {
do { // put the loop condition below
// user enters test scores
System.out.print("Enter score: ");
testScore = sc.nextInt();
// accumulate score count and score total
if (testScore <= 100) {
scoreCount += 1;
scoreTotal += testScore;
setNumber--;
} // Added for Exercise 2-2, #4 modified if statement
else if (testScore > 100 || testScore < 0) {
System.out.println("Invalid entry, score not counted");
} else if (testScore == 999) {
System.out.println("Average test score complete");
}
if (testScore > max && testScore <= 100) {
max = testScore;
}
if (testScore < min && testScore >= 0) {
min = testScore;
}
// if (setNumber == counter) {
// break outerLoop;
// }
if (setNumber == counter) { // test if the counter reached zero
System.out.print("Enter more test scores? (y/n): "); // ask if the user want to add more
userAnswer = new Scanner(System.in).next(); // read the input
if (userAnswer.toCharArray()[0] == 'y') { // if yes, do
setNumber += 1; // add +1 to setNumber, so user can add more one score
}
}
} while (setNumber > 0);
}
// display the score count, score total, and average score
// Added casting from int ot double Exercise 3-2 #5
double averageScore = (double) scoreTotal / (double) scoreCount;
// Added number formatting ( 1 decimal place)
NumberFormat number = NumberFormat.getNumberInstance();
number.setMaximumFractionDigits(1);
String message = "\n" + "Score count: " + scoreCount + "\n"
+ "Score total: " + scoreTotal + "\n" + "Average score: "
+ averageScore + "\n"
// Added for Exercise 3-2 #4 add min/max
+ "Max score: " + max + "\n" + "Min score: " + min + "\n";
System.out.println(message);
}
}
There are several modifications to be done in the program.
When you are asking user to enter the choice for inputting more, you should accept his/her choice in your userAnswer variable before closing off the do-while loop SO THAT THE USER CHOICE CAN BE CHECKED AFTER EACH ITERATION!
There is no need to break the OUTER-LOOP without checking user's input!
scoreCount & scoreTotal need to be initialised with 0 again in the beginning of the do-while loop.
The corrected program along with the imports needed :-
import java.text.NumberFormat;
import java.util.Scanner;
public class JavaApplication7 {
public static void main(String[] args) {
System.out.println("Please enter the number of test scores to be entered");
System.out.println("To end the program enter 999.");
System.out.println(); // print a blank line
int scoreCount = 0,scoreTotal = 0;
int testScore = 0;
int min = 100;
int max = 0;
int counter = 0;
int setNumber = 0;
String userAnswer = "n";
Scanner sc = new Scanner(System.in);
// get a series of test scores from the user
do {
// user enters number of test scores to be entered
System.out.print("Enter the number of test scores to be entered: ");
setNumber = sc.nextInt();
if (setNumber > 0 && setNumber != 999)
{
scoreCount=0;
scoreTotal=0;
while (setNumber > 0)
{
// user enters test scores
System.out.print("Enter score: ");
testScore = sc.nextInt();
if (testScore <= 100)
{
scoreCount += 1;
scoreTotal += testScore;
setNumber --;
} //Added for Exercise 2-2, #4 modified if statement
else if (testScore > 100 || testScore < 0) {
System.out.println("Invalid entry, score not counted");
} else if (testScore == 999) {
System.out.println("Average test score complete");
}
if (testScore > max && testScore <= 100) {
max = testScore;
}
if (testScore < min && testScore >= 0) {
min = testScore;
}
}
// display the score count, score total, and average score
// Added casting from int ot double Exercise 3-2 #5
double averageScore = (double) scoreTotal / (double) scoreCount;
// Added number formatting ( 1 decimal place)
NumberFormat number = NumberFormat.getNumberInstance();
number.setMaximumFractionDigits(1);
String message = "\n"
+ "Score count: " + scoreCount + "\n"
+ "Score total: " + scoreTotal + "\n"
+ "Average score: " + averageScore + "\n"
//Added for Exercise 3-2 #4 add min/max
+ "Max score: " + max + "\n"
+ "Min score: " + min + "\n";
System.out.println(message);
}
System.out.print("Enter more test scores? (y/n): ");
userAnswer=sc.next(); // Single Error----Only corrected piece of code.
}while(userAnswer.compareTo("y") == 0 );
// end of do loop
}
}
You are asking the user:
System.out.print("Enter more test scores? (y/n): ");
after you exit from the while loop. This won't work. Just put this line exactly before:
userAnswer = sc.next();
When i run my program and choose a number between 0 and 100, it prints my answer wrong.
Java console
----jGRASP exec: java TestScores
How many tests do you have? 3
Enter grade for Test 1: 80
Enter grade for Test 2: 80
Enter grade for Test 3: 80
The average is: 26.666666666666668The average is: 53.333333333333336The average is: 80.0
----jGRASP: operation complete.
import java.util.Scanner;
public class TestScores {
public static void main(String[] args)
{
int numTests = 0;
double[] grade = new double[numTests];
double totGrades = 0;
double average;
int check = 1;
Scanner keyboard = new Scanner(System.in);
System.out.print("How many tests do you have? ");
numTests = keyboard.nextInt();
grade = new double[(int) numTests];
for (int index = 0; index < grade.length; index++)
{
System.out.print("Enter grade for Test " + (index + 1) + ": ");
grade[index] = keyboard.nextDouble();
if (grade[index] < 0 || grade[index] > 100)
{
try
{
throw new InvalidTestScore();
}
catch (InvalidTestScore e)
{
e.printStackTrace();
}
break;
}
}
for (int index = 0; index < grade.length; index++) {
totGrades += grade[index];
average = totGrades / grade.length;
System.out.print("The average is: " + average);
}
}
}
public class InvalidTestScore extends Exception
{
public InvalidTestScore()
{
super(" Error: Enter a number between 0 and 100");
}
}
You print the average inside the loop that calculates the average.
Print it only outside the loop.
You should calculate sum in loop and then (after the loop) divide it by the number of elements.
I move the statement which calculates the sum from inside the loop to the outside, that works.
My new code is.
import java.util.Scanner;
public class TestScores
{
public static void main(String[]args)
{
int numTests = 0;
double[] grade = new double[numTests];
double totGrades = 0;
double average;
int check = 1;
Scanner keyboard = new Scanner(System.in);
System.out.print("How many tests do you have? ");
numTests = keyboard.nextInt();
grade = new double[(int) numTests];
for (int index = 0; index < grade.length; index++)
{
System.out.print("Enter grade for Test " + (index + 1) + ": ");
grade[index] = keyboard.nextDouble();
if (grade[index] < 0 || grade[index]> 100)
{
try
{
throw new InvalidTestScore();
}
catch (InvalidTestScore e)
{
e.printStackTrace();
}
break;
}
}
for (int index = 0; index < grade.length; index++)
{
totGrades += grade[index];
}
average = totGrades/grade.length;
System.out.print("The average is: " + average);
}
}
public class InvalidTestScore extends Exception
{
public InvalidTestScore()
{
super(" Error: Enter a number between 0 and 100");
}
}
You can close my post.