C*****************************************************************
C                                                                *
C        ROLL MANAGER - VERSION 2                                *
C        EAST TENNESSEE STATE UNIVERSITY                         *
C        AUGUST 1, 1980                                          *
C        GORDON L. BAILES                                        *
C                                                                *
C*****************************************************************
      REAL*8 AG(15),SP2
      REAL SPACE,LINE(16),LIM(4)
      REAL TLINE(5),PLINE(10),DASH
      REAL T(5),P(10),AVG(15), TDATE(3),TTIME(3),TT(5),TP(10)
      REAL TPCT(5),PPCT(10)
      REAL*8 OPTION(21),ANS,YES,NO,CLASS(2),STAT(7)
C**********************************************************************
C                                                                     *
C        Real variables and arrays                                    *
C          T .......... test grades for an individual                 *
C          P .......... problem grades for an individual              *
C          TPCT ....... percentage of total grade allocated to        *
C                         each test                                   *
C          PPCT ....... percentage of total grade allocated to each   *
C                         problem                                     *
C          TDATE ...... current date as obtained from DATE function   *
C          TTIME ...... current time as obtained from TIME function   *
C          ANS ........ input variable for answer to various          *
C                         questions                                   *
C          CLASS ...... undergraduate(UNGRD) or graduate(GRAD)        *
C          STAT ....... credit, audit, noshow, incomplete,W,WP,WF     *
C          OPTION ..... list of functions performed by this           *
C                         program                                     *
C          LIM ........ lower limits for letter grades A,B,C, and D   *
C                 Other variables are primarily used for formatting   *
C                    temporary storage, or fixed values               *
C                                                                     *
C**********************************************************************
C
      INTEGER TPLG(6,15)  !TOTAL LETTER GRADES FOR EACH TEST/PROB
      INTEGER NAME(20), CNO(12), CNAME(10), Q(6)      , SEC(2) ,TTI
      INTEGER TTO,HT,HP
      INTEGER PNAME(10), NTEST,NPROB,INFO(10),STATUS(4),OFLAG,OUT
      INTEGER RPT(11),FILE,FIL(11),ZZ(10),NT,NP,KNT(15),GRADE(10)
      INTEGER BLANK,IT(5),IP(10),AUDIT,LK(10),ONE,F(50)
      INTEGER NTEMP(20),NINFO(10),NSTAT(4),END,PAGE
      INTEGER PROJ,PROG,JOB(4)   !PROJ #, PROG #, JOB #
      INTEGER PW(6),NPW(6),PRJ,NPJ,DOTS(10)
      INTEGER BITSET,HIBIT
C**********************************************************************
C                                                                     *
C        Integer variables and arrays:                                *
C          LK .......... counts of letter grades                      *
C          N ........... number of students on roll                   *
C          NT .......... number of tests recorded                     *
C          NP .......... number of problems recorded                  *
C          FIL ......... name of file containing the class roll       *
C          KNT ......... array of counts used in averaging            *
C          GRADE ....... array of letter grades                       *
C          TTI ......... keyboard for input                           *
C          TTO ......... terminal for output                          *
C          LP .......... printer(file) for output                     *
C          RPT ......... name of file holding printed report          *
C          FILE ........ unit number of FIL                           *
C          NAME ........ student name (20 letters maximum)            *
C          CNO ......... course number (24 letters maximum)           *
C          CNAME ....... course name (20 letters maximum)             *
C          Q ........... term name (12 characters maximum)            *
C          SEC ......... section number                               *
C          PNAME ....... professor's name (20 characters maximum)     *
C          NTEST ....... number of tests expected this term           *
C          NPROB ....... number of problems expected this term        *
C          OFLAG ....... switch to show if a roll-file is open        *
C          INFO ........ special information for a student            *
C          STATUS ...... (1)-graduate or undergraduate                *
C                        (2)-credit, audit, noshow,incomplete,W,WP,WF *
C                        (3)-(4)-indicator bits showing which tests   *
C                                and problems have been recorded      *
C          BITSET ...... function used to set a bit on or off         *
C          HIBIT ....... function used to find which is the high-     *
C                        order bit set to one in a given word         *
C          JOB ......... job number for this class                    *
C          PROJ ........ project number for this class                *
C          PROG ........ programmer number for this student           *
C          PRJ ......... individual project number                    *
C          PW .......... student password                             *
C          PAGE ........ page number for printed report               *
C          NMAX ........ maximum number of students a given class     *
C                        have enrolled                                *
C              Other variables and arrays used for fixed values,      *
C                counters, formatting, and temporary switches and     *
C                storage areas                                        *
C                                                                     *
C**********************************************************************
C
C
C==================================================================
C  FILE LAYOUT:  N2 records each 128 words long                   =
C-----------------------------------------------------------------=
C  RECORD       WORDS         CONTENTS WITH VARIABLE NAME         =
C  ------       -----         ---------------------------         =
C  5-NMAX        1-20         student name (20A1)   NAME          =
C               21-30         special information (10A2) INFO     =
C                31           graduate/undergraduate (I1) STATUS  =
C                32           credit/audit/W/I/etc. (I1) STATUS(2)=
C                33-34        codes for which tests/problems      =
C                             have been recorded (2I) STATUS(3&4) =
C                35-44        5 test grades (5F) T(1 - 5)         =
C                45-64        10 problem grades (10F) P(1 - 10)   =
C                 65          programmer number (I3)    PROG      =
C                 66          project number (I3)       PRJ       =
C                67-72        password  (6A1)           PW        =
C               73-128        unused                              =
C.................................................................=
C  N1=3         1-12          course number (10A2)     CNO        =
C               13-22         course name   (10A2)     CNAME      =
C               23-28         term name     (6A2)      Q          =
C               29-30         section       (2A2)      SEC        =
C               31-40         professor's name (10A2)  PNAME      =
C                 41          number tests to be given (I) NTEST  =
C                 42          number probs to be given (I) NPROB  =
C               43-72         percentage of grade allocated to    =
C                             tests(5F) and probs(10F) TPCT,PPCT  =
C                 73          number of students (I)   N          =
C                 74          number of tests already recorded NT =
C                 75          number of probs already recorded NP =
C                 76          project number (I3)  PROJ           =
C               77-80         job number  (4A2)    JOB            =
C                 81          max. possible enrollment (i) NMAX   =
C               82-128        unused                              =
C.................................................................=
C   N2=4         1-8          4 real limits - lower limits for    =
C                                    letter grades LIM(1)-LIM(4)  =
C                9-128        unused                              =
C.................................................................=
C   1-2          all          unused                              =
C==================================================================
C
C
      COMMON TDATE,TTIME,CNO,CNAME,SEC,Q,PNAME,NTEST,NPROB,NT,NP,
     1    LP,LINE,SPACE,HT,HP,DASH,PAGE,PROJ,JOB
      COMMON /CMN1/ TPCT,PPCT,TAVG,PAVG,AV
      DATA SP2/'        '/
      DATA HT,HP/'T','P'/
      DATA DASH,SPACE/'____','    '/
      DATA  OPTION /'CREATE','LABEL', 'ADD'   ,'DROP'  ,'STATUS',
     1 'TEST  ', 'PROB'  ,'CTEST'  ,'CPROB','DISPLAY',  'REPORT',
     2'SELRPT','NEXTFILE','HELP','STOP','INFO','CNAME','INIT',
     3 'PASSWORD','ACCT','CURVE'/
      DATA YES,NO /'YES','NO'/
      DATA NUMOPT /21/        ! 21 OPTIONS FROM WHICH TO CHOOSE
      DATA ZZ/10*'ZZ'/
      DATA GRADE/'A','B','C','D','F','I','Au','W','WP','WF'/
      DATA PAGE/0/
      DATA DOTS /10*'..'/
      DATA BLANK/'  '/
      DATA CLASS,STAT/'Ungrd','Grad','Credit','Audit','Noshow','Incomp',
     1 'W','W-pass','W-fail'/
      DATA INCOMP/'In'/
      DATA AUDIT/'Au'/
      DATA ONE /'1'/
      DATA END/'/'/
C
C**********************************************************************
C                                                                     *
C       Initialize variables, determine filename for printed          *
C         report and open that file.                                  *
C                                                                     *
C**********************************************************************
      CALL DATE(TDATE)
      CALL TIME(TTIME)
      CALL OPEN (7,'KB:',3,,'NC')
      WRITE(7,9)TDATE,TTIME
    9 FORMAT(/////// 'ETSU CLASS ROLL MANAGER ACTIVE -- DATE:',
     1 2A4,A1,' TIME:',3A4)
C DEVICE AND FILE NUMBERS FOLLOW
      FILE=2
      TTO=7
      N2=4                   !POSITION OF FINAL HEADER RECORD
      N1=3                     !RELATIVE POSITION OF HEADER RECORD
      TTI=7
      OFLAGS=0 ! NO OPEN FILES HERE
      WRITE(TTO,1)
    1 FORMAT('Enter name and extension for the report file ',
     1 'in the form XXXXXX.XXX  ')
      DO 12 J = 1,11
 12   RPT(J)=BLANK
      READ(TTI,2)(RPT(J),J=1,10)
    2 FORMAT(10A2)
      CALL OPEN (1,RPT,0,'NEW','CC',,,,,188)  !FILE FOR PRINTED REPORTS
      LP=1                    !DEVICE NUMBER FOR REPORT
C
C**************************************************************************
C                                                                         *
C          Ask for the function to be performed, analyze the response,    *
C            and branch to the proper routine.                            *
C                                                                         *
C**************************************************************************
    8 WRITE(TTO,3)
    3 FORMAT(//'Enter desired option - for a list of all options',
     1 ', type "HELP": ',$)
      READ(TTI,4)ANS
    4 FORMAT(A8)
