/home/wpollock1/public_html/Java/AverageGPA.java

// AverageGPA.java - A program to read in a bunch of student records
// from a file, and print all student names who have a greater than
// average GPA.  The file format is:
//    count_of_records (int) <newline>
//    name (String) <tab> GPA (double) <newline>
//
// An ArrayList might be a better choice for this particular
// application, but I wanted to show array processing so I added a count
// of the records as the first line of the file.  The file name is
// passed as a command line argument to the program.
//
// Storing the data in a collection (array in this case) is required,
// since the data must be processed twice: once to compute the average; then
// after that, to print those with GPAs above average.  Without a collection,
// the data would need to be read in a second time.
//
// Written 2018 Wayne Pollock, Tampa FL USA.

import java.nio.file.Paths;
import java.util.*;

public class AverageGPA {
   public static void main ( String [] args ) {
      Scanner in;
      int numRecords = 0;
      double runningTotal = 0.0;

      // Filename should be a file in (or relative to) the current directory:
      if ( args.length != 1 ) {
         System.out.println( "\nUsage: java AverageGPA <name_of_datafile>"
            + "\n(example: java AverageGPA StudentRecords.txt)" );
         return;
      }

      try {  // Make a Scanner from the filename:
         in = new Scanner( Paths.get(args[0]) );
         numRecords = in.nextInt();
         in.nextLine();  // Throw away the newline
         // Use tabs and newlines as field delimiters for rest of file:
         in.useDelimiter( "[\\t\\r\\n]" );
      }
      catch ( Exception e ) {
         System.err.println( "\n*** Could not read number of records from file"
            + " (the first line).\n" + e.toString() );
         return;
      }

      if ( numRecords < 1 ) {
         System.err.println(
            "\n*** Number of records in file is less than 1!\n" );
         return;
      }

      Student[] student = new Student[numRecords];

      for ( int i = 0; i < numRecords; ++i ) {
         try {
            String name = in.next();  // Read up to a tab
            double GPA = in.nextDouble();
            in.nextLine();  // Skip over the newline

            student[i] = new Student( name, GPA );
            runningTotal += GPA;
         }
         catch ( InputMismatchException ime ) {
            System.err.println( "Error: Badly formatted input data" );
            return;  // TODO probably should continue, to just skip bad data.
         }
      }

      // Compute the average:
      double average = runningTotal / numRecords;

      // Display a title for the output table:
      System.out.printf( "\n       GPA greater than %4.2f:\n", average );

      for ( final Student s : student ) {
         if ( s.getGPA() > average ) {
            System.out.println( "\t" + s.toString() );
         }
      }
      // TODO: check for zero students > average, and display message if none.
      // (That can only happen if all the students have the same GPA.)
   }
}  // End of class AverageGPA

// This is a trivial class Student, containing only a name and GPA:
class Student {
   private final String name;
   private final double GPA;

   public Student ( String name, double GPA ) {
      this.name = name;
      this.GPA = GPA;
   }

   public String getName () {
      return name;
   }

   public double getGPA () {
      return GPA;
   }

   // Format a student record nicely:
   public String toString () {
      return "Name: " + name + "\tGPA: " + String.format( "%4.2f", GPA );
   }
}