so I am trying to read and find the average of all these integers from a normal .txt file, this is how it looks:

Mary 60
Tom 70
Jack 80
John 90
Sue 100
Bob 95
Gary 85
Emily 75

I have the read part down, but something is wrong with either my while loop or my try block

This is my desired output: The average is 81.0

This is my actual output:

The average is 7.0 The average is 8.0 The average is 10.0 The average is 11.0 The average is 12.0 The average is 11.0 The average is 10.0 The average is 9.0

Can anybody find the error in my logic?

public class Average {//begin class

public static void main(String[] args) {//begin main
    // TODO Auto-generated method stub

    try {//begin try
        File datafile = new File("C:\\Users\\jglez\\Documents\\Data.txt");
        Scanner inputFile = new Scanner(datafile);
        while(inputFile.hasNext()) {
            String name = inputFile.next();
            int grade = inputFile.nextInt();
            double average = grade/8;

            System.out.println("The average is " + average);
        }//end while

    }//end try
    catch(Exception e) {//begin catch
        System.out.println("FileNotFoundException caught");
    }//end catch

}//end main
    }//end class

I tried placing

double average = grade/8; System.out.println("The average is " + average);

outside of my try while loop and before my try block because I think it should work logically like that, but I get the error "grade cannot be resolved to a variable" even though I declared it in my while loop, so I don't know what's the fix?

I appreciate any help, thanks!

5 Answers

-1
Abhijeet On

Many changes required. Following is the resulted try block. You can find comments inline

try {//begin try
        File datafile = new File("C:\\Users\\jglez\\Documents\\Data.txt");
        Scanner inputFile = new Scanner(datafile);
        double average=0; //Intializing average outside
        while(inputFile.hasNext()) {
            String name = inputFile.next();
            double grade = inputFile.nextDouble(); //Changed datatype to double
            average = average +  grade/8.0; //changed your average calculation


        }
        System.out.println("The average is " + average); //Printing average outside
2
AxelH On

Let see.

I tried placing [code] outside of my try while loop and before my try block because I think it should work logically like that, but I get the error "grade cannot be resolved to a variable" even though I declared it in my while loop, so I don't know what's the fix?

Well, grade is declare in the while loop so grade only exist in that block. Explaining why you can't access it outside.


Your math is wrong

double average = grade/8

In java, int / int will always give you a int, so you will loose the decimal value. You can correct that with grade / 8.0 because int / double gives a double.

double average = grade / 8.0

Note that an average should be the sum of all value divide by the amount of value so the loop should do two thing :

  • Sum every grade in a variable
  • Count the number of grade

Then you just need to divide the sum by the count to get the average

 int sum = 0, count = 0;

 Scanner inputFile = new Scanner(datafile);
 while(inputFile.hasNext()) {
      String name = inputFile.next();
      int grade = inputFile.nextInt();
      sum = sum + grade;
      count++;
 }//end while

 double average = 1.0 * sum / count;
-1
Community On

I think you are trying to divide each value with the count which is not appropriate instead you need to find sum of all elements and divide it by count and your code should change something as below:

public class Average {//begin class

public static void main(String[] args) {//begin main
    // TODO Auto-generated method stub

    try {//begin try
        double sum=0.0,grade =0.0;
        File datafile = new File("C:\\Users\\jglez\\Documents\\Data.txt");
        Scanner inputFile = new Scanner(datafile);
        while(inputFile.hasNext()) {
            String name = inputFile.next();
            grade = inputFile.nextInt();
            sum = sum+grade;


        }//end while
        System.out.println("The average is " + sum/8.0);
    }//end try
    catch(Exception e) {//begin catch
        System.out.println("FileNotFoundException caught");
    }//end catch

}//end main
    }

Hope this is helpful and try to include arithmetic exception catch clause for above logic.

0
Yaman Jain On

Considering files can have any number of records, it is better to count them rather than hard-coding as 8. Make sure integer summation does not overflow otherwise use BigInteger. Division of two ints will result in int result, you have to typecast it into float or double.

Changes to be made, declare countLines to count records in the file and sumOfGrades to hold summation of grades. Once file scan is complete, declare variable average and compute it using sumOfGrades/countLines with typecase to get the result.

try {//begin try
            File datafile = new File("C:\\Users\\jglez\\Documents\\Data.txt");
            Scanner inputFile = new Scanner(datafile);
            int sumOfGrades = 0;
            int countLines = 0; // to calculate number of lines file has.
            while(inputFile.hasNext()) {
                String name = inputFile.next();
                int grade = inputFile.nextInt();
                sumOfGrades += grade;
                ++countLines;
            }//end while
            double average = (double) sumOfGrades/countLines;
            System.out.println("The average is " + average);
        }//end try
        catch(Exception e) {//begin catch
            System.out.println("FileNotFoundException caught");
            e.printStackTrace();
        }//end catch
0
Stephen C On

so I don't know what's the fix?

I am not going to tell you the fix. It is more important that you understand what your answer is wrong ... so that you can learn from your mistakes.

So let's step back.

The formula for calculating an average of a set of numbers is:

average = total sum of all the numbers / number of items in the set.

(You should have learned this in high school maths, if not before!)

Now let us compare this with what you are doing in your code:

    int grade = inputFile.nextInt();
    double average = grade/8;
    System.out.println("The average is " + average);

What is wrong with that?

Problem #1:

You are not calculating the sum of all the numbers. The grade is the value you just read. Not the sum. (Summing means you need to add up the grades!)

Problem #2:

You are assuming that the number of items is 8:

  • If the file doesn't contain 8 items, that is not true.

  • When you are computing and outputting a running average (as you are currently doing), you should be dividing by the number of elements read so far.

Hint: count them.

Problem #3:

This problem is a bit more subtle.

Since grade is an integer and 8 is an integer, grade / 8 is an integer division. That means that the result is truncated. For example, 60 / 8 gives you 7 ... not 7.5.

If you want an accurate floating point result, you need one of the operands of the / operator to be a floating point value. For example

  int sum = 60;
  int count = 8;
  double average = sum / count;            // INCORRECT answer - `7.0`
  double average = ((double) sum) / count; // CORRECT answer   - `7.5`

If you understand the above 3 problems, you should be able to figure out how to solve them, and make your program work.