C DETERMINE WHICH OPTION WAS SELECTED
      DO 5 I=1,NUMOPT
      IF(ANS.NE.OPTION(I))GO TO 5
      IF (I.GE.16 .AND. OFLAG.NE.1) GO TO 10
      IF(I.GE.13)GO TO 6    !DOES FILE HAVE TO BE OPEN?
      IF(I.EQ.1 .OR.OFLAG.EQ.1)GO TO 6  !YES - IS FILE OPEN?
   10 WRITE(TTO,7)ANS
    7 FORMAT('Option "',A8,'" must be preceded by "CREATE" or ',
     1 '"NEXTFILE"')
      GO TO 8
    6 GO TO(100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,
     1 1400,1500,1600,1700,1800,1900,2100,2200),I !GO TO PROPER ROUTINE
    5 CONTINUE
C
C************************************************************************
C                                                                       *
C         HELP - routine lists available functions                      *
C                                                                       *
C************************************************************************
 1400 WRITE(TTO,1401)
 1401 FORMAT(///'LIST OF OPTIONS'/'---- -- -------'/
     1 /'ACCT ........ change a student''s account number'
     2 /'ADD ......... add a new student to the class roll'
     3 /'CNAME ....... change a student''s name'
     4 /'CPROB ....... change a problem grade for 1 or more ',
     5                 'students'
     6 /'CREATE ...... create a new file for a class'
     7 /'CTEST ....... change a test grade for 1 or more students'
     8 /'CURVE ....... curve test or problem grade'
     9 /'DISPLAY ..... display the roll on the terminal'
     A /'DROP ........ drop a student from the roll'
     B /'HELP ........ display this list of functions'
     C /'INFO ........ change special information field'
     D /'INIT ........ initialize an old roll at start of a new term',
     E /'LABEL ....... change class description(title,number,etc.)'
     F /'NEXTFILE .... stop processing this roll and start ',
     G                 'processing another roll'
     H /'PROB ........ record a problem grade for entire class'
     I /'PASSWORD .... change a student''s password',
     J /'REPORT ...... print the roll in report file (for later '
     K                 ,'printing)'
     L /'SELRPT ...... print short reports for some or all students'
     M /'STATUS ...... modify the status(audit,grad,incomplete,etc.)'
     N /'STOP ........ terminate all processing'
     O /'TEST ........ record a test grade for each student in class')
      GO TO 8  ! ASK FOR NEXT OPTION
