Computing Classes Averages

Problem Statement

There are four sessions of CS110 and CS201, each of which has a different number of students. Suppose all students take three exams. Someone has prepared a file that records the exam scores of all students. This file has a form as follows:

4
3
97.0  87.0  90.0
100.0 78.0  89.0
65.0  70.0  76.0
2
100.0 100.0 98.0
97.0  85.0  80.0
4
78.0  75.0  90.0
89.0  85.0  90.0
100.0 97.0  98.0
56.0  76.0  65.0
3
60.0  65.0  50.0
100.0 99.0  96.0
87.0  74.0  81.0
The first number 4 gives the number of classes in this file. For each class, it starts with an integer, giving the number of students in that class. Thus, the first class has 3 students, the second has 2, the third has 4 and the fourth has 3. Following the number of students, there are that number of lines each of which contains the three scores of a student.

Write a program that reads in a file of this form and computes the following information:

  1. the average of each student;
  2. the class average of each exam; and
  3. the grant average of the class.
Click here to download this data file.

Solution

! ----------------------------------------------------------
! This program computes the average of each student and the
! the average of the class.  The input file starts with an
! integer giving the number of classes.  For each class, the
! input starts with an integer giving the number of students
! of that class, followed that number of lines on each of
! which there are three scores.  This program reads in the
! scores and computes their average and also the class
! averages of each score and the grant average of the class.
! ----------------------------------------------------------

PROGRAM  ClassAverage
   IMPLICIT  NONE

   INTEGER :: NoClass              ! the no. of classes
   INTEGER :: NoStudent            ! the no. of students in each class
   INTEGER :: Class, Student       ! DO control variables
   REAL    :: Score1, Score2, Score3, Average
   REAL    :: Average1, Average2, Average3, GrantAverage

   READ(*,*)  NoClass              ! read in the # of classes
   DO Class = 1, NoClass           ! for each class, do the following
      READ(*,*)  NoStudent         !   the # of student in this class
      WRITE(*,*)
      WRITE(*,*) 'Class ', Class, ' has ', NoStudent, ' students'
      WRITE(*,*)
      Average1 = 0.0               !   initialize average variables
      Average2 = 0.0
      Average3 = 0.0
      DO Student = 1, NoStudent    !   for each student in this class
         READ(*,*)  Score1, Score2, Score3   ! read in his/her scores
         Average1 = Average1 + Score1        ! prepare for class average
         Average2 = Average2 + Score2
         Average3 = Average3 + Score3
         Average  = (Score1 + Score2 + Score3) / 3.0   ! average of this one
         WRITE(*,*)  Student, Score1, Score2, Score3, Average
      END DO
      WRITE(*,*)  '----------------------'
      Average1     = Average1 / NoStudent    ! class average of score1
      Average2     = Average2 / NoStudent    ! class average of score2
      Average3     = Average3 / NoStudent    ! class average of score3
      GrantAverage = (Average1 + Average2 + Average3) / 3.0
      WRITE(*,*) 'Class Average: ', Average1, Average2, Average3
      WRITE(*,*) 'Grant Average: ', GrantAverage
   END DO

END PROGRAM  ClassAverage
Click here to download this program.

Program Input and Output

The input shown above should produce the following output:
Class 1 has 3 students

1,  97.,  87.,  90.,  91.3333359
2,  100.,  78.,  89.,  89.
3,  65.,  70.,  76.,  70.3333359
----------------------
Class Average: 87.3333359,  78.3333359,  85.
Grant Average: 83.5555573

Class 2 has 2 students

1,  100.,  100.,  98.,  99.3333359
2,  97.,  85.,  80.,  87.3333359
----------------------
Class Average: 98.5,  92.5,  89.
Grant Average: 93.3333359

Class 3 has 4 students

1,  78.,  75.,  90.,  81.
2,  89.,  85.,  90.,  88.
3,  100.,  97.,  98.,  98.3333359
4,  56.,  76.,  65.,  65.6666641
----------------------
Class Average: 80.75,  83.25,  85.75
Grant Average: 83.25

Class 4 has 3 students

1,  60.,  65.,  50.,  58.3333321
2,  100.,  99.,  96.,  98.3333359
3,  87.,  74.,  81.,  80.6666641
----------------------
Class Average: 82.3333359,  79.3333359,  75.6666641
Grant Average: 79.1111145

Discussion

This is a relatively easy problem. Here is an analysis in case you need it.

Since for each class we need to compute the average of each student, the class average of each exam, and the grant average of the whole class, we might immediately come up the following scheme:

READ(*,*)  NoClass
DO Class = 1, NoClass
   compute various average for this class
   display exam averages and class the grant average
END DO
Thus, "compute various average for the class" becomes the job of the inner loop. This loop should read in the scores of each student and do some computation as follows:
READ(*,*)  NoStudent
DO Student = 1, NoStudent
   READ(*,*)  Score1, Score2, Score3
   compute the average of this student
   compute the exam averages
END DO
Now, the only trouble is how to compute the exam averages. In fact, this inner loop has no way to compute the exam averages directly; but, it could compute the sum of the scores of a particular exam. After this inner loop ends, the outer loop could divide the sum with the number of students to obtain the average. To accumulate these sums, we need to initialize variables. Thus, the result is:
Average1 = 0.0
Average2 = 0.0
Average3 = 0.0
DO Student = 1, NoStudent
   READ(*,*)  Score1, Score2, Score3
   Average1 = Average1 + Score1
   Average2 = Average2 + Score2
   Average3 = Average3 + Score3
   Average  = (Score1 + Score2 + Score3) / 3.0
   WRITE(*,*)  Student, Score1, Score2, Score3, Average
END DO
WRITE(*,*)  '----------------------'
Average1     = Average1 / NoStudent
Average2     = Average2 / NoStudent
Average3     = Average3 / NoStudent
GrantAverage = (Average1 + Average2 + Average3) / 3.0
In the above, Average1, Average2 and Average3 are for the exam averages. They must be initialized right before entering the inner DO-loop, since the exam averages are computed for each class. The actual average is computed right after the inner DO-loop by dividing Average1, Average2 and Average3 with the number of students NoStudents. Once we have the exam averages, the grant average is computed as the average of these exam averages.