object GradingPolicy { import scala.math.{min,max,round} val version = "December 2012, Version 1.0" def roundToHalf(grade: Double) : Double = round(grade*2.0)/2.0 def ratioToGrade(ratio: Double) : Double = roundToHalf(5*ratio + 1.24999) def baseGrade(project: Double, theory: Double) = ratioToGrade(0.55*project + 0.45*theory) val threshold = 0.5 def isRatio(x:Double):Boolean = {0.0 <= x && x <= 1.0} // Input: ratios of points achieved relative to maximum possible def finalGrade(project: Double, homeworks: Double, quiz: Double) : Double = { require(isRatio(project) && isRatio(homeworks) && isRatio(quiz)) val theory = 0.45*homeworks + 0.55*quiz val base = baseGrade(project, theory) if (project >= threshold && theory >= threshold) base else min(base, 3.5) } ensuring (result => 1.0 <= result && result <= 6.0) // ==================== Tests ============================= def illustrate(scores : (Double,Double,Double)) = { val (project, homeworks, quiz) = scores val grade = finalGrade(project, homeworks, quiz) printf("project=%4.2f, homeworks=%4.2f, quiz=%4.2f ==> GRADE = %3.1f \n", project, homeworks, quiz, grade) } def main(args : Array[String]) = { List[(Double, Double, Double)]( (0.2 ,0.3 ,0), (0.2 ,0.4 ,0), (0.4 ,0.2 ,0.24), (0.49, 0.5, 0.5), (0.49,1.0,1.0), (0.5 ,0 ,0.23), (0.5 ,0 ,0.25), (0.5, 0.5, 0.5), (0.5,1.0,1.0), (0.51, 0.51, 0.51), (0.6, 0.5, 0.0), (0.6, 0.6, 0.6), (0.6,1.0,1.0), (0.7 ,0.7 ,0.66), (0.7 ,0.7 ,0.88), (0.7 ,0.8 ,0.87), (0.7,1.0,1.0), (0.8 ,0.6 ,0.75), (0.8 ,0.7 ,0.63), (0.8 ,0.7 ,0.85), (0.8 ,0.8 ,0.78), (0.8, 0.8, 0.0), (0.8,1.0,1.0), (0.9 ,0.7 ,0.59), (0.9 ,0.8 ,0.63), (0.9 ,0.8 ,0.8), (0.9 ,0.9 ,0.88), (0.9,1.0,1.0), (1 ,0.8 ,0.88), (1 ,1.0 ,0.91), (1.0,0.2,1.0), (1.0,1.0,0.2), (1.0,1.0,0.2), (1.0,1.0,1.0) ) foreach illustrate } }