So I am attempting to write a program where you enter your grades, totals them up, averages, and then drops the lowest grade. This is what I have so far, however, when I try to run the program I receive the average of 92 when I enter the values 100,100,75.
The average should be printing as 100. What is wrong with the code?
Thanks in advance!
import java.util.Scanner;
public class l3_drop_lowest_slide36 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double grade;
int count;
double minGrade;
double sumGrade;
double average;
System.out.println("Begin entering grades below. When done, type -1.");
System.out.println();
count = 0;
sumGrade = 0;
grade = 0;
minGrade = 100;
while ( grade != -1 ) {
sumGrade += grade;
count++;
System.out.print("Grade: ");
grade = input.nextDouble();
}
if ( grade < minGrade ) {
minGrade = grade;
}
if ( grade == -1 ) {
sumGrade = sumGrade - minGrade;
count = count - 1;
average = (sumGrade / count);
System.out.print("Your average is: " +average);
}
}
}
You can do something like this:
while ( grade != -1 ) {
sumGrade += grade;
count++;
System.out.print("Grade: ");
grade = input.nextDouble();
if(grade < minGrade && grade != -1)
minGrade = grade;
}
sumGrade = sumGrade - minGrade;
count = count - 1;
average = (sumGrade / count);
System.out.print("Your average is: " +average);
This way you are dropping out the minimum grade.
You are reading grade = input.nextDouble(); first and then checking if it's -1. Your while loop runs 4 times and not 3. So, essentially your count is 4 and not 3. Your minimum grade is -1 (the last input value) and not 75. Fix that logic and you should be good.
Your
if ( grade < minGrade ) {
minGrade = grade;
}
should be inside your
while ( grade != -1 ) {
}
Because when you get -1, -1 < 100 and minGrade = -1.
sumGrade - minGrade = (100+100+75) - (-1) = 276
And when u divide 276/3 = 92.
Related
I have this program where the user inputs x amount of grades, then the program divides the sum of the grades by the number of inputs taken. It should also find the highest and lowest grades entered. When the user is finished, he/she types in -1 to end the program. However, I am having some issues with it.
The program adds -1 to the average which skews all my results.
I can't figure out how to calculate the minimum value in the list. It always counts -1 as the minimum value.
Here is the code below:
import java.util.Scanner;
public class Lab4_EnteringGrades
{
public static void main (String a[])
{
Scanner kb = new Scanner(System.in);
double average = 0;
double gradesSum = 0;
int grade = 0;
int numTests = 0;
int maxValue = 0;
int minValue = 0;
while (grade != -1)
{
gradesSum += grade;
numTests += 1;
average = gradesSum / numTests;
System.out.print("Enter a grade: ");
grade = kb.nextInt();
while ((grade < -1) || (grade > 100))
{
System.out.println("Invalid grade.");
System.out.print("Enter a grade: ");
grade = kb.nextInt();
}
if (grade > maxValue)
maxValue = grade;
if (grade < maxValue)
minValue = grade;
}
System.out.printf("\nTotal number of tests: %d", numTests);
System.out.printf("\nThe average is %.1f", average);
System.out.printf("\nThe max value is %d", maxValue);
System.out.printf("\nThe min value is %d", minValue);
}
}
I made few changes -
Initialization of minValue and maxValue , in your original code, minValue was -1 and grade could not be less than -1, hence you always saw minValue as -1.
In general, if you want min and max vales, it is better to initialize like I did here.
Moved the logic of calculating grade, average AFTER user has entered the grade in order not to mess up the average.
Your original code was:
if (grade < maxValue)
I changed this to be if (grade < minValue). I believe it was a typo.
import java.util.Scanner;
public class Lab4_EnteringGrades {
public static void main (String a[])
{
Scanner kb = new Scanner(System.in);
double average = 0;
double gradesSum = 0;
int grade = 0;
int numTests = 0;
int maxValue = Integer.MIN_VALUE;
int minValue = Integer.MAX_VALUE;
while (true)
{
System.out.print("Enter a grade: ");
grade = kb.nextInt();
while ((grade < -1) || (grade > 100))
{
System.out.println("Invalid grade.");
System.out.print("Enter a grade: ");
grade = kb.nextInt();
}
if (grade == -1) {
break;
}
gradesSum += grade;
numTests += 1;
average = gradesSum / numTests;
if (grade > maxValue)
maxValue = grade;
if (grade < minValue)
minValue = grade;
}
System.out.printf("\nTotal number of tests: %d", numTests);
System.out.printf("\nThe average is %.1f", average);
System.out.printf("\nThe max value is %d", maxValue);
System.out.printf("\nThe min value is %d", minValue);
} }
The problems are that
You do gradesSum += grade; before reading the first grade, when grade is still 0.
You do if (grade < maxValue) after the user has entered grade=-1;, thus always find that -1 is smaller.
You compare the grade to maxValue both for checking max and min
Since you initialize minValue=0, you won't ever find a smaller value (except -1), so you should initialize it to something larger
You can move all the code that processes the grade until after you've read it, and then break if the user enters -1:
import java.util.Scanner;
public class Lab4_EnteringGrades
{
public static void main (String a[])
{
Scanner kb = new Scanner(System.in);
double average = 0;
double gradesSum = 0;
int grade = 0;
int numTests = 0;
int maxValue = 0;
int minValue = 101;
while (true)
{
System.out.print("Enter a grade: ");
grade = kb.nextInt();
while ((grade < -1) || (grade > 100))
{
System.out.println("Invalid grade.");
System.out.print("Enter a grade: ");
grade = kb.nextInt();
}
// Stop if the user entered -1
if (grade == -1) break;
gradesSum += grade;
numTests += 1;
average = gradesSum / numTests;
if (grade > maxValue)
maxValue = grade;
if (grade < minValue)
minValue = grade;
}
System.out.printf("\nTotal number of tests: %d", numTests);
System.out.printf("\nThe average is %.1f", average);
System.out.printf("\nThe max value is %d", maxValue);
System.out.printf("\nThe min value is %d", minValue);
}
}
The while(true) { if(..) break; } is slightly awkward though. You can improve the code further by creating a separate function for reading input:
import java.util.Scanner;
public class Lab4_EnteringGrades
{
public static int readGrade(Scanner kb) {
System.out.print("Enter a grade: ");
int grade = kb.nextInt();
while ((grade < -1) || (grade > 100))
{
System.out.println("Invalid grade.");
System.out.print("Enter a grade: ");
grade = kb.nextInt();
}
return grade;
}
public static void main (String a[])
{
Scanner kb = new Scanner(System.in);
double average;
double gradesSum = 0;
int grade;
int numTests = 0;
int maxValue = Integer.MIN_VALUE;
int minValue = Integer.MAX_VALUE;
// Common idiom for reading a grade until it's -1
while ((grade = readGrade(kb)) != -1) {
gradesSum += grade;
numTests += 1;
if (grade > maxValue)
maxValue = grade;
if (grade < minValue)
minValue = grade;
}
// Consider handling the case of numTests == 0
average = gradesSum / numTests;
System.out.printf("\nTotal number of tests: %d", numTests);
System.out.printf("\nThe average is %.1f", average);
System.out.printf("\nThe max value is %d", maxValue);
System.out.printf("\nThe min value is %d", minValue);
}
}
enter image description hereI'm working on the convertToLetterGrade portion. I'd like to figure out how to pass my array into the string in order to output the minimum and maximum grade as a letter, the comments here are helpful, and I also need the gpa passed through in order to output a letter grade for that as well
public class WesternGPACalc {
public static void main(String[] args) {
//TODO:
//declare an array to hold the grades you earned in your classes
//feel free to use fake values
//declare at least 4 grades
//use a 0.0 - 4.0 scale...
//4.0 = A, 3.5 = A/B
//3.0 = B, 2.5 = B/C
//2.0 = C
//1.0 = D
//0.0 = F
//for example...
double[] grade = new double[4];
grade[0] = 4.00; // A
grade[1] = 2.50; // B/C
grade[2] = 2.00; // C
grade[3] = 1.00; // D
//TODO:
//use a method to print the min and max grades as letter grades
//printGradeStats(grade);
printGradeStats(grade);
//TODO:
//declare an array to hold the credits each class was worth
//the indices must match the grade[i] indices for the class
//for example...
int[] credit = new int[4];
credit[0] = 3;
credit[1] = 3;
credit[2] = 3;
credit[3] = 3;
//TODO:
//use a method to calculate and print the GPA as both
//a number and a letter grade
//pass both the credit and grade arrays to the method
//printGPA(grade, credit);
printGPA(grade, credit);
}
//TODO:
//Finish this method which will accept an array of grades
//and print the min and max letter grade
private static void printGradeStats(double[] grade){
//TODO:
//First determine the min and max letter grade...
double minGrade = 0;
double maxGrade = 0;
for(int i = 0; i < grade.length; i++) {
if(grade[i] < minGrade) {
minGrade = grade[i];
}
if(grade[i] > maxGrade) {
maxGrade = grade[i];
}
}
//TODO:
//convert the min and max grades to a letter grade...
//using your convertToLetterGrade(grade) method
//For example...
//String maxLetterGrade = convertToLetterGrade(maxGrade);
String maxLetterGrade = convertToLetterGrade(maxGrade);
String minLetterGrade = convertToLetterGrade(minGrade);
//TODO:
//Output them...
System.out.println("Max grade earned in a class was " + maxLetterGrade);
System.out.println("min grade earned in a class was " + minLetterGrade);
}
//TODO:
//Finish this method which will convert
//a grade on the 4.0 scale and return a letter grade
//Use the following scale...
//A = 4.0
//4.0 > A/B >= 3.5
//3.5 > B >= 3.0
//3.0 > B/C >= 2.5
//2.5 > C >= 2.0
//2.0 > D >= 1.0
//F < 1.0
private static String convertToLetterGrade(double grade){
String letterGrade = "F";
return letterGrade;
}
//TODO:
//Finish this method which will accept an array of grades and credits
//and print the cumulative GPA as a letter grade
private static void printGPA(double[] grade, int[] credit){
//Recall...GPA is just a weighted average...
//Cumulative GPA is the sum of all grade points -- grade[i] * credit[i]
//divided by the sum of all credits[i]
double sumCredits = 0;
//TODO:
//Calculate cumulative GPA
for (int n = 0; n < credit.length; n++) {
sumCredits += credit[n];
}
double gpa = ((grade[0] * credit[0]) + (grade[1] * credit[1]) + (grade[2] * credit[2]) + (grade[3] * credit[3])) / sumCredits;
//TODO:
//Output Cumulative GPA as both a number and a grade
System.out.println("Cumulative GPA " + gpa);
System.out.println("Cumulative GPA as a letter grade: ");
}
}
you can achieve it by using if-else block as following
private static String convertToLetterGrade(double grade){
String letterGrade="";
if(grade == 4.0){
letterGrade="A";
}else if(grade >=3.5 && grade < 4){
letterGrade="A/B";
}else if(grade >= 3.0 && grade < 3.5){
letterGrade="B";
}else if(grade >= 2.5 && grade < 3.0){
letterGrade="B/C";
}else if(grade >= 2.0 && grade < 2.5){
letterGrade="C";
}else if(grade >= 1.0 && grade < 2.0){
letterGrade="D";
}else if(grade < 1.0){
letterGrade="F";
}
return letterGrade;
}
I see you have an answer, but let me enhance the code a little bit.
When you are calculating the cumulative GPA, You hard code the summation. You can actually use the same loop you have used to get the sumCredits for that, and it is the correct way to do it (Otherwise you can only check/consider 4 elements/grades).
double gpa = 0.0;
for (int n = 0; n < credit.length; n++) {
gpa += grade[n] * credit[n];
sumCredits += credit[n];
}
gpa /= sumCredits;
One thing in Logic,
double minGrade = 5.0; // Or any max value, because you are going to find minimum values that this default one
double maxGrade = 0;
for(int i = 0; i < grade.length; i++) {
if(grade[i] < minGrade) {
// if you set `double minGrade = 0` this if never becode true since every grade is greater than `0`
minGrade = grade[i];
}
if(grade[i] > maxGrade) {
maxGrade = grade[i];
}
}
The first part of the exercise was to calculate the test score average. The next problem asked me to build off this problem and calculate the minimum and maximum. Can anyone help me? This is my code so far.
import java.util.Scanner;
import java.io.*;
import java.text.DecimalFormat;
public class hw
{
public static void main ( String[] args )
{
int maxGrade;
int minGrade;
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 ++;
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 ));
}
else
System.out.println("\nNo grades were entered");
}
}
in your while loop, you can compare the current score to the maximum and the minimum.
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();
}
You also need to set the max and min (when declaring them) to their "opposite" value:
int maxGrade = Integer.MIN_VALUE;
int minGrade = Integer.MAX_VALUE;
Basically, I have this program. It is not completed yet but the gist of it is that it is a grade book with user input grades for a number of students they enter. They also enter the number of grades. What I'm struggling with is how to get the program to read the numbers after the first one on the line. The numbers being read is under the name "scores". So I want it to read it as:
1 2 3 4 (it just would read 1 and 5 right now)
5 6 7 8 (I want it to read them all)
Here's my code if it helps:
import java.util.Scanner;
import java.text.DecimalFormat;
public class SeventhAssignment {
public static double scores[][];
public static void main(String[] args) {
DecimalFormat formatter = new DecimalFormat(".00");
Scanner input = new Scanner(System.in);
int students;
System.out.print("Enter number of students");
students = input.nextInt();
if (students <= 0) {
System.out.println("Both numbers must be positive");
System.exit(0);
}
int grades;
System.out.print("Enter number of grades");
grades = input.nextInt();
if (grades <= 0) {
System.out.println("Both numbers must be positive");
System.exit(0);
}
double[][] arr = new double[students][grades];
System.out.println("Enter " + students * grades + " grades: ");
int i;
int j;
for (i = 0; i < students; i++) {
for (j = 0; j < grades; j++) {
Scanner scores = new Scanner(System.in);
arr[i][j] = scores.nextInt();
}
for (i = 0; i < students; i++) {
for (j = 0; j < grades; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
public double getMinimum() {
double lowGrade = scores[0][0];
for (double studentGrades[] : scores) {
for (double grade : studentGrades) {
if (grade < lowGrade)
lowGrade = grade;
}
}
return lowGrade;
}
public double getMaximum() {
double highGrade = scores[0][0];
for (double studentGrades[] : scores) {
for (double grade : studentGrades) {// if grade is greater than
// higherGrade, assign to higher
// grade
if (grade > highGrade)
highGrade = grade;
}
}
return highGrade;// returtn higher grade
}
public static double getAverage(double setofGrades[]) {
double total = 0;// Initializing total
// sum of grade for one student
for (double grade : setofGrades)
total += grade;
// return average of grade
return (double) total / setofGrades.length;
}
public void outputGrades() {
System.out.println("The grades are:\n");
System.out.println(" ");// for alignment
for (double test = 0; test < scores[0].length; test++)
System.out.printf("Test %d", test + 1);
System.out.println("Average"); // student average column heading
for (double student = 0; student < scores.length; student++) {
System.out.printf("student %2d", student + 1);
for (double test : scores[(int) student])// output student grades
System.out.printf("%8d", test);
// call method getAverage to calculate students average grade
// pass row of grades as the argument to getAveerage
double average = getAverage(scores[(int) student]);
System.out.printf("%9.2f\n", average);
}
}
}
Thanks ahead for any help you guys can bring!
I have a java program that takes the scores of 4 players and computes each player's average score when -1 is inputted. At the end of the program I need to display the highest average score out of the 4 averages, however I cannot figure out how to do this, can you guys set me in the right direction? The program looks like this when it is run: (I have also attached my code) I cannot use anything but loops.
Player 1
Enter your score: 100
Enter your score: 90
Enter your score: 80
Enter your score: 70
Enter your score: -1 (when -1 is inputted, the average score is calculated)
Average Score = 85.00
Player 2
Enter your score: 90
Enter your score: 90
etc.
etc.
import java.util.Scanner;
public class BowlingScores
{
public static void main(String[]args)
{
double score = 0;
double totalScore = 0;
double count = 0;
Scanner input = new Scanner(System.in);
for (int player = 1; player <= 4; player++){
System.out.printf("\nPlayer %d\n", player);
do{
System.out.println("Enter Your Score: ");
totalScore = totalScore + score;
score = input.nextDouble();
count++;
} while (score != -1);
if (score == -1){
count--;
System.out.printf("Average Score = %.2f\n",totalScore/count);
count = 0;
score = 0;
totalScore = 0;
}
}
}
}
Just keep track of the highest average in another variable. Then in your score == -1 condition check to see if the current average is higher than the highest average, and if so make current the new highest. Then after your for loop you could print out the highest average.
You can add a copy of the highest at the top of your code like this double highest = 0 then in your for loop have a way to replace it if the current average is higher.
if(score > highest){
highest=score;
}
Then at the -1 you can either reset it to 0 or keep it going.
public static void main(String[] args) {
final List<Double> allAverages = new ArrayList<>();
double score = 0;
double totalScore = 0;
double avg = 0;
int count = -1;
Scanner input = new Scanner(System.in);
for (int player = 1; player <= 4; player++) {
System.out.printf("\nPlayer %d\n", player);
do {
System.out.println("Enter Your Score: ");
totalScore = totalScore + score;
score = input.nextDouble();
count++;
} while (score != -1);
avg = totalScore / count;
System.out.printf("Average Score = %.2f\n", avg);
allAverages.add(totalScore / count);
score = 0;
totalScore = 0;
count = -1;
}
System.out.println("The highest is : " + Collections.max(allAverages));
}
Here a list of the modifications I did to your code to get it working :
The variable count now start at -1, so there is no need to do count-- when we exit the loop.
I've added a List that keep a track of all the averages.
I've removed the validation if(count == -1) after the loop as the only way to exit the loop is to have count == -1 so we already know it is the actual value.
To retrieve the maximum of all averages, I use Collections.max(allAverages).
Take average of all 4 players and store into one array. Then check for the largest number in array.
double[] highest = new double[4];
for(int i=0; i<4; i++){
highest[i] = totalScore/count;
}
if(highest[0]>highest[1] && highest[0]>highest[2] && highest[0]>highest[3])
System.out.println("highest" + highest[0]);
else if(highest[1]>highest[0] && highest[1]>highest[2] && highest[0]>highest[3])
System.out.println("highest" + highest[1]);
else if(highest[2]>highest[0] && highest[2]>highest[1] && highest[0]>highest[3])
System.out.println("highest" + highest[2]);
else System.out.println("highest" + highest[3]);
public static void main(String[]args) {
double bestScore = 0;
int bestPlayer = 1;
Scanner input = new Scanner(System.in);
for (int player = 1; player <= 4; player++){
System.out.printf("\nPlayer %d\n", player);
int count = 0; // does not need to be double
double totalScore = 0;
do {
System.out.println("Enter Your Score: ");
double score = input.nextDouble();
if (score != -1) {
totalScore += score;
count++;
}
} while (score != -1);
double averageScore = totalScore / count;
if (averageScore > bestScore) {
bestScore = averageScore;
bestPlayer = player;
}
System.out.printf("Average Score = %.2f\n", averageScore);
}
System.out.printf("Best Average Score = %.2f, best player = %d\n", bestScore, bestPlayer);
}
Just keep a variable to record the top average score every time as in topAverage in my example below. The code is same as your's except I changed the variable names for my readability.
public static void main(String[] args) throws NumberFormatException,
IOException {
double currentScore = 0;
double totalScore = 0;
int numScores = 0;
double averageScore = 0;
double topAverage = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
for (int i = 0; i < 4; i++) {
do {
System.out.println("Enter Score");
currentScore = Double.parseDouble(br.readLine());
totalScore = totalScore + currentScore;
numScores += 1;
} while (currentScore != -1);
numScores-=1;
totalScore+=1;
averageScore = totalScore / numScores;
System.out.println("Average Score is " + averageScore);
if (topAverage < averageScore) {
topAverage = averageScore;
}
currentScore = 0;
totalScore = 0;
numScores = 0;
}
System.out.println("Top Average is " + topAverage);
}
Edit
#Andrei Nikolaenko posted the same answer before me, so consider that answer, I am adding this edit because I want to mention that my browser did not refresh on time to show me that the answer has already been posted.