program gradeval ! Evaluates calculated vs. "true" gpa. implicit none real g ! Raw "true" grade. 100 point max, 90-100=A, 80 - <=90 is B etc. real gpa ! Calculates GPA as a function of g and grading system. real gpa_err ! Calculates rms error in GPA as a function of g and grading sys real teacherr! Calculates the rms error in assigned gpa due to teacher errors. external teacherr real old ! Old(g) returns quality points for g under old system. external old real new ! new(g) returnes quality points for g under new system. external new real sd ! standard deviation of noise in grades character*80 sd_char !character representation of sd from command line !Argument passing declarations. Note: getarg is not standard f90 external getarg integer*4 iargc external iargc character*80 student_gpa_file,teacher_gpa_file !Output files character*80 myname !the name of the executable of this program call getarg(0,myname) if (iargc()<>3) then write(*,*) "Syntax:" write(*,*) trim(myname)//" sd student_file teacher_file" write(*,*) "where" write(*,*) "sd=standard deviation of both student grades and teacher errors" write(*,*) "student_file is output file of student grades" write(*,*) "teacher_file is output file of teacher grades." stop end if !Read command line arguments call getarg(1,sd_char) read(unit=sd_char,fmt=*) sd call getarg(2,student_gpa_file) call getarg(3,teacher_gpa_file) !Generate the effects of new and old system on student GPA's open(11,file=student_gpa_file) write(11,*) "Student GPAs, for SD=", sd write(11,90) "Raw","Old GPA","New GPA","Diff","Old RMS Error","New RMS Error" do g=50,100,0.1 write(11,100) g,gpa(old,g,sd),gpa(new,g,sd),gpa(new,g,sd)-gpa(old,g,sd),gpa_err(old,g,sd),gpa_err(new,g,sd) end do 90 format(A5,3A10,2A17) 100 format(F5.1,3F10.3,2F17.3) close(11) !Now let's find the rms error in the assigned gpa due to errors !in grading under the new and old systems. open(11,file=teacher_gpa_file) write(11,*) "Errors in QPs due to errors in teacher scores, for SD=", sd write(11,190) "Raw","Old QP","New QP","Old Grading Err","New Grading Err" 190 format(A5,2A10,2A17) 200 format(F5.1,2F10.3,2F17.3) do g=50,100,0.1 write(11,200) g,gpa(old,g,sd),gpa(new,g,sd),teacherr(old,g,sd),teacherr(new,g,sd) end do close(11) stop end function gpa(func,g,sd) ! Calculate the gpa the student would have under system given by "func", ! given a mean grade of g and a standard deviation of sd. ! P(offset,sd) describes the probability of receiving a score that ! differs by offset from the grade g. sd is the the standard deviation ! of the probability distribution P. real gpa !the calculated gpa real:: func ! func(g) returns quality points for g under gradings system ! of interest. external func real,intent(in):: g !raw grade. real, intent(in)::sd !standard deviation of grade distribution (typical noise in grades) real offset !Offset of a noisy grade from "true" grade real denom real step real P external P real true external true !Integrate probability P*func(grade) over +/- sd standard devations gpa=0.0 denom=0.0 step=sd/200.0 do offset=-4.0*sd,4.0*sd,step gpa=gpa+P(offset,sd)*func(g+offset) denom=denom+P(offset,sd) end do gpa=gpa/denom return end function gpa_err(func,g,sd) ! Calculate the gpa the student would have under A,B,C,D system. implicit none real gpa_err !the calculated gpa real func ! func(g) returns quality points for g under gradings system ! of interest. external func real g !raw grade. real sd !standard deviation of grade distribution (typical noise in grades) real offset !Offset of a noisy grade from "true" grade real denom real step real P external P real true external true !Integrate probability P*(func(grade)- true grade)^2 ! over +/- 4 standard devations gpa_err=0.0 denom=0.0 step=sd/200.0 do offset=-4.0*sd,4.0*sd,step gpa_err=gpa_err+P(offset,sd)*(func(g+offset)-true(g+offset))**2 denom=denom+P(offset,sd) end do gpa_err=sqrt(gpa_err/denom) return end function old(g) real old !quality points under old system. real g !raw grade if (g >= 90) then old=4.0 else if (g >= 80) then old=3.0 else if (g >= 70) then old=2.0 else if (g >= 60) then old=1.0 else old=0.0 end if return end function new(g) real new !quality points under new system real g !raw score if ( g >= 93.333 ) then new=4.0 else if (g >= 90.0) then new=3.667 else if (g >= 86.667) then new=3.333 else if (g >=83.333 )then new=3.0 else if (g >= 80) then new=2.667 else if (g >=76.667) then new=2.333 else if (g>=73.333) then new=2.0 else if(g>=70.0) then new =1.667 else if (g>=66.667) then new=1.333 else if (g >=63.333) then new=1.0 else if (g>=60.0) then new=0.667 else new=0.0 end if return end function true(g) real true real g !calculates "true" gpa, the one you would have if there were no noise. !Assumes linear mapping of 10 point scale, 1.0=65,2.0=75,3.0=85,4.0=95. !But all grades over 95 are 4.0, all grades under 60 are 0.0 if (g>=95) then true=4.0 else if (g<60) then true=0.0 else true=(g-55.0)/10.0 end if return end function P(offset,sd) !Calculates probability of a certain offset with standard deviation sd. real P real offset real sd P=exp(-offset**2/(2*sd**2)) return end function teacherr(func,g,sd) real teacherr !Calculates the rms error in the assigned quality points, assuming !the teachers assigned raw grade g has an rms error sd real g ! raw grade real sd !rms error in raw grade assigned real right !the quality points the student should have received. real func !the gpa assignment function external func real offset !Error from true raw grade real denom !Normalization factor teacherr=0.0 denom=0.0 step=sd/100.0 do offset=-4*sd,4*sd,step teacherr=teacherr+P(offset,sd)*(func(g+offset)-func(g))**2 denom=denom+P(offset,sd) end do teacherr=sqrt(teacherr/denom) if (teacherr<0) write(*,*) "Error: teacherr=",teacherr return end