0

I have my code that will read in a a list of numbers in a file called "QuizScores.txt". However, in this file, certain numbers contain letters. I have told my program to simply ignore those instances and move onto the next number. My issue now if that my code is only reading one line at a time where I need it to look at the entire file, read it in, calculate the average, the maximum, and the minimum, and finally output that to a file called "QuizStats.txt". Any help with this would be greatly appreciated! Thanks!

QuizScores:

45
63
74g
34.7
75
4
8
15
16
23
42
67f
34
67

Code:

import java.io.*;

public class ScoreReader {


    public static void main(String[] args) {
        BufferedReader reader = null;

        try {
               String currentLine;

               reader = new BufferedReader(new FileReader("QuizScores.txt"));
               while ((currentLine = reader.readLine()) != null) {

                   int sum = 0;
                   String[] nums = currentLine.split("\\s+");
                   for (int i = 0; i < nums.length; i++) {
                       try{
                           double num = Integer.parseInt(nums[i]);
                           if (num != -1) {
                               sum += num;
                           }
                       } catch( NumberFormatException err )
                       {

                       }
                   }

                   System.out.println(sum);
               }
            } catch (IOException err) {
                err.printStackTrace();
            } 
            catch (NumberFormatException err) {}
            finally {
                try {
                   if (reader != null){
                       reader.close();
                   }
                }
                   catch (IOException err) {
                    err.printStackTrace();
                   }
            }
    }
}
7
  • 1
    what is the problem with reading one line at at time? Commented Apr 10, 2014 at 19:19
  • Don't you want double sum and double num = Double.parseDouble(nums[i]);? Commented Apr 10, 2014 at 19:21
  • Could I still calculate the average, max, and min even if the file is read in one line at a time? Because I couldn't get that to work and assumed that was my problem. Commented Apr 10, 2014 at 19:21
  • 3
    You can. add a counter variable to count the number of values you have, then divide the sum by that counter to get the average. add another two variables for the max and min - as you read in each value, compare it to the current max and min and update the max and min as necessary... Commented Apr 10, 2014 at 19:23
  • @ElliottFrisch Yeah, you're right, the code is still a work in progress. Thanks for catching that though. :) Commented Apr 10, 2014 at 19:24

4 Answers 4

2
double min = 0.0;
double max  = 0.0;
int count = 0;



sum += num;
count++;
if (num > max) {
    max = num;
}
if (num < min) {
    min = num;
}
double avg = (double) sum/count;

Then the avg, sum, min, and max are all known. I would probably take a different approach from the beginning, but the code above should work with your code. I have not run it though.

Sign up to request clarification or add additional context in comments.

2 Comments

Will this not still output the entire list of numbers if I try to print the avg/max/min to the command line?
Im a little confused by your question. You could print the average by System.out.println(String.valueOf(avg)); Follow this pattern for the other variables. Is this what you are asking??
1

Try this code

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ScoreReader {

    public static void main(String[] args) {
        BufferedReader reader = null;
        double average = 200.0;
        double min = Double.MAX_VALUE;
        double max = Double.MIN_VALUE;
        int n = 1;
        String currentLine;
        double c;
        try {
            reader = new BufferedReader(new FileReader("QuizScores.txt"));
            System.out.println("--Quiz Scores--");
            while ((currentLine = reader.readLine()) != null) {
                try {
                    c = Double.parseDouble(currentLine);
                } catch (Exception ex) {
                    continue;
                }
                max = max > c ? max : c;
                min = min < c ? min : c;
                average += (c - average) / n;
                n++;
                System.out.println(c);
            }
            System.out.println("--Summary--");
            System.out.println("Average: " + average);
            System.out.println("Minimum: " + min);
            System.out.println("Maximum: " + max);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Output

--Quiz Scores--
45.0
63.0
34.7
75.0
4.0
8.0
15.0
16.0
23.0
42.0
67.0
34.0
67.0
--Summary--
Average: 37.97692307692308
Minimum: 4.0
Maximum: 75.0

Is this what you are looking for?

Comments

1
 private class Statistics{

    public double min = -1;
    public double max;
    public double avg;
    public long sum;

    Statistics(List<Long> list){

        int count = 0;
        for (Long num : list) {
            sum += num;
            count++;

            if(min == -1) min= num;

            if (num > max) {
                max = num;
            }
            if (num < min) {
                min = num;
            }
        }

        this.avg = sum/(double)count;
    }

}

// USAGE

    Statistics statistics = new Statistics(Arrays.asList(1l, 2l, 3l, 4l));

    System.out.println(statistics.avg);
    System.out.println(statistics.min);
    System.out.println(statistics.max);
    System.out.println(statistics.sum);

Comments

0

Read line by line parsing only the numbers and put those into a list, then pass that list to a function such as:

 public static Float getAverage(ArrayList <Float> x)
 {
    Float sum = 0.0f;

    for (Float a : x )
        sum += a;

    return sum / x.size();
 }

3 Comments

Why should he do that? Keep the sum as you go, and count the numbers you've parsed....
That's fine too but he also wants to use the same data for other computations so he could hold it in one array, but it is really just a personal preference.
If the data set was small and the manipulation simple, separating the read and data cleaning from the computation would make the code a little more readable. With a data set that is small, such as this, that approach could be justified.

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.