C
C**************************************************************************
C                                                                         *
C        INFO - change special information field for a student            *
C                or change the programmer number for that student         *
C                                                                         *
C**************************************************************************
 1600 WRITE(TTO,1601)
 1601 FORMAT(//'Change special information')
      DO 1603 I=1,NMAX
 1605 WRITE(TTO,1602)
 1602 FORMAT(/'Enter student number - type 0 to end this ',
     1 'function: ',$)
      READ(TTI,114)K
      IF(K.EQ.0)GO TO 610
      IF(K.GT.0 .AND. K.LE.N) GO TO 1604
      WRITE(TTO,405)K,N
      GO TO 1605
 1604 READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
 1608 WRITE(TTO,1606)NAME,INFO
 1606 FORMAT('Change information for ',20A1, ' from ',10A2,' to: ')
      READ(TTI,105)INFO
 1603 WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      GO TO 610
C
C***************************************************************
C                                                              *
C        CNAME - change individual student name                *
C                  and re-sort the file                        *
C                                                              *
C***************************************************************
 1700 MRTN=1
      WRITE(TTO,1701)
 1701 FORMAT(//'CHANGE STUDENT NAME AND SORT')
      DO 1703 I=1,NMAX
 1705 WRITE(TTO,1602)
      READ(TTI,114)K
      IF(K.EQ.0)GO TO 2000     !SORT ROUTINE
      IF(K.GT.0.AND.K.LE.N)GO TO 1702
      WRITE(TTO,405)K,N
      GO TO 1705
1702  READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      WRITE(TTO,1704)NAME
1704  FORMAT(/'Change name from ',20A1,' to: ',$)
1706  READ(TTI,1707)NAME
1707  FORMAT(20A1)
1703  WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      GO TO 2000   !CALL SORT ROUTINE
C
C****************************************************************
C                                                               *
C       STOP - terminate all processing and close all files     *
C                                                               *
C****************************************************************
 1500 WRITE(TTO,1501)
 1501 FORMAT(//'Type NO to halt the termination process ',
     1 '- otherwise, press RETURN')
      READ(TTI,4)   ANS
      IF(ANS.EQ.NO)GOTO 8
      WRITE(TTO,1503)RPT
 1503 FORMAT(//'PROGRAM TERMINATED DUE TO USER REQUEST'/
     1'TO PRINT REPORTS GENERATED BY THIS RUN, TYPE' /
     2'QUE LPm:ROLL=',11A2,1X,
     3'WHERE m DESIGNATES THE PRINTER TO BE USED.')
      CALL EXIT
C
C****************************************************************
C                                                               *
C       CREATE - this function closes any open roll-file and    *
C                creates a new file (for another class) -       *
C                information about the class such as course     *
C                name, professor's name, etc. is obtained       *
C                interactively through answers given by the     *
C                user to questions given by the program.        *
C                                                               *
C****************************************************************
C****************************************************************
  100 WRITE(TTO,101)
  101 FORMAT(///'''CREATE'' INITIALIZES NEW CLASS ROLL -- TO CONTINUE TY
     1PE ''YES''')
      READ(TTI,4)ANS
      IF(ANS.NE.YES)GOTO8     ! IF NOT GO TO NEXT OPTION
      IF(OFLAG.EQ.0) GO TO 102  ! IS A FILE ALREADY OPEN
      CALL CLOSE(FILE)
      WRITE(TTO,136)FIL
  136 FORMAT(/'FILE ',11A2,' CLOSED.')
  102 WRITE(TTO,103)
  103 FORMAT(///'Enter name of file for class roll'/10X,
     1'***CAUTION*** If the name specified is the name of an ',
     2'existing file'/T12,'the old file will be replaced by this one:'
     31X,$)
      DO 150 I=1,5
         TPCT(I) = 0.
  150 CONTINUE
      DO 151 I = 1,10
         PPCT(I) = 0.
  151 CONTINUE
      DO 137 J=1,11
 137  FIL(J)=BLANK
      READ(TTO,2)(FIL(J),J=1,10)
      WRITE(TTO,161)
  161 FORMAT(/'Enter maximum number of students for this class;'/
     1 5X,'Please leave room for anticipated additions. ',$)
      READ(TTI,114)NMAX
      N0=NMAX + 10     !Students + headers + cushion
      DEFINE FILE 2(N0,128,U,KEY)
       CALL OPEN(2,FIL,0,'NEW','NC',,'RAN',,,188,,16)
      OFLAG=1       ! FILE 2 NOW OPEN
      NT=0
C OPEN ROUTINE SHOULD REQUEST FILENAME FROM TERMINAL
C FILE IS RANDOM
      NP=0
      WRITE(TTO,104)
  104 FORMAT(///'After each prompt, enter the requested information'/
     1 'Course number (24 characters max)')
      READ(TTI,105)CNO
  105 FORMAT(12A2)
      WRITE(TTO,106)
  106 FORMAT('Course title (20 char max)')
      READ(TTI,105)CNAME
      WRITE(TTO,108)
  108 FORMAT('Term name (12 char max)')
      READ(TTI,105)Q
      WRITE(TTO,110)
  110 FORMAT('Section number (up to 4 chars)')
      READ(TTI,2)SEC
      WRITE(TTO,112)
  112 FORMAT('Instructor''s name (20 char max)')
      READ(TTI,105)PNAME
  117 WRITE(TTO,113)
  113 FORMAT('Probable number of tests and problems to be given ',
     1 'separated by a comma')
      READ(TTI,114)NTEST,NPROB
  114 FORMAT(2I6)
      IF(NTEST.GE.0.AND.NTEST.LE.5.AND.NPROB.GE.0.AND.NPROB.LE.10)GOTO
     1  120
      WRITE(TTO,116)
  116 FORMAT('Number of tests must be 1-5, number of problems 1-10'//)
      GOTO117
  120 WRITE(TTO,118)
  118 FORMAT('Probable percentage of total grade allocated to '/
     1 '     each test or problem (.000 to 1.000)')
  119 FORMAT(F8.0)
      WRITE(TTO,4)'TESTS   '
      DO 152 I = 1,NTEST
  155    WRITE(TTO,153)I
  153    FORMAT(I4,' -  ',$)
         READ(TTI,119)TPCT(I)
         IF(TPCT(I) .GE. 0. .AND. TPCT(I) .LE. 1) GO TO 152
            WRITE(TTO,154)
  154       FORMAT('***ERROR - TRY AGAIN***')
            GO TO 155
  152 CONTINUE
      WRITE(TTO,4)'PROBLEMS'
      DO 156 I = 1,NPROB
  157    WRITE(TTO,153)I
         READ(TTI,119)PPCT(I)
         IF(PPCT(I) .GE. 0. .AND. PPCT(I) .LE. 1.)GO TO 156
            WRITE(TTO,154)
            GO TO 157
  156 CONTINUE
      WRITE(TTO,134)
  134 FORMAT('Project number - use 0 if not used or unknown ',$)
      READ(TTI,114)PROJ
      WRITE(TTO,138)
  138 FORMAT('Job number (8 char or blanks) ',$)
      READ(TTI,105)JOB
      WRITE(TTO,121)NMAX
  121 FORMAT('Number of students to be on the roll 0-',I3)
      READ(TTI,114)N
      DO 125 I=1,5
  125 T(I)=0.       ! ZERO TEST GRADES
      DO 126 I=1,10
  126 P(I)=0.       ! ZERO PROB GRADES
      DO 127 I=1,4
  127 STATUS(I)=0   ! INITIALIZE STATUS
      DO 146 I=1,10
         INFO(I) = ' '
  146 CONTINUE
      WRITE(TTO,141)
  141 FORMAT('Are the names for the roll currently in some file ? ',$)
      READ(TTI,4)ANS
      IF(ANS .NE. YES) GO TO 142
      WRITE(TTO,143)
  143 FORMAT('Enter the name of the file containing the roll - ',$)
      CALL OPEN (9,,-20,'OLD')
      DO 144 I = 1,N
          READ(9,145,END=147)NAME,(INFO(J),J=1,6),PRJ,PROG,PW
  145     FORMAT(20A1,5A2,A1,I3,I4,2X,6A1)
          WRITE(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  144 CONTINUE
  147 CALL CLOSE(9)
      GO TO 133
  142 WRITE(TTO,123)N
  123 FORMAT(///'Type ',I3, ' names, special information, and status')
  132 FORMAT('Align first char of each entry under first char of ',
     1 'heading'/'Under status use 0 for undergraduate or 1 for ',
     2 'graduate'/T5,' followed by 0-credit, 1-audit, or 2-noshow'
     3 /'Default status is 00 (undergraduate,credit)')
      WRITE(TTO,132)
  124 FORMAT(T6,'NAME',T26,'SPECIAL INFORMATION',T46,'STATUS'/)
      WRITE(TTO,124)
      M1=0           !The next 6 lines start a random number gen.
      M2=0
      J1=N*(NTEST + NPROB)
      DO 140 I=1,J1
         CALL RANDU(M1,M2,X)
  140 CONTINUE
      DO 128 I=1,N
      WRITE(TTO,129)I
  129 FORMAT(I3,'.',1X,$)
      READ(TTI,130,END=133)NAME,INFO,STATUS(1),STATUS(2)
  130 FORMAT(20A1,10A2,2I1)
      PROG = I    !SET UP PROG # = ROLL NUMBER (IN ORDER ENTERED)
      CALL PSWORD(PW,M1,M2)
      PRJ=PROJ
      WRITE(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      IF(I/8*8 .EQ. I) WRITE(TTO,124)
  128 CONTINUE
  133 I=I-1
      WRITE(TTO,131)I
  131 FORMAT(I3,' Names on roll'/)
      N=I
      WRITE(FILE'N1)CNO,CNAME,Q,SEC,PNAME,NTEST,NPROB,TPCT,PPCT,N,NT,NP,
     1 PROJ,JOB,NMAX
      DO 158 I=1,4
          WRITE(TTO,159)GRADE(I)
  159     FORMAT('Specify lower limit for grade of ',A1,' - ',$)
          READ(TTI,160)LIM(I)
  160     FORMAT(F6.0)
  158 CONTINUE
      WRITE(FILE'N2)LIM
      MRTN=1
      GO TO 2000    !SORT ROUTINE
C
C***************************************************************
C                                                              *
C       NEXTFILE - this routine closes any roll-file open      *
C                  and terminates processing of that file      *
C                  - it then asks the user which roll-file     *
C                  should be processed next.                   *
C                                                              *
C***************************************************************
 1300 IF(OFLAG.NE.1)GOTO1301
      CALL CLOSE(2)           !CLOSE OPEN FILE
      WRITE(TTO,136)FIL
 1301 WRITE(TTO,1302)
 1302 FORMAT(///'Enter filename - file must already exist')
      DO 1303 J=1,11
1303  FIL(J)=BLANK
      READ(TTO,2)(FIL(J),J=1,10)
      DEFINE FILE 2(0,128,U,KEY)
      CALL OPEN(2,FIL,0,'OLD','NC',1,'RAN')
      OFLAG=1                 !FILE NOW OPEN
      READ(FILE'N1)CNO,CNAME,Q,SEC,PNAME,NTEST,NPROB,TPCT,PPCT,N,NT,NP,
     1 PROJ,JOB,NMAX
      GO TO 8
C
C***********************************************************
C                                                          *
C       LABEL - change a field in the course label         *
C               information(such as course name, section,  *
C               or professor's name)                       *
C                                                          *
C***********************************************************
  200 WRITE(TTO,201)
  201 FORMAT(//'Select from the following list the number of the '
     1                     ,'field you wish to change'
     2       / '------ ---- --- --------- ---- --- ------ -- --- ',
     3                      '----- --- ---- -- ------'/
     4  /' 1 - course number'
     5  /' 2 - course name'
     6  /' 3 - term name'
     7  /' 4 - section number'
     8  /' 5 - name of instructor'
     9  /' 6 - total number of tests to be given'
     A  /' 7 - total number of problems to be assigned'
     B  /' 8 - the percentage of the total grade allocated to ',
     C         'the tests and problems'
     D  /' 9 - project number'
     E  /'10 - job number'
     F  /'11 - lower limits for letter grades'
     G  /'12 - change number of recorded tests and problems'//)
      READ(TTI,114)I
      GOTO(210,220,230,240,250,260,270,280,290,295,275,265),I
      GO TO 8  ! IF INVALID ENTRY GO TO 8
  210 WRITE(TTO,105)CNO
      WRITE(TTO,211)
  211 FORMAT(T3,'Change to?')
      READ(TTI,105)CNO
  212 WRITE(FILE'N1)CNO,CNAME,Q,SEC,PNAME,NTEST,NPROB,TPCT,PPCT,N,NT,NP,
     1 PROJ,JOB,NMAX
      GO TO 610
 220  WRITE(TTO,105)CNAME
      WRITE(TTO,211)
      READ(TTI,105)CNAME
      GO TO 212
  230 WRITE(TTO,105)Q
      WRITE(TTO,211)
      READ(TTI,105)Q
      GO TO 212
  240 WRITE(TTO,2)SEC
      WRITE(TTO,211)
      READ(TTI,2)SEC
      GO TO 212
  250 WRITE(TTO,105)PNAME
      WRITE(TTO,211)
      READ(TTI,105)PNAME
      GO TO 212
  260 WRITE(TTO,114)NTEST
      WRITE(TTO,211)
      READ(TTI,114)NTEST
      GO TO 212
  265 WRITE(TTO,266)NT
  266 FORMAT('TESTS RECORDED - ',I2)
      WRITE(TTO,211)
      READ(TTI,114)NT
      WRITE(TTO,267)NP
  267 FORMAT('PROBLEMS RECORDED - ',I2)
      WRITE(TTO,211)
      READ(TTI,114)NP
      GO TO 212
  270 WRITE(TTO,114)NPROB
      WRITE(TTO,211)
      READ(TTI,114)NPROB
      GO TO 212
  275 DO 276 I = 1,4
          WRITE(TTO,159)GRADE(I)
          READ(TTI,160)LIM(I)
  276 CONTINUE
      WRITE(FILE'N2)LIM
      GO TO 610
  280 WRITE(TTO,4)'TESTS   '
      DO 281 I = 1,NTEST
  283    WRITE(TTO,282)I,TPCT(I)
  282    FORMAT(I4,' CHANGE ',F6.4,' TO ',$)
         READ(TTI,119)TPCT(I)
         IF(TPCT(I) .GE. 0. .AND. TPCT(I) .LE. 1.)GO TO 281
            WRITE(TTO,154)
            GO TO 283
  281 CONTINUE
      WRITE(TTO,4)'PROBLEMS'
      DO 284 I = 1,NPROB
  285    WRITE(TTO,282)I,PPCT(I)
         READ(TTI,119)PPCT(I)
         IF(PPCT(I) .GE. 0. .AND. PPCT(I) .LE. 1.)GO TO 284
            WRITE(TTO,154)
            GO TO 285
  284 CONTINUE
      GO TO 212
  290 WRITE(TTO,114)PROJ
      WRITE(TTO,211)
      READ(TTI,114)PROJ
      GO TO 212
  295 WRITE(TTO,2)JOB
      WRITE(TTO,211)
      READ(TTI,2)JOB
      GO TO 212
C
C*****************************************************************
C                                                                *
C      ADD - add a student to the roll                           *
C                                                                *
C*****************************************************************
  300 WRITE(TTO,301)
  301 FORMAT('Type name, special information, and status'/'Type "/*" ',
     1 'to stop adding')
      WRITE(TTO,132)
      WRITE(TTO,124)
      DO 302 I=1,5       !INITIALIZE TEST,PROBLEM GRADES AND STATUS
  302 T(I)=0.
      DO 303 I=1,4
  303 STATUS(I)=0
      DO 304 I=1,10
  304 P(I)=0.
      M1=0
      M2=0
      DO 305 I=1,NMAX
      WRITE(TTO,129)I
      READ(TTI,130)NAME,INFO,STATUS(1),STATUS(2)
      IF(NAME(1).EQ.END)GO TO 306
      N=N+1
      PROG = N     !ASSIGN PROGRAMMER NUMBER
      CALL PSWORD(PW,M1,M2)
      PRJ=PROJ
      IF(N.LE.NMAX)GO TO 307
      WRITE(TTO,308)
  308 FORMAT('***ROLL FULL***/FUNCTION ABORTED')
      N=N-1
      GO TO 8
  307 WRITE(FILE'N+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      IF (MOD(I,8) .EQ. 0) WRITE(TTO,124)
  305 CONTINUE
  306 WRITE(TTO,131)N
      MRTN=2
      GO TO 2000    !SORT ROUTINE
C
C******************************************************************
C                                                                 *
C        DROP - drop a student from the roll                      *
C                                                                 *
C******************************************************************
  400 WRITE(TTO,401)
  401 FORMAT(///'Type number of student to be dropped'/
     1 'Type 0 to end drop process')
      MRTN=3
      M1=0
      DO 402 I=1,NMAX
  403 READ(TTI,114)K
      IF(K.EQ.0) GO TO 2000
      IF(K.GT.0.AND.K.LE.N )GOTO 404
      WRITE(TTO,405)K,N
  405 FORMAT(I3,' is invalid-it must be 1-',I3)
      GO TO403
  404 READ(FILE'K+4)NAME
      WRITE(TTO,406)NAME
  406 FORMAT('Drop ',20A1,'? (YES or NO)')
      READ(TTI,4)ANS
      IF(ANS.NE.YES)GO TO 402
      M1=M1+1    !Number dropped
      WRITE(FILE'K+4)ZZ
      WRITE(TTO,407)NAME
  407 FORMAT(20A1,1X,'Dropped')
  402 WRITE(TTO,401)
  415 N=N-M1         !REDUCE SIZE OF ROLL
      WRITE(TTO,411)M1
  411 FORMAT(I3,' Students dropped')
      WRITE(TTO,131)N
      WRITE(FILE'N1)CNO,CNAME,Q,SEC,PNAME,NTEST,NPROB,TPCT,PPCT,N,NT,NP,
     1 PROJ,JOB,NMAX
      GO TO 610
C
C*********************************************************************
C                                                                    *
C          STATUS - alter the status of a student                    *
C                   Possible status values are:                      *
C                   Status 1 - undergraduate & graduate              *
C                   Status 2 - credit, audit, noshow, incomplete     *
C                              W, WP, WF                             *
C                                                                    *
C*********************************************************************
  500 WRITE(TTO,501)
  501 FORMAT(///'Status1=0-Undergraduate'/
     1          'Status1=1-Graduate'//
     2          'Status2=0-Credit'/
     3          'Status2=1-Audit'/
     4          'Status2=2-Noshow'/
     5          'Status2=3-Incomplete'/
     6          'Status2=4-Withdrew (W)'/
     7          'Status2=5-Withdrew passing (WP)'/
     8          'Status2=6-Withdrew failing (WF)'
     A///'Type 0 for student number to end function')
      DO 502 I=1,NMAX
      WRITE(TTO,503)
  503 FORMAT('Type student number ',$)
  505 READ(TTI,114  )K
      IF(K.EQ.0) GO TO 610
      IF(K.GT.0.AND.K.LE.N)GOTO504
      WRITE(TTO,405)K,N
      GO TO 505
  504 READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  507 WRITE(TTO,506)NAME,STATUS(1),STATUS(2)
  506 FORMAT('For ',20A1,1X,'Status1=',I1,' Status2=',I1/'Change which s
     1tatus (1 OR 2)?',$)
      READ(TTI,114)J
      IF(J.EQ.1 .OR. J.EQ.2)GOTO508
      WRITE(TTO,405)J,2
      GO TO 507
  508 WRITE(TTO,509)STATUS(J),J
  509 FORMAT('Old value(',I1,') of status',I1,1X,'change to:  ',$)
      M1=1
      IF(J .EQ. 2)M1=6
      READ(TTI,114)M
      IF(M.LE.M1)GO TO 511
      WRITE(TTO,405)M,M1
      GO TO 508
  511 STATUS(J)=M
      WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  502 CONTINUE
      GOTO8
C
C********************************************************************
C                                                                   *
C        TEST - record a test grade for all students in the         *
C               class -- it is assumed to be the first test         *
C               for which this function has not been carried out    *
C               For example, the first invocation of this function  *
C               is assumed to record the grade for the first test   *
C               and the second invocation records the grades for    *
C               the second test.  This function also updates the    *
C               counter for number of tests recorded.               *
C                                                                   *
C********************************************************************
  600 NT=NT+1
      IF(NT.LE.NTEST)GO TO601     !MORE THAN NTEST TESTS-ERROR
      WRITE(TTO,602)NTEST
  602 FORMAT(///'MAX OF ',I2,' TESTS ALREADY RECORDED')
      GOTO8
  601 WRITE(TTO,603)
  603 FORMAT(///'Test ',$)
      WRITE(TTO,604)NT
  604 FORMAT(I2,' - After each name, type grade'//)
      DO 605 I=1,N
      READ(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      IF(BITSET(STATUS(3),NT) .EQ. 1)GO TO 605 !ALREADY RECORDED?
      CALL SETBIT(STATUS(3),NT,1)
      WRITE(TTO,606)I,NAME
  606 FORMAT(I3,'. ',20A1,1X,$)
      READ(TTI,119)T(NT)
      WRITE(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  605 CONTINUE
  611 WRITE(FILE'N1)CNO,CNAME,Q,SEC,PNAME,NTEST,NPROB,TPCT,PPCT,N,NT,NP,
     1 PROJ,JOB,NMAX
  610 CALL TIME(TTIME)
      WRITE(TTO,608)TTIME
  608 FORMAT(//'Completed at ',3A4)
      GO TO 8
C
C*********************************************************************
C                                                                    *
C       PROB - record a problem grade for each person in the class   *
C              This function works similar to the one for tests.     *
C                                                                    *
C*********************************************************************
  700 NP=NP+1
      IF(NP.LE.NPROB)GO TO 701   ! MORE THAN NPROB PROBLEMS - ERROR
      WRITE(TTO,702)NPROB
  702 FORMAT(///'MAX OF ',I2,' PROBLEMS ALREADY RECORDED')
      GO TO 8
  701 WRITE(TTO,703)
  703 FORMAT(///'Problem ',$)
      WRITE(TTO,604)NP
      DO 705 I=1,N
      READ(FILE'I +4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      IF(BITSET(STATUS(4),NP) .EQ. 1)GO TO 705 !Already recorded?
      CALL SETBIT(STATUS(4),NP,1)
      WRITE(TTO,606)I,NAME
      READ(TTI,119)P(NP)
      WRITE(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  705 CONTINUE
      GO TO 611     !WRITE REC N1, RETURN FOR NEXT OPTION
C
C***********************************************************************
C                                                                      *
C        CTEST - change a test grade for one or more students          *
C                This routine asks the user which test is to be        *
C                changed and then allows any number of student         *
C                grades to be changed for that test only.              *
C                To change grades for 2 different tests, this          *
C                function must be called twice.                        *
C                A grade for some (not all) students may be recorded   *
C                for the first time using this function.  It keeps     *
C                track of number of tests recorded for a student       *
C                even if the grade has not been recorded for the       *
C                entire class yet.                                     *
C                                                                      *
C***********************************************************************
  800 WRITE(TTO,801)
  801 FORMAT(///'Which test',1X,$)
      READ(TTI,114)M
      IF(M.GT.0.AND.M.LE.NTEST)GO TO 802
      WRITE(TTO,405)M,NTEST
      GO TO 800
  802 DO 805 I=1,N
  804 FORMAT(//'Type number of student whose grade is to change - type 0
     1 to stop')
  807 WRITE(TTO,804)
      READ(TTI,114)K
      IF(K.EQ.0) GO TO 610
      IF(K.LE.N)GO TO 806
      WRITE(TTO,405)K,N
      GO TO 807
  806 READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      WRITE(TTO,808)NAME,T(M)
  808 FORMAT('Change grade for ',20A1,' from ',F4.0,' to ',$)
      READ(TTI,119)TESTM
      IF(TESTM .NE. 0)CALL SETBIT(STATUS(3),M,1)
      IF(M.LE.NT)GO TO 820
      IF(TESTM .EQ. 0)CALL SETBIT(STATUS(3),M,0)
  820 T(M)=TESTM
      WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  805 CONTINUE
      GO TO 610      !PRINT 'FINISHED' MESSAGE
C
C*******************************************************************
C                                                                  *
C      CPROB - change or record a problem grade for one or         *
C              more students.  This function is similar to CTEST.  *
C                                                                  *
C*******************************************************************
  900 WRITE(TTO,901)
  901 FORMAT(///'Which problem',1X,$)
      READ(TTI,114)M
      IF(M.GT.0.AND.M.LE.NPROB)GOTO902
      WRITE(TTO,405)M,NPROB
      GO TO 900
  902 DO 905 I=1,N
  907 WRITE(TTO,804)
      READ(TTI,114)K
      IF (K.EQ.0) GO TO 610
      IF(K.LE.N)GOTO906
      WRITE(TTO,405)K,N
      GO TO 907
  906 READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      WRITE(TTO,808)NAME,P(M)
      READ(TTI,119)TESTM
      IF(TESTM .NE. 0)CALL SETBIT(STATUS(4),M,1)
      IF(M.LE.NP)GO TO 920
      IF(TESTM .EQ. 0)CALL SETBIT(STATUS(4),M,0)
  920 P(M)=TESTM
      WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
  905 CONTINUE
      GO TO 610      !PRINT 'FINISHED' MESSAGE
C
C****************************************************************
C                                                               *
C       DISPLAY - display the class roll                        *
C                 The user gets his choice of 3 formats         *
C                 with different information in each            *
C                                                               *
C****************************************************************
 1000 WRITE(TTO,1001)
 1001 FORMAT(///'Type number of desired display'/'1-Name,special informa
     1tion,status,averages,and letter grade' / '2-Name,test,problem grad
     2es,averages,letter grade'/'3-All items for selected students')
      READ(TTO,114)M
      IF(M.LE.3)GO TO 1002
      WRITE(TTO,405)M,3
      GO TO 1000
 1002 CALL TIME(TTIME)
      WRITE(TTO,1003)CNO,CNAME,SEC
 1003 FORMAT(//'Course:'12A2,1X,10A2,1X,'Section:',2A2)
      WRITE(TTO,1004)Q,PNAME,NTEST,NPROB
 1004 FORMAT('Term:',6A2,4X,'Instructor:',10A2,1X,'Tests:',1X,I1,2X,
     1'Problems:',I2)
      WRITE(TTO,1005)NT,NP,TDATE,TTIME
 1005 FORMAT('Tests recorded:',I1,5X,'Problems recorded:',I2,12X,
     1 2A4,A1,2X,3A4)
      IF (PROJ .NE. 0) WRITE(TTO,1021)PROJ,JOB
 1021 FORMAT('Project #:',I3,T39,'Job #:',4A2)
      GO TO (1022,1022,1080),M
 1022 DO 1006 I=1,15
      AVG(I)=0.          ! INITIALIZE COUNTS AND AVERAGES
 1006 KNT(I)=N
      DO 1007 I=1,N
      READ(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      M1=HIBIT(STATUS(3))
      M2=HIBIT(STATUS(4))
      IF(M1.LT.NT)M1=NT
      IF(M2.LT.NP)M2=NP
      CALL AVER(NTEST,NPROB,T,P,M1,M2)
      CALL LGRADE(J,AV,N2)
      CALL LET(J,K,STATUS(2))
      LG=GRADE(K)
      CALL PLMIN(LG,K,STATUS(2),N2,AV)  !Add +, -, or * to letter
C                                          grade where appropriate
      DO 1012 J=1,5
          AVG(J)=AVG(J)+T(J)
          IF(T(J).EQ.0)KNT(J)=KNT(J)-1
 1012 CONTINUE
      DO 1013 J=6,15
          AVG(J)=AVG(J)+P(J-5)
          IF(P(J-5).EQ.0)KNT(J)=KNT(J)-1
 1013 CONTINUE
      GO TO(1014,1050),M
 1014 IF((I-1)/15*15.NE.I-1)GOTO1015
      IF(I.EQ.1)GO TO 1016
      WRITE(TTO,1017)
 1017 FORMAT(/'To display next page-press RETURN')
      READ(TTI,4)ANS
      CALL TIME(TTIME)
      WRITE(TTO,1003)CNO,CNAME,SEC
      WRITE(TTO,1004)Q,PNAME,NTEST,NPROB
      WRITE(TTO,1005)NT,NP,TDATE,TTIME
      IF (PROJ .NE. 0) WRITE(TTO,1021)PROJ,JOB
 1016 WRITE(TTO,1018)
 1018 FORMAT(/5X,'Name',T27,'Special information',T48,'Class ','Status',
     1T61,'Test',T67,'Prob',T73,'Avg', T78,'Gr')
 1015 M1=STATUS(1)+1
      M2=STATUS(2)+1
      IF(INFO(1).NE. BLANK)GO TO1019
      WRITE(TTO,1020)I,NAME,DOTS,CLASS(M1),STAT(M2),TAVG,PAVG,AV,LG
 1020 FORMAT(I3,'.',1X,20A1,T27,10A2,T48,A5,1X,A6,T60,F5.1,T66,F5.1,T71,
     1F6.2,T78,A2)
      GO TO 1007
 1019 WRITE(TTO,1020)I,NAME,INFO,CLASS(M1),STAT(M2),TAVG,PAVG,AV,LG
      GO TO 1007
C
C FORMAT 2 DISPLAY
C
 1050 IF((I-1)/ 8*8 .NE.I-1)GO TO 1051
      IF(I.EQ.1)GO TO 1052
      WRITE(TTO,1017)
      READ(TTI,4)ANS
      WRITE(TTO,1003)CNO,CNAME,SEC
      WRITE(TTO,1004)Q,PNAME,NTEST,NPROB
      CALL TIME(TTIME)
      WRITE(TTO,1005)NT,NP,TDATE,TTIME
      IF (PROJ .NE. 0) WRITE(TTO,1021)PROJ,JOB
 1052 WRITE(TTO,1053)
 1053 FORMAT(/5X,'Name',T27,'Tests/Problems',T51,'Grade',T61,'Avg',T71,
     1'T/P Avg')
 1051 DO 1054 J=1,5
 1054 IT(J)=T(J)
      DO 1055 J=1,10
 1055 IP(J)=P(J)
      ENCODE(20,1154,TLINE)IT
      ENCODE(40,1155,PLINE)IP
      N22=NT+1
      IF(NT.GE.5)GO TO 1065
      DO 1066 J=N22,5
      IF(IT(J).EQ.0) TLINE(J)=SPACE
1066  CONTINUE
1065  N22=NP+1
      IF(NP.GE.10)GO TO 1067
      DO 1068 J=N22,10
      IF(IP(J).EQ.0)PLINE(J)=SPACE
1068  CONTINUE
1067  WRITE(TTO,1056)I,NAME,TLINE,LG,AV,TAVG
 1056 FORMAT(I3,'. ',20A1,T26,5(A4), T53,A2, T59,F6.2,T71,F6.2)
      WRITE(TTO,1057)PLINE,PAVG
 1057 FORMAT(T17,'Problems',T26,10A4,T71,F6.2)
 1007 CONTINUE
      DO 1060 J=1,15
      IF(KNT(J).GT.0)AVG(J)=AVG(J)/KNT(J)
 1060 CONTINUE
      WRITE(TTO,1017)
      READ(TTI,4)ANS
      WRITE(TTO,1061)(J,J=1,NTEST)
 1061 FORMAT(//'Averages (with weights) not including grades of zero' /
     1 'Tests',T15,5(I1,6X))
      WRITE(TTO,1062)(AVG(J),J=1,NTEST)
 1062 FORMAT(T10,5(F6.2,1X))
      WRITE(TTO,1070)(INT(100.*TPCT(J)),J=1,NTEST)
 1070 FORMAT(T10,5(:,'(',I3,'%) '))
      WRITE(TTO,1063)(J,J=1,NPROB)
 1063 FORMAT(/'Problems:'/10(5X,I2))
      WRITE(TTO,1064)(AVG(J),J=6,5+NPROB)
 1064 FORMAT(10(1X,F6.2))
      WRITE(TTO,1071)(INT(100.*PPCT(J)),J=1,NPROB)
 1071 FORMAT(10(:,1X,'(',I3,'%)'))
      GO TO 610
C*************************************
C                                    *
C  Format 3 display                  *
C                                    *
C*************************************
 1080 WRITE(TTO,1204)
      DO 1081 J=1,N
 1082    READ(TTI,114)F(J)
         IF(F(J) .EQ. 0)GO TO 1090
         IF(F(J) .LE. N .AND. F(J) .GT. 0)GO TO 1081
         WRITE(TTO,405)F(J),N
         GO TO 1082
 1081 CONTINUE
 1090 K=J-1
      IF(K .EQ. 0)GO TO 610
      DO 1083 J = 1,K
         READ(FILE'F(J)+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
         M1=HIBIT(STATUS(3))
         M2=HIBIT(STATUS(4))
         CALL AVER(NTEST,NPROB,T,P,M1,M2)
         CALL LGRADE(M,AV,N2)
         CALL LET(M,I,STATUS(2))
         LG =GRADE(I)
         CALL PLMIN(LG,I,STATUS(2),N2,AV)  !Add +, -, or * to letter
C                                          grade where appropriate
         WRITE(TTO,1086)F(J),NAME,PRJ,PROG,PW,INFO
 1086    FORMAT(//I3,T5,20A1,T30,'[',I3,',',I3,']',T40,6A1,T50,10A2)
         WRITE(TTO,1087)(T(I),I=1,M1)
         WRITE(TTO,1088)(P(I),I=1,M2)
 1087    FORMAT('Tests:',T10,5F6.0)
 1088    FORMAT('Problems:',T10,10F6.0)
         M1=STATUS(1)+1
         M2=STATUS(2)+1
         WRITE(TTO,1089)TAVG,PAVG,AV,LG,CLASS(M1),STAT(M2)
 1089    FORMAT('Test avg:',F7.2,' Prob avg:',F7.2,' Avg:',F7.2,
     1          /'Grade: ',A2,' Class: ',A6,' Status: ',A6)
 1083 CONTINUE
      GO TO 610
C
C********************************************************************
C                                                                   *
C       REPORT - produce a formatted copy of the roll in a file     *
C                for later printing.  The user always gets a list   *
C                with the names, scores, overall average, and       *
C                letter grades as well as class averages and        *
C                grade distributions.  If the user wishes, he may   *
C                get a second part of the report including          *
C                account numbers, special information, status, etc. *
C                In this second case, the user gets a separate list *
C                of people with grades of "I", if any.              *
C                                                                   *
C********************************************************************
 1100 L1=ONE
      M=1
      NS = 0    !Number of NO-SHOWS
C INITIALIZE COUNTS AND AVERAGES
 1120 DO 1104 J= 1,15
      AVG(J)=0.
          DO 1121 K=1,6
              TPLG (K,J) = 0
 1121     CONTINUE
 1104 KNT(J)=N
      DO 1161 J=1,10
 1161 LK(J)=0
      DO 1105 I=1,N
      IF (MOD(I,45) .EQ. 1) CALL HEAD(M,L1)  !PRINT HEADING
      READ(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
      IF(STATUS(2) .EQ. 2) NS = NS + 1  !Count the NO-SHOWS
      M1=HIBIT(STATUS(3))
      M2=HIBIT(STATUS(4))
      IF(M1.LT.NT)M1=NT
      IF(M2.LT.NP)M2=NP
      CALL AVER(NTEST,NPROB,T,P,M1,M2)
      CALL LGRADE(J,AV,N2)
      CALL LET(J,K,STATUS(2))
      LG=GRADE(K)
      CALL PLMIN(LG,K,STATUS(2),N2,AV)  !Add +, -, or * to letter
C                                          grade where appropriate
 1160 DO 1110 J=1,5
          CALL LGRADE(J1,T(J),N2)
          TPLG(J1,J)=TPLG(J1,J)+1  !COUNT LETTER GRADES FOR THIS TEST
          AVG(J)=AVG(J)+T(J)
          IF(T(J).EQ.0)KNT(J)=KNT(J)-1
 1110     IT(J)=T(J)
      DO 1111 J=6,15
          CALL LGRADE(J1,P(J-5),N2)
          TPLG(J1,J)=TPLG(J1,J)+1  !COUNT LETTER GRADES FOR THIS PROBLEM
          AVG(J)=AVG(J)+P(J-5)
          IF(P(J-5).EQ. 0)KNT(J)=KNT(J)-1
 1111     IP(J-5)=P(J-5)
      LK(K)=LK(K)+1                !COUNT LETTER GRADES
      GO TO(1112,1152),M                !PRINT PROPER REPORT
1112  ENCODE(20,1154,TLINE)IT
1154  FORMAT(5(I3,1X))
      DASH='___ '
      ENCODE(40,1155,PLINE)IP
1155  FORMAT(10(I3,1X))
      IF(NTEST.GE.5)GOTO 1157
      N22=NTEST+1
      IF(NTEST.LE.0)N22=1
      DO 1158 J=N22,5
1158  TLINE(J)=SPACE
1157  IF(NT.GE.NTEST) GO TO 1159
      N22=NT+1
      IF(NT.LE.0)N22=1
      IF(NTEST.LE.0)GOTO1159
      DO 1163 J=N22,NTEST
      IF(IT(J).EQ.0)TLINE(J)=DASH
1163  CONTINUE
1159  IF (NPROB.GE.10)GO TO 1162
      N22=NPROB+1
      IF(NPROB.LE.0)N22=1
      DO 1172 J=N22,10
1172  PLINE(J)=SPACE
1162  IF(NP.GE.NPROB)GOTO1165
      N22=NP+1
      IF(NP.EQ.0)N22=1
      IF(NPROB.LE.0)GO TO 1165
      DO 1164 J=N22,NPROB
      IF(IP(J).EQ.0)PLINE(J)=DASH
1164  CONTINUE
 1165 DO 1180 J=1,16
 1180 LINE(J)=SPACE
      DO 1177 J=1,NTEST
 1177 LINE(J)=TLINE(J)
      ENCODE(4,1178,LINE(NTEST+1))LG
 1178 FORMAT('<',A2,'>')
      DO 1179 J=1,NPROB
 1179 LINE(J+1+NTEST)=PLINE(J)
      WRITE(LP,1113)I,NAME,AV,(LINE(J),J=1,NTEST+NPROB+1)
 1113 FORMAT(' ',I3,'. ',20A1,T28,F6.2,'#',T36,16(A4,2X))
      DASH='____'
      GO TO 1105
 1152 L=STATUS(1)+1
      K=STATUS(2)+1
      WRITE(LP,1153)I,NAME,CLASS(L),STAT(K),TAVG,PAVG,AV,LG,INFO,
     1 PRJ,PROG,PW
 1153 FORMAT(' ',I3,'. ',20A1,T28,A5,T34,A6,T42,F6.2, T51,F6.2,T60,F6.2,
     1T72,A2,T77,10A2,T104,'[',I3,',',I3,']',T122,6A1)
 1105 CONTINUE
      IF(M.EQ.2)GO TO 1115
      DO 1118 J=1,15
         IF(KNT(J).GT.0) AVG(J) = AVG(J)/KNT(J)
 1118 CONTINUE
      ENCODE(120,1166,AG)AVG
1166  FORMAT(15(F5.1,3X))
      N22=NTEST+1
      IF(NTEST.GE.5)GO TO 1167
      DO 1168 J=N22,5
1168  AG(J)=SP2
1167  N22=NPROB+1
      IF(NPROB.GE.10)GO TO 1169
      DO 1170 J=N22,10
1170  AG(J+5)=SP2
 1169 DO 1187 J=1,NTEST+NPROB+1
 1187 LINE(J) = DASH
      DO 1188 J1=J,16
 1188 LINE(J1)=SPACE
      WRITE(LP,1114)(LINE(J),J=1,NTEST+NPROB+1)
 1114 FORMAT(' ',T35,16(A4:,'__'))
      WRITE(LP,1189)(AG(J),J=1,NTEST),SP2,(AG(J),J=6,NPROB+6)
 1189 FORMAT(' ',T23,'Averages:',T34,16(A5,1X))
      WRITE(LP,1182)
 1182 FORMAT(T34,'* next to letter grade indicates NO-SHOW')
      IF (MOD(I,45) .GT. 41) CALL HEAD(M,L1)
C*********Print letter grades for each test and problem.
      CALL PRT(TPLG,GRADE, LINE,LP,NTEST,NPROB)
      WRITE(LP,1190)
 1190 FORMAT('0',T22,'Grades of 0 are not counted in class averages.')
      J1 = MOD(I,45)
      IF (J1 .GT. 41) GO TO 1198
      IF(J1 .LE. 36) GO TO 1115
      CALL HEAD(3,L1)
      WRITE(LP,1199)
 1199 FORMAT(///'0')
      GO TO 1198
 1115 M1=127
      IF(M .EQ. 1)M1=37 + 6*(NTEST + NPROB)
      WRITE(LP,1116)('*',J=1,M1)
 1116 FORMAT(' ',132A1)
 1198 WRITE(LP,1197)(GRADE(J),J=1,10),(LK(J),J=1,10),NS
 1197 FORMAT(' ',5(/'+GRADE DISTRIBUTION:')/' Grade:    ',10(A2,3X)/
     1 ' Number: ',10(I3,2X)/T11,'Totals ',
     2 'include ',I3,' people who never attended or quit attending')
      IF(M.EQ.2)GOTO 1191
      M=2
      NS = 0
      WRITE(TTO,1196)
 1196 FORMAT('Do you want the part of the report with ',
     1 'account numbers,status,etc.? ',$)
      READ(TTI,4)ANS
      IF(ANS .NE. 'YES')GO TO 610  !IF NO - FUNCTION COMPLETE
      GO TO 1120
C
C     LIST INCOMPLETES (IF ANY)
C
 1191 IF(LK(6) .LE. 0) GO TO 610 !IF NO INCOMPLETES - RETURN
      CALL HEAD(3,L1)            !PRINT HEADINGS
      WRITE(LP,1192)             !SUBHEADINGS
 1192 FORMAT(/'0',T20,'LIST OF INCOMPLETES'/
     1 ' ',T7,'NAME',T30,'ACCOUNT NUMBER',T48,'PASSWORD'/
     2 ' ',T7,'----',T30,'--------------',T48,'--------')
      K=0
      DO 1193 I=1,N
          READ(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
          IF (STATUS(2) .NE. 3) GO TO 1193     !IS THIS AN INCOMPLETE?
          K=K+1
          WRITE(LP,1194)K,NAME,PRJ,PROG,PW
 1194     FORMAT(' ',I3,'. ',20A1,T32,'[',I3,',',I3,']',T49,6A1)
 1193 CONTINUE
      WRITE(LP,1195)K,CNO
 1195 FORMAT(///'0',T10,'There are ',I3,' incompletes in ',12A2)
      GO TO 610                               !FINISHED
C
C*******************************************************************
C                                                                  *
C       SELRPT - produce individual student reports for later      *
C                printing.  The user may choose to get reports     *
C                for all students on the roll, or he may designate *
C                those for which he wants the reports.             *
C                The reports are printed 3 to a page, and contain  *
C                a name, grades, averages, letter grade, account   *
C                number, and other information.                    *
C                If the student is not taking the course for credit*
C                his report will be generated if it is explicitly  *
C                requested only.                                   *
C                                                                  *
C*******************************************************************
 1200 J2=0
D     WRITE(7,*)'TPCT = ',TPCT
      CALL TIME(TTIME)
      WRITE(TTO,1201)CNO,CNAME
 1201 FORMAT(///22A2)
      WRITE(TTO,1299)
 1299 FORMAT('Do you want reports for everyone on the roll')
      READ(TTI,4)ANS
      IF(ANS.NE.YES)GO TO 1202
      J2=1
      DO 1203 J=1,N
 1203     F(J)=J
      K=N
      GO TO 1206
 1202 WRITE(TTO,1204)
 1204 FORMAT(//'List numbers of students for whom reports are needed-1 n
     1umber per line'/'Type 0 after last one')
      DO 1205 J=1,N
 1222 READ(TTI,114)F(J)
      IF(F(J).EQ.0) GO TO 1207
      IF(F(J).LE. N.AND. F(J).GT. 0)GO TO 1205
      WRITE(TT0,405)F(J),N
      GO TO 1222
 1205 CONTINUE
 1207 K=J-1
 1206 WRITE(TTO,1223)
 1223 FORMAT('Print passwords (YES or NO)? ',$)
      READ(TTI,4)ANS
      DO 1208 J=1,K
      I=F(J)
      READ(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
D     WRITE(7,*)'TPCT = ',TPCT
      L=BLANK
      IF(J-J/3*3.EQ.1)L=ONE
      IF(STATUS(2) .EQ. 0 .OR. J2 .NE. 1)GO TO 1220
      IF(L .EQ. ONE)WRITE(LP,1221)
 1221 FORMAT('1')
      GO TO 1208
 1220 CONTINUE
      CALL HEAD(3,L)   !PRINT HEADING
      M1=HIBIT(STATUS(3))
      M2=HIBIT(STATUS(4))
      CALL AVER(NTEST,NPROB,T,P,M1,M2)
      CALL LGRADE(I,AV,N2)
      CALL LET(I,J1,STATUS(2))
      LG=GRADE(J1)
      CALL PLMIN(LG,J1,STATUS(2),N2,AV)  !Add +, -, or * to letter
C                                          grade where appropriate
D     WRITE(7,*)'TPCT = ',TPCT
      WRITE(LP,1213)F(J),NAME,(T(I),I=1,M1)
 1213 FORMAT('0', I3,'. ',20A1, T31,'Test grades:',5(F5.0,3X))
      WRITE(LP,1214)(P(I),I=1,M2)
 1214 FORMAT(' ',T28,'Problem grades:',10(F5.0,3X))
      IF(PRJ .NE. 0)WRITE(LP,1218)PRJ,PROG
 1218 FORMAT('+',T7,'Acct #: [',I3,',',I3,']')
D     WRITE(7,*)'TPCT = ',TPCT
      WRITE(LP,1215)TAVG,(IFIX(100.*TPCT(I)),I=1,M1)
 1215 FORMAT('0Test average:',T19,F6.2,T26,'Based on weights: ',5(I3,
     1 '%',4X))
D     WRITE(7,*)'TPCT = ',TPCT
      WRITE(LP,1225)PAVG,(IFIX(100.*PPCT(I)),I=1,M2)
 1225 FORMAT(' Problem average:',T19,F6.2,T26,'Based on weights: ',
     1 10(I3,'%',4X))
      WRITE(LP,1226)AV,LG,INFO
 1226 FORMAT(' Overall average:',T19,F6.2/' Grade: ',A2/T25,10A2,
     1 T8,'---')
      IF(ANS .EQ. YES)WRITE(LP,1224)PW
 1224 FORMAT('+',T55,'Password: ',6A1)
      WRITE(LP,1216)TTIME,TDATE,PNAME
 1216 FORMAT(' ','Grades of 0 may indicate work not completed.' /
     1' Work graded after ',2A4,A3,' on ',2A4,A1,
     2' is not included in this report.'/
     3'0Please report all errors immediately to ',10A2)
      WRITE(LP,1217)
 1217 FORMAT('0'/' ')
 1208 CONTINUE
      GO TO 610
C
C*******************************************************************
C                                                                  *
C        INIT - this routine initializes test and problems         *
C               grades to 0.  It also initializes counters to      *
C               0.  It should be used at the beginning of a term   *
C               to initialize a roll which was used in the         *
C               previous term and will be used again this term.    *
C               It does not change course title, term name, add    *
C               or drop students, etc.  To accomplish these        *
C               functions, use LABEL, ADD, DROP, etc.              *
C                                                                  *
C*******************************************************************
 1800 WRITE(TTO,1201)CNO,CNAME
      WRITE(TTO,1801)
 1801 FORMAT(/'This function deletes all grades and resets all ',
     1 'counters for this roll.'/
     2 'It should be used at the beginning of a term to ',
     3 'initialize an old roll which'/
     4 'will be used again.  '/
     5 'To make other changes such as course name, term name, ',
     6 'adding or dropping '/
     7 'students, use LABEL, ADD, DROP, etc.'//
     8 'If you want this roll initialized type YES - else ',
     9 'press RETURN')
      READ(TTI,4)ANS
      IF(ANS .NE. YES) GO TO 8
      NT=0
      NP=0
      DO 1802 I=1,N
         READ(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
         STATUS(3)=0
         STATUS(4)=0
         DO 1803 K=1,5
            T(K)=0.
            P(K)=0.
            P(K+5)=0.
 1803    CONTINUE
         WRITE(FILE'I+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
 1802 CONTINUE
      GO TO 611
C
C******************************************************************
C                                                                 *
C      PASSWORD - this routine changes the record on this roll    *
C                 of a student's password.  It does not change    *
C                 the actual password known to the system.        *
C                                                                 *
C******************************************************************
 1900 WRITE(TTO,1901)
 1901 FORMAT(//'Change the password recorded in this roll'/)
      DO 1905 I=1,N
 1902    WRITE(TTO,1602)
         READ(TTI,114)K
         IF(K.EQ.0)GO TO 610
         IF(K.GT.0 .AND. K .LE. N)GO TO 1903
         WRITE(TTO,405)K,N
         GO TO 1902
 1903    READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
         WRITE(TTO,1904)NAME,PW
 1904    FORMAT('Change password for ',20A1,' from ',6A1,' to ',$)
         READ(TTI,1707)PW
         WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
 1905 CONTINUE
      GO TO 610
C
C*********************************************************************
C                                                                    *
C       ACCT - change the recorded account number for a student on   *
C              this roll.  This function does not change the account *
C              number known to the system for this student.          *
C                                                                    *
C*********************************************************************
 2100 WRITE(TTO,2101)
 2101 FORMAT(//'Change account number recorded for a student'/)
      DO 2105 I=1,N
 2102    WRITE(TTO,1602)
         READ(TTI,114)K
         IF(K .EQ. 0)GO TO 610
         IF(K .GT. 0 .AND. K .LE. N)GO TO 2103
         WRITE(TTO,405)K,N
         GO TO 2102
 2103    READ(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
         WRITE(TTO,2104)NAME,PRJ,PROG
 2104    FORMAT('Change acct# for ',20A1,' from [',I3,',',I3,
     1   '] to (no brackets) ',$)
         READ(TTI,114)PRJ,PROG
         WRITE(FILE'K+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
 2105 CONTINUE
      GO TO 610
C
C*******************************************************************
C                                                                  *
C         SORT - this routine sorts the roll into alphabetical     *
C                order based on names.                             *
C                                                                  *
C*******************************************************************
 2000 K=N-1
      M=N
      CALL TIME(TTIME)
      WRITE(TTO,2030)TTIME
 2030 FORMAT('***** ROLL BEING SORTED - PLEASE WAIT *****',
     1' -- Time: ',3A4)
      DO 2001 I=1,K
      IND=0
      M=M-1
      DO 2002 J=1,M
          READ(FILE'J+4)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
          READ(FILE'J+5)NTEMP,NINFO,NSTAT,TT,TP,NPROGT,NPJ,NPW
          DO 2003 L=1,20
               IF(NAME(L).LT.NTEMP(L))GO TO 2002
               IF(NAME(L).GT.NTEMP(L))GO TO 2004
 2003     CONTINUE
          GO TO 2002
 2004     WRITE(FILE'J+5)NAME,INFO,STATUS,T,P,PROG,PRJ,PW
          WRITE(FILE'J+4)  NTEMP,NINFO,NSTAT,TT,TP,NPROGT,NPJ,NPW
          IND=1
 2002 CONTINUE
      IF(IND.EQ.0) GO TO 2005
 2001 CONTINUE
 2005 CALL TIME(TTIME)
      WRITE(TTO,2031)TTIME
 2031 FORMAT('***** SORT NOW COMPLETED *****',' -- Time: ',3A4)
      GO TO(610,611,415),MRTN      ! RETURN
CC******************************************************************
C                                                                 *
C       CURVE - This routine applies one of three types of        *
C               curves to a test or problem grade.  The types     *
C               of curve are: fixed increment, fixed percentage,  *
C               and square root.                                  *
C                                                                 *
C******************************************************************
 2200 WRITE(TTO,2201)
 2201 FORMAT('Curve a TEST or PROBLEM grade? ',$)
      K=0
      READ(TTI,4)ANS
      IF(ANS .EQ. 'TEST' .OR. ANS .EQ. 'PROBLEM')GO TO 2202
        WRITE(TTO,154)
        GO TO 2200
 2202 WRITE(TTO,2203)ANS
 2203 FORMAT('WHICH ',A8,$)
      READ(TTO,114)J
      IF(ANS .EQ. 'PROBLEM')J = J + 5    !5=MAX TESTS
      IF(J .LE. 15) GO TO 2204
         WRITE(TTO,154)
         GO TO 2202
 2204 WRITE(TTO,2205)
 2205 FORMAT('Specify type of curve:'
     1 / T5,'INCREMENT ... add fixed amount to each grade'
     2 / T5,'PERCENTAGE .. multiply each grade by fixed amount'
     3 / T5,'SQUARE ROOT . add square root of grade to grade')
      READ(TTI,4)ANS
      IF(ANS .EQ. 'SQUARE R')GO TO 2206
        WRITE(TTO,2207)
 2207   FORMAT('Specify amount ',$)
        READ(TTI,160)Y
 2206 WRITE(TTO,2209)
 2209 FORMAT('Do you want to apply the curve to grades of 0? ',$)
      READ(TTI,105)K
      DO 2210 I = 1,N
         READ(FILE'I+4)NAME,INFO,STATUS,AVG,PROG,PRJ,PW
         IF(K .NE. 'YE' .AND. AVG(J) .EQ. 0.)GO TO 2210
         IF(ANS .EQ. 'INCREMEN')AVG(J) = AVG (J) + Y
         IF(ANS .EQ. 'PERCENTA')AVG(J) = AVG(J)*Y
         IF(ANS .EQ. 'SQUARE R')AVG(J) = AVG(J) + SQRT(ABS(AVG(J)))
 2208    WRITE(FILE'I+4)NAME,INFO,STATUS,AVG,PROG,PRJ,PW
 2210 CONTINUE
      GO TO 610
      END
      SUBROUTINE PSWORD(PW,I,J)
C***************************************************************
C                                                              *
C       PSWORD - this subroutine uses a random number generator*
C                to generate a random 6 letter password (PW)   *
C                I and J are used by the random number         *
C                generator to compute the next random number.  *
C                                                              *
C***************************************************************
      INTEGER PW(6),L(26)
      DATA L/'A','B','C','D','E','F','G','H','I','J','K','L','M',
     1   'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'/
      DO 1 K=1,6
         CALL RANDU(I,J,X)
         M = 26. * X + 1.
         PW(K) = L(M)
    1 CONTINUE
      RETURN
      END
      SUBROUTINE HEAD (M,L)
C****************************************************************
C                                                               *
C     THIS SUBROUTINE PRINTS HEADINGS FOR THE 3 REPORTS         *
C          GENERATED BY THIS PROGRAM. THE ARGUMENTS ARE:        *
C          M: 1,2,or 3 depending on the report to be printed.   *
C          L: control character for first line of report.       *
C                                                               *
C****************************************************************
      INTEGER CNO(12),CNAME(10),Q(6),SEC(2),PNAME(10),HT,HP,PAGE
      INTEGER PROJ,JOB(4)
      REAL TDATE(3),TTIME(3),LINE(16),TPCT(5),PPCT(10)
      COMMON TDATE,TTIME,CNO,CNAME,SEC,Q,PNAME,NTEST,NPROB,NT,NP,
     1   LP,LINE,SPACE,HT,HP,DASH,PAGE,PROJ,JOB
      COMMON /CMN1/TPCT,PPCT,TAVG,PAVG,AV
      L1=L
      CALL TIME(TTIME)
      IF (L1 .NE. '1')GO TO 10
         PAGE = PAGE + 1       !IF TOP OF PAGE PRINT PAGE NUMBER
         WRITE(LP,4)PAGE
    4    FORMAT('1',60X,'Page: ',I3)
         L1=' '
   10 WRITE(LP,1101)L1,CNO,CNAME,SEC,Q,TDATE,TTIME
 1101 FORMAT(A1,'Course:',12A2,1X,10A2,8X,'Section: ',2A2,
     1 5(/'+','Course:',53X,'Section:')/
     2 ' ','Term:',1X,6A2,22X,'Date:',2A4,A1,5X,' Time:',2A4,A3,1X,
     3 5(/'+','Term:',35X,'Date:'15X,'Time:'))
      WRITE(LP,1102)PNAME,NTEST,NPROB,NT,NP
 1102 FORMAT(' ','Instructor:',10A2,9X,'Tests:',I2,12X,'Problems:',I2,
     1 5(/'+','Instructor:',29X,'Tests:',14X,'Problems:')/
     2 ' ','Tests recorded:',I2,22X,' Problems recorded:',I2,
     4 5(/'+','Tests recorded:',25X,'Problems recorded:'))
      IF(PROJ .NE. 0)WRITE(LP,1000)PROJ,JOB
 1000 FORMAT(' Project #: ',I3,T42,'Job #: ',4A2,
     1  5(/'+Project #:',T42,'Job #:'))
      GO TO (1,2,3),M  !PRINT PROPER REPORT
C****************************************************************
C                                                               *
C     PRINT HEADING FOR REPORT 1                                *
C                                                               *
C****************************************************************
    1 DO 1181 J=1,16
 1181 LINE(J)=SPACE
      ENCODE(NTEST*4,1151,LINE)(IFIX (100.*TPCT(I)),I=1,NTEST)
 1151 FORMAT(10(I3,'%'))
      ENCODE(NPROB*4,1151,LINE(NTEST+2))(IFIX(100.*PPCT(I)),I=1,NPROB)
      WRITE(LP,1155)
 1155 FORMAT('0')
      DO 1154 J=1,5
           WRITE(LP,1152)(LINE(I),I=1,NTEST+NPROB+1)
 1152      FORMAT('+',T27,'Weights:',T35,16(A4,2X))
 1154 CONTINUE
      DO 1153 I = 1,16
         LINE(I) = SPACE
 1153 CONTINUE
      ENCODE(NTEST*4,1183,LINE)(HT,J,J=1,NTEST)
 1183 FORMAT(10(A1,I2,1X))
      ENCODE(NPROB*4,1183,LINE(NTEST+2))(HP,J,J=1,NPROB)
      WRITE(LP,1103)((LINE(K),K=1,NTEST),' Grade',
     1     (LINE(K),K=NTEST+2,16),J=1,5)
 1103 FORMAT(' ',5(/'+',5X,'Name',T30,'Avg',T34,16(A6)))
      DO 1184 J=1,NTEST
 1184 LINE(J)=DASH
      DO 1185 J=1,NPROB
 1185 LINE(J+1+NTEST)=DASH
      WRITE(LP,1186)(DASH,DASH,LINE,J=1,5)
 1186 FORMAT(' ',5(/'+',5X,A4,T30,A3,T36,16(A3,3X)))
      RETURN
C****************************************************************
C                                                               *
C     PRINT SUBHEADING FOR PAGE 2                               *
C                                                               *
C****************************************************************
    2 WRITE(LP,1117)
 1117 FORMAT(/'0',5X,'Name',T28,'Class',T34,'Status',T41,'Test avg',
     1    T50,'Prob avg', T60,'Average',T70,'Grade',T77,'Special informa
     2tion',T100,'Project/Programmer',T121,'Password',
     3/' ',5X,'----',T28,'-----',T34,'------',T41,'--------',
     4 T50,8('-'),T60,7('-'),T70,5('-'),T77,19('-'),T100,18('-'),
     5 T121,8('-'))
      RETURN
C****************************************************************
C                                                               *
C     NO SUBHEADING FOR INDIVIDUAL REPORT                       *
C                                                               *
C****************************************************************
    3 RETURN
      END
      SUBROUTINE LGRADE(I,T,N2)
C**************************************************************
C                                                             *
C        This subroutine determines a letter grade            *
C             for a test or problem T and returns             *
C             a 1-6 for A-F or 0 respectively.                *
C             N2 is the record position containing the        *
C             lower limits for grades A,B,C, and D.           *
C                                                             *
C**************************************************************
      REAL L(4)
      READ(2'N2)L
      DO 1 I=1,4
           IF(T .GE. L(I))RETURN     !GRADE IS THE Ith ONE
    1 CONTINUE
      IF(T.EQ.0) I=6   !IF GRADE IS ZERO, SET I TO 6
      RETURN
      END
      SUBROUTINE PRT(TPLG,GRADE,LINE,LP,NTEST,NPROB)
C**************************************************************
C                                                             *
C        This subroutine formats and prints total letter      *
C             grades for each test and problem.               *
C                                                             *
C**************************************************************
      INTEGER TPLG(6,15),GRADE(6)
      REAL LINE(16)
      GRADE(6)='0'
      WRITE(LP,1)
    1 FORMAT('0',T18,'Letter grades:')
      DO 2 I=1,16
          LINE(I)=' '
    2 CONTINUE
      N=5+NPROB
      DO 10 I=1,6
          ENCODE(NTEST*4,3,LINE)(TPLG(I,J),J=1,NTEST)
    3     FORMAT(10I4)
          ENCODE(NPROB*4,3,LINE(6))(TPLG(I,J),J=6,N)
          WRITE(LP,4)GRADE(I),(LINE(J),J=1,NTEST),' ',(LINE(J),J=6,N)
    4     FORMAT(T25,A1,'''s',T34,16(A5,1X))
   10 CONTINUE
      GRADE(6)='I'
      RETURN
      END
      SUBROUTINE LET(J,K,S)
C*******************************************************************
C                                                                  *
C       LET - this subroutine returns a digit indicating which of  *
C             10 letter grades (A-F) or status grades (I,Au,W,WP,  *
C             or WF) should be printed.                            *
C                                                                  *
C*******************************************************************
      INTEGER S
      K=J
      IF(J .EQ. 6) K=5
      IF(S .EQ. 1) K=7
      IF(S .EQ. 3) K=6
      IF(S .GT. 3) K=S+4
      RETURN
      END
      SUBROUTINE AVER(NTEST,NPROB,T,P,M1,M2)
C********************************************************************
C                                                                   *
C     This subroutine computes the test average TAVG, the problem   *
C          average PAVG and the overall average AV of the tests T,  *
C          and the problems P based on individual test and problem  *
C          weights TPCT and PPCT respectively.                      *
C                                                                   *
C********************************************************************
      REAL TPCT(5), PPCT(10), T(5), P(10)
      COMMON /CMN1/ TPCT,PPCT,TAVG,PAVG,AV
   20 PCTT = 0.
      PCTP = 0.
      TAVG = 0.
      PAVG = 0.
      IF(M1 .LE. 0)GO TO 30
      DO 1008 J = 1,M1
         PCTT = PCTT + TPCT(J)
         TAVG = TAVG + T(J) * TPCT(J)
 1008 CONTINUE
   30 IF(M2 .LE. 0)GO TO 40
      DO 1009 J = 1,M2
         PCTP = PCTP + PPCT(J)
         PAVG = PAVG + P(J) * PPCT(J)
 1009 CONTINUE
   40 PCT = PCTT + PCTP
      AV = 0.
      IF (PCT .GT. 0)AV = (TAVG + PAVG)/PCT
      IF(PCTT .GT. 0.)TAVG = TAVG/PCTT
      IF(PCTP .GT. 0.)PAVG = PAVG/PCTP
      RETURN
      END
      SUBROUTINE PLMIN(LG,K,S,N2,AV)
C********************************************************************
C                                                                   *
C     PLMIN adds a + to letter grade in LG if average AV is in      *
C           top 20% of grade bracket, adds a - to LG if AV is in    *
C           lower 20% of grade bracket, and adds an * to LG if      *
C           status S = 2 (noshow).  K is an indicator returned by   *
C           subroutine LET indicating which letter grade is         *
C           assigned.  N2 is position in file of the grade limits.  *
C                                                                   *
C********************************************************************
      REAL L(6)
      INTEGER S
      IF(S .NE. 2)GO TO 1
         LG=LG+2560          !Add * for NO-SHOW
         RETURN
    1 IF(K .GT. 5) RETURN    !Grade not A, B, C, D, or F
      READ(2'N2)(L(I),I=2,5)
      L(1) = 100.
      L(6) = L(5)-10.   !Set 10 pt. range for F (in getting + or -)
      RANGE = .20 * (L(K) - L(K+1))  !20% of range for + or -
      IF( (L(K) - AV) .LT. RANGE)   LG = LG+2816 !Add + 
      IF( (AV - L(K+1)) .LT. RANGE) LG = LG+3328 !Add -
      RETURN
      END
