PROGRAM Average_Corn_Yields
!-----------------------------------------------------------------------
! Program to find the average yield for each of several hybrids of
! corn, using data consisting of a hybrid code and yield obtained from
! tests of these hybrids on several test plots.  Identifiers used are:
!     FileName   : name of data file containing the corn-yield data
!     NumHybrids : number of hybrids being tested
!     Count      : Count(I) = number of tests of hybrid I
!     TotalYield : TotalYield(I) = sum of yields for hybrid I
!     Hybrid     : current hybrid code
!     Yield      : current yield being processed!
!     I          : subscript
! Input:  Pairs of hybrid codes and yields (stored in Hybrid and Yield)
! Output: For each hybrid, the average yield or a message that no test
!         results were reported for that particular hybrid
!-----------------------------------------------------------------------

  IMPLICIT NONE
  CHARACTER(10) :: FileName
  INTEGER, DIMENSION(:), ALLOCATABLE :: Count
  INTEGER :: NumHybrids, Hybrid, I
  REAL, DIMENSION(:), ALLOCATABLE :: TotalYield
  REAL :: Yield

  ! Get the name of the file containing the corn-yield data
  ! and open it for input

  PRINT *, "This program reads pairs of hybrid codes and yields "
  PRINT *, "from a data file.  The first line of the file contains"
  PRINT *, "the number of hybrids.  Each subsequent line contains"
  PRINT *, "a hybrid code and a yield.  The last line of the file"
  PRINT *, "contains the pair 0, 0 to signal the end of data."
  WRITE (*, '(/ 1X, A)', ADVANCE = "NO") &
        "Enter the name of the data file to be used: "
  READ *, FileName
  OPEN (UNIT = 10, FILE = FileName, STATUS = "OLD")

  ! Read number of hybrids from the first line of the file, 
  ! allocate memory for arrays Count and TotalYield
  READ (10, *) NumHybrids
  ALLOCATE(Count(NumHybrids), TotalYield(NumHybrids))

  ! Zero out the arrays Count and TotalYield.
  ! Note:  As described in Section 8.4, this could be done more
  !        simply by:    Count = 0   and   TotalYield = 0.0

  DO I = 1, NumHybrids
     Count(I) = 0
     TotalYield(I) = 0.0
  END DO

  ! While there is more data, read a hybrid code and yield,
  ! increment the appropriate counter, and add the yield to the
  ! appropriate sum

  DO
     READ (10, *) Hybrid, Yield
     IF (Hybrid <= 0) EXIT     ! End of data, terminate repetition

     ! Otherwise process the corn-yield data
     IF (Hybrid < NumHybrids) THEN
        Count(Hybrid) = Count(Hybrid) + 1
        TotalYield(Hybrid) = TotalYield(Hybrid) + Yield
     ELSE
        PRINT *, "*** Illegal hybrid code:", Hybrid
     END IF
  END DO

  ! Calculate and print average yields

  PRINT '(//1X, "For hybrid")'
  DO Hybrid = 1, NumHybrids
     IF (Count(Hybrid) > 0) THEN
        PRINT '(1X, I10, ":  Average yield is", F6.2)', &
               Hybrid, TotalYield(Hybrid) / REAL(Count(Hybrid))
     ELSE
        PRINT '(1X, I10, ":  There were no test results reported")', &
             Hybrid
     END IF
  END DO

  DEALLOCATE(Count, TotalYield)

END PROGRAM Average_Corn_Yields
