So it's time to come back to the users of stackoverflow for help again on an assignment.
I'm supposed to fill an array with a size of 10 with doubles given from the user. The entered numbers are supposed to be grades so they have to be in the range of 0 - 100. Anything out of the range (more, less, or incorrect characters) are not saved to the array and the user is prompted to try again at the given index of the array. After either the array is filled to the max value or the user presses enter to skip, the program is supposed to return the grades entered in order and display the average.
public static final SIZE = 10;
Scanner userIn = new Scanner(System.in);
double[] grades = new double [SIZE];
int counter = 0;
int counterList = 1;
boolean exit = false;
String sTemp = "";
double gradeNum = 0;
double avrGrade = 0.0;
double sum = 0;
while((counter < SIZE) && (!exit)) {
System.out.println("Enter grade " + counterList +
", or press enter to quit.");
sTemp = userIn.nextLine();
counterList++;
if(sTemp.length() < 1) {
exit = true; //ending for loop
} else {
gradeNum = Double.parseDouble(sTemp);
grades[counter] = gradeNum;
counter++;
} //else statement
} //end of while loop
counterList = 1;
System.out.println("You entered " + counter + " grades total.");
for(int i = 0; i <= counter; i++) {
System.out.println("Your grade " + counterList + " is " + grades[i]);
counterList++;
}
for(int i = 0; i < grades.length; i++)
sum += grades[i];
System.out.println("The average grade is: " + sum / grades.length);
So I finished taking my user's input and calculating the average but I'm having trouble setting the range and not saving the invalid inputs. I also feel like once I started to struggle I got really sloppy and there might be stuff going on in there that's not needed. Let me know anything helps!
An example of what the program should output given different scenarios
You can trim down your code. There are variables that you don't require. Explanations after the code.
import java.util.Scanner;
public class GradeAvg {
private static final int SIZE = 10;
public static void main(String[] args) {
Scanner userIn = new Scanner(System.in);
double[] grades = new double [SIZE];
int counter = 0;
String sTemp = "";
double sum = 0;
while(counter < SIZE) {
System.out.println("Please enter grade " + (counter + 1) + ": ");
sTemp = userIn.nextLine();
if (sTemp.isEmpty()) {
break;
}
try {
grades[counter] = Double.parseDouble(sTemp);
}
catch (NumberFormatException xNumberFormat) {
System.out.println("That wasn't a valid percentage, I need a number between 0 - 100. Try again.");
continue;
}
if (grades[counter] < 0 || grades[counter] > 100) {
System.out.println("That wasn't a valid percentage, I need a number between 0 - 100. Try again.");
continue;
}
sum += grades[counter];
counter++;
} //end of while loop
for (int i = 0; i < counter; i++) {
System.out.println("grade " + (i + 1) + ": " + grades[i]);
}
System.out.println();
System.out.println("number of valid grades entered: " + counter);
System.out.println();
System.out.println("average: " + sum / counter);
}
}
After accepting the user input, first check if the user simply pressed <ENTER> without entering a value. I used method isEmpty(), of class java.lang.String, to do this check. If the user simply pressed <ENTER>, you need to exit the while loop. This is what break does. So no need for boolean variable exit.
Variable counter is all you need to both keep track of how many grades have been entered and which index of array grades needs to be assigned a value, so no need for variable counterList.
If an invalid value is entered, continue skips the rest of the while loop and starts a new loop iteration. Think of it as a sort of goto that jumps back to the statement:
while (counter < SIZE)
You can assign a value directly to an element in array grades so no need for variable gradeNum.
You can update variable sum inside the while loop so no need for the extra for loop in order to calculate the average. By the way, your calculation of the average is incorrect since you are dividing by the size of array grades and not by the actual number of grades that were entered. Adding up all the elements in array grades still gives you the correct sum since all elements of the array are implicitly initialized to 0 (zero).
I changed what the program displays on the screen so as to match your example of what the program should output given different scenarios.
Here is the output according to the sample you provided.
Please enter grade 1:
A
That wasn't a valid percentage, I need a number between 0 - 100. Try again.
Please enter grade 1:
100
Please enter grade 2:
Bob
That wasn't a valid percentage, I need a number between 0 - 100. Try again.
Please enter grade 2:
41.5
Please enter grade 3:
-7
That wasn't a valid percentage, I need a number between 0 - 100. Try again.
Please enter grade 3:
grade 1: 100.0
grade 2: 41.5
number of valid grades entered: 2
average: 70.75
I made some adjustments:
final int SIZE = 10;
Scanner userIn = new Scanner(System.in);
double[] grades = new double [SIZE];
int counter = 0;
String sTemp = "";
double gradeNum = 0;
double sum = 0;
while(counter < SIZE) {
boolean err = false;
System.out.println("Enter grade " + (counter + 1) +
", or press enter to quit.");
sTemp = userIn.nextLine();
try {
gradeNum = Double.parseDouble(sTemp);
} catch(NumberFormatException ex)
{
err = true;
}
if(sTemp.length() < 1) {
break; //ending the loop
} else if(gradeNum <= 100 && gradeNum >= 0 && !err)
{
grades[counter] = gradeNum;
counter++;
} else
{
System.out.println("That wasn't a valid percentage, I need a number between 0 - 100. Try again.");
}
} //end of while loop
userIn.close(); //closing the Scanner
System.out.println("You entered " + counter + " grades total.");
for(int i = 0; i < counter; i++) {
System.out.println("Your grade " + (i + 1)+ " is " + grades[i]);
}
for(int i = 0; i < counter; i++) {
sum += grades[i];
}
System.out.println("\nNumber of valid grades entered: " + counter + "\n");
System.out.println("The average grade is: " + sum / counter);
}
This seems to work, I made some corrections (like SIZE declaration, took out the println from the last loop, replaced exit with a break statement, ...). The most relevant changes are the input checks and the average grade calculation (I used counter instead of grades.length because it is always 10). The try/catch checks if the input string contains only numbers.
(sorry for bad english, just ask if something isn't clear)
Related
I need to create a loop where the user can input any amount of numbers between 1-4 and then I calculate the average. Typing 0 will end the program and calculate the average. Any value greater than 4 or less than 0 should not count and ask the user to input the value again. I'm stuck on the last part. I'm not sure if the while loop is the correct loop to use either. Thanks for any help
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double sum = 0;
double count = 0;
while(input.hasNextInt()) {
int num = input.nextInt();
if (num == 0)
break;
if (num > 4)
System.out.println("Invalid number");
sum += num;
count += 1;
}
System.out.println("Average: " + sum/count);
}
You will always hit the lines:
sum += num;
count += 1;
Because the code just drops through from the second if statement.
The following would work - note the else if and else blocks will only be executed when the first if drops through:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double sum = 0;
double count = 0;
while(input.hasNextInt()) {
int num = input.nextInt();
if (num == 0) {
break;
}
else if (num > 4) {
System.out.println("Invalid number");
}
else {
sum += num;
count += 1;
}
}
System.out.println("Average: " + sum/count);
}
I have encountered some problems with the calculating of largest and smallest number... If the first number I entered is a larger number than the 2nd number input, it will not record the 1st number into the largest...
Take a look at the output, it will help elaborate better..
Calculation Error.. &
1st input problem..
Codes below!
public static void main(String[] args) {
int smallest = Integer.MAX_VALUE;
int largest = 0;
int number;
double totalAvg = 0;
double totalSum = 0;
int count = 0;
Scanner kb = new Scanner(System.in);
System.out.println("Enter few integers (Enter negative numbers to end input) :");
while (true) { //LOOP till user enter "-1"
number = kb.nextInt();
//Condition for the loop to break
if (number <= -1) {
System.out.println("End Of Input");
break;
} else {
count = count + 1;
}
if (number < smallest) { //Problem 1 : If 1st input num is bigger than 2nd input num,
smallest = number; // largest num will not be recorded..
} else {
largest = number;
}
totalSum = totalSum + number;
totalAvg = (totalSum / count);
}
System.out.println("The smallest number you have entered is : " + smallest);
System.out.println("The largest number you have entered is : " + largest);
System.out.println("The total sum is : " + totalSum);
System.out.println("The total average is : " + totalAvg);
System.out.println("Count : " + count);
} // PSVM
You could build an IntStream if you are using Java 8, and extract those numbers automatically using IntSummaryStatistics. You can find the official documentation from Oracle here.
Here is the code to achieve that:
List<Integer> input = new ArrayList<>();
while (true) { // LOOP till user enter "-1"
number = kb.nextInt();
// Condition for the loop to break
if (number <= -1) {
System.out.println("End Of Input");
break;
} else {
input.add(number);
}
}
IntSummaryStatistics z = input.stream() // gives Stream<Integer>
.mapToInt(Integer::intValue) // gives IntStream
.summaryStatistics(); // gives you the IntSummaryStatistics
System.out.println(z);
If you input 8 3 7 the output will be:
IntSummaryStatistics{count=3, sum=18, min=3, average=6.000000, max=8}
I hope it helps!
Do it like this:
public static void main(String[] args) {
int smallest = Integer.MAX_VALUE;
int largest = 0;
int number;
double totalAvg = 0;
double totalSum = 0;
int count = 0;
Scanner kb = new Scanner(System.in);
System.out.println("Enter few integers (Enter negative numbers to end input) :");
while (true) { //LOOP till user enter "-1"
number = kb.nextInt();
//Condition for the loop to break
if (number <= -1) {
System.out.println("End Of Input");
break;
} else {
count = count + 1;
}
if (number < smallest) { //Problem 1 : If 1st input num is bigger than 2nd input num,
smallest = number; // largest num will not be recorded..
}
//REMOVED ELSE ADDED another IF
if (number > largest){
largest = number;
}
totalSum = totalSum + number;
totalAvg = (totalSum / count);
}
System.out.println("The smallest number you have entered is : " + smallest);
System.out.println("The largest number you have entered is : " + largest);
System.out.println("The total sum is : " + totalSum);
System.out.println("The total average is : " + totalAvg);
System.out.println("Count : " + count);
} // PSVM
The problem is your if statement, as the logic is flawed. If the input number is smaller than smallest, then you update the smallest number. So far all is correct. The problem occurs, because you update largest in the else part. This means, if a number is not the smallest, largest is overwritten. But if the number is greater than the smallest, it is not automatically the largest. The right way to do this, is to check if the number is larger than the largest in a new if statement and update largest only in this case.
My program for some reason is calculating the GPA average wrong. If I enter 4.0 three times, then it says the average GPA is 3.0 but should be 4.0. Can someone help me find the issue?
//variables
double gpa = 0;
double total = 0;
int counter = 0;
int counter2 = 0;
do
{
String gpaEntry = JOptionPane.showInputDialog("Please enter GPAs:");
gpa = Double.parseDouble(gpaEntry);
if (gpa >= 3.5)
counter2 ++;
total += gpa;
counter ++;
}
while (gpa != 0);
double average = (double) (total/counter);
JOptionPane.showMessageDialog(null, "The Average GPA is: " + average);
JOptionPane.showMessageDialog(null, "Number of students:" + counter2);
Let's walk through the code
gpa = 0
get user input (user enters '2')
now gpa = 2
total += 2
counter ++
while(gpa != 0) // nope, gpa is 2
loop back
get user input (user enters '0')
now gpa = 0
total += 0
counter ++ // oops!
while(gpa != 0) // yep, quit the loop
but it's too late, we already incremented counter, so our average calculation is wrong
What is wrong is that if a user enters 0, then it runs the program and then exits.
Try this code (Sorry, I do not have an editor at the moment so you might have to fix some small thing).
//variables
double gpa = 0;
double total = 0;
int counter = 0;
int counter2 = 0;
String gpaEntry = JOptionPane.showInputDialog("Please enter GPAs:");
gpa = Double.parseDouble(gpaEntry);
while (gpa != 0) {
if (gpa >= 3.5)
counter2 ++;
total += gpa;
counter ++;
gpaEntry = JOptionPane.showInputDialog("Please enter GPAs:");
gpa = Double.parseDouble(gpaEntry);
}
JOptionPane.showMessageDialog(null, "The Average GPA is: " + average);
JOptionPane.showMessageDialog(null, "Number of students:" + counter2);
Comment if you have any more questions.
So here is my code:
package e7;
import java.util.Scanner;
public class Q1 {
public static void main(String[] args)
{
double[] scores = new double[10];
double sum = 0.0D;
int count = 0;
Scanner sc = new Scanner(System.in);
do {
System.out.print("Enter a new score (-1 to end): ");
scores[count] = sc.nextDouble();
if (scores[count] >= 0.0D)
sum += scores[count];
}
while (scores[(count++)] >= 0.0D);
System.out.println("The total number of scores is: " + count );
double average = sum / (count - 1);
int numOfAbove = 0;
int numOfBelow = 0;
for (int i = 0; i < count - 1; i++) {
if (scores[i] >= average)
numOfAbove++;
else
numOfBelow++;
}
System.out.printf("Average is " + "%.2f\n",average);
System.out.println("Number of scores above or equal to the average " + numOfAbove);
System.out.println("Number of scores below the average " + numOfBelow);
}
}
How do make it display the correct number of scores calculated? If I input 2 numbers and then do the -1 one to end it keeps saying 3 scores. Should only be two. How do I fix this? Thanks
System.out.println("The total number of scores is: " + count );
You probably want:
System.out.println("The total number of scores is: " + (count - 1));
You could also change your loop from a do while to a while loop as follows,
while (true) {
System.out.print("Enter a new score (-1 to end): ");
double tempDouble = sc.nextDouble();
if (tempDouble >= 0.0D)
scores[count] = tempDouble;
sum += scores[count];
count++;
else
break;
}
That way as if your double input isn't correct it would break out of the while loop when the user entered -1. You might have to tweak it a bit for your use case.
I am creating a program that calculates users grades based on their input. All is good except that I need to deal with users inputting invalid entries.
Example: The user enters three exam scores on a single line (95 90 87 for example). If one of these scores is negative (95 90 -87) I need the program to NOT enter those three scores and assign a letter grade and instead prompt the user to re-enter the scores correctly.
Here is my code:
public class GradeCalculator {
public static void main(String[] args) {
int classSum = 0; // variable used to hold sum of entire classes exams
int classExams = 0; // variable used to hold number of exams taken by whole class
Scanner s = new Scanner(System.in);
System.out.println("Welcome to Gradecalculator!");
System.out.println("Please enter the number of students:");
int students = s.nextInt();
System.out.println("Please enter the number of exams:");
int exams = s.nextInt();
int i = 0;
int studentnumber = 1;
int sum = 0;
while (i < students) { // loop until it matches number of students entered above
i++;
sum = 0;
System.out.println("Enter student " + studentnumber++ + "'s name :");
String studentname = s.next();
System.out.println("Enter exam scores :");
int input = 0;
for (; input < exams; input++) {
int n = s.nextInt();
sum+=n;
if (n < 0) {
System.out.println("Invalid exam scores, reenter: "); //if one of the scores entered is negative, display message
}
}
double average = sum/exams; // assign letter grade based on average of exams
if (average <= 100 && average >= 90) {
System.out.println("Letter grade: A");
System.out.println(studentname + " gets 4 stars! ****");
} if (average <= 89 && average >= 80) {
System.out.println("Letter grade: B");
System.out.println(studentname + " gets 3 stars! ***");
} if (average <= 79 && average >= 70) {
System.out.println("Letter grade: C");
System.out.println(studentname + " gets 2 stars! **");
} if (average <= 69 && average >= 60) {
System.out.println("Letter grade: D");
System.out.println(studentname + " gets 1 star! *");
} if (average <= 59) {
System.out.println("Letter grade: F");
System.out.println(studentname + " gets 0 stars!");
}
classSum += sum; // add sum of this student's scores to the classSum
classExams += exams; // add exams taken by this student to amount of exams taken by whole class
}
int classAverage = classSum/classExams; // compute class average
System.out.println("Class statistics:");
System.out.println("\tAverage: " + classAverage);
}
}
Clearly I have this code in the wrong place:
if (n < 0) {
System.out.println("Invalid exam scores, reenter: "); //if one of the scores entered is negative, display message
}
}
Because this is the output I get when entering a negative score:
Enter exam scores :
70 70 -70
Invalid exam scores, reenter:
Letter grade: F
joe gets 0 stars!
As you can see, it still assigns a letter grade and stars and asks for the next student's name. I need it to instead ask to re-enter this student's scores. Can't figure out how to do that.
You can subtract one from the input inside that for loop so that it stays in that loop and other inputs aren't wiped out (and also make sure that the sum doesn't add those negative inputs)
int input = 0;
for (; input < exams; input++) {
int n = s.nextInt();
if (n>=0)
sum+=n;
else {
input--;
System.out.println("Invalid exam score entered, reenter: ");
}
}
EDIT: Use interactive input, which should be more user friendly.
You need to reset your loop counter to start the loop again:
// Delete first output and counter variable initialization before loop
for (int input = 1; input < exams; input++) {
System.out.println(String.format("Enter %d. exam score: ", input + 1));
int n = s.nextInt();
if (n < 0) {
System.out.println("Invalid value (must be positive)!");
input--; // Reenter last value
} else {
sum+=n; // Only use correct scores.
}
}