1

How can I keep prompting the error message until a valid grade has been entered? Right now, I'm only prompted 4 times then the average is displayed.

Also, how would I calculate the average of only the three highest grades?

  final int MAX_NUM_GRADES = 4;
      double avg;
      double sum = 0;
      int count = 1;
      double[] examGrade = new double[MAX_NUM_GRADES];
      for (int i = 0; i < examGrade.length; i++) {
         try {
            examGrade[i] = Double.parseDouble(JOptionPane.showInputDialog("Enter Grade " + count + ":"));
            if (examGrade[i] < 0 || examGrade[i] > 100) {
               JOptionPane.showMessageDialog(null,"ERROR!.");           
            }
            else {
               count++;
               sum = sum + examGrade[i];                       
            }
         }
         catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null,"ERROR!");         
         }      
      }
      avg = sum/examGrade.length;
      JOptionPane.showMessageDialog(null,"average exam grade is: " 
         + String.format("%.1f",avg)); 
1
  • Use a do-while or a while-do loop instead of a for loop; the termination condition would be eventually "when a valid grade is entered". Notice although you can use something similar with a for loop but the semantics might look "odd" Commented Jun 16, 2015 at 17:46

4 Answers 4

1

Change your code to this:

  final int MAX_NUM_GRADES = 4;
  double avg;
  double sum = 0;
  double min = Double.MAX_VALUE;
  int count = 1;
  double[] examGrade = new double[MAX_NUM_GRADES];
  for (int i = 0; i < examGrade.length; i++) {
     boolean invalid = true;
     while(invalid) {
     try {
        examGrade[i] = Double.parseDouble(JOptionPane.showInputDialog("Enter Grade " + count + ":"));
        if (examGrade[i] < 0 || examGrade[i] > 100) {
           JOptionPane.showMessageDialog(null,"ERROR!.");           
        }
        else {
           invalid = false;
           count++;
           sum = sum + examGrade[i];
           if(examGrade[i] < min) min = examGrade[i]; 
        }
     }
     catch (NumberFormatException e) {
        JOptionPane.showMessageDialog(null,"ERROR!");         
     }
     }      
  }
  avg = (sum - min)/(examGrade.length - 1);
  JOptionPane.showMessageDialog(null,"average exam grade is: " 
     + String.format("%.1f",avg));
Sign up to request clarification or add additional context in comments.

2 Comments

Why does double min = Integer.MAX_VALUE?
Changed it to Double.MAX_VALUE. It is initialized with the highest value so it can be used to calculate minimum. Initializing it with any other value would affect minimum calculation.
1

I would recommend putting it in a loop. Below is a psudo-code example.

for(int I = 0; I < examGrade.length; I++) {
    invalid = true;
     while(invalid) {
        //Accept the input, set invalid = false if it is correct
    }
}

Comments

1

you need a while or a do while loop , you keep looping till the input is valid

final int MAX_NUM_GRADES = 4;
  double avg;
  double sum = 0;
  int count = 1;
  double[] examGrade = new double[MAX_NUM_GRADES];
  boolean valid; // this is true when the input is valid
  for (int i = 0; i < examGrade.length; i++) {
     valid=false;// initialize valid
     try {
        do{
        examGrade[i] = Double.parseDouble(JOptionPane.showInputDialog("Enter Grade " + count + ":"));
        if (examGrade[i] < 0 || examGrade[i] > 100) {
           JOptionPane.showMessageDialog(null,"ERROR!.");
           valid=false;//in this case input is not valid           
        }
        else {
           count++;
           sum = sum + examGrade[i];
           valid=true;// input is valid                       
        }
       }while(!valid)//keep looping while valid is false
     }
     catch (NumberFormatException e) {
        JOptionPane.showMessageDialog(null,"ERROR!");         
     }      
  }
  avg = sum/examGrade.length;
  JOptionPane.showMessageDialog(null,"average exam grade is: " 
     + String.format("%.1f",avg)); 

now to calculate average of 3 highest grades you need to sort the array , then pick the last 3 grades , you can use any sorting algorithm , for example:

int tmp;
for(int i=0;i<examGrade.length;i++){
  for(int j=i;j<examGrade.length;j++{
  if(examGrade[j]<examGrade[i]){
    tmp=examGrade[j];
    examGrade[j]=examGrade[i];
    examGrade[i]=tmp;
   }
  }
  //now that its sorted you can calculate the average of highest scores
   float avg=0;
   for(int i=1;i<examGrade.length;i++){
     avg+=examGrade[i];
    }
   avg=avg/3;

1 Comment

You can avoid sorting by using a smarter data structure, fyi
1

This is because your for loop is iterating thru only the length of your examGrade array, which is set to 4 at the start of your program with MAX_NUM_GRADES.

Instead, you could try keeping track of valid answers and only calculate once 3 valid grades have been answered using a while-loop. The TreeSet used below automagically sorts the values inputted into the set, so sorting is done for you.

Like so:

TreeSet<Double> grades = new TreeSet<Double>();
final int MAX_NUM_GRADES = 4;
double avg;
double sum = 0;
double temp = 0d;

while(grades.size() < MAX_NUM_GRADES){
     temp = Double.parseDouble(JOptionPane.showInputDialog("Enter Grade " + count + ":"));
     if (examGrade[i] < 0 || examGrade[i] > 100) {
         JOptionPane.showMessageDialog(null,"ERROR!.");           
     } else {
         grades.add(temp);                   
     }
}
for (Double val : grades) {
    sum += val;
}
avg = sum/grades.size();
  JOptionPane.showMessageDialog(null,"average exam grade is: " 
     + String.format("%.1f",avg)); 

Just add the try-catch blocks where you would like them.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.