module Grade where import Data.List (foldl') -- Weighted sum: Each part of the course has a "weight" defined as the fraction -- of the course grade (0 is nothing and 1 is 100%). The course grade is -- calculated by the weighted sum of all parts. weighted_sum :: [(Double, Double)] -> Double weighted_sum = foldl' (\sm (wt, gr) -> sm + wt * gr) 0 -- Average practical grade: The first practical is worth 10% of the course -- grade. The second and third are 20%. The maximum average practicum grade is -- 5. p_average :: Double -> Double -> Double -> Double p_average p1 p2 p3 = weighted_sum [(0.1, p1), (0.2, p2), (0.2, p3)] -- Average test grade: The first test is 20%, and the second is 30%. The maximum -- average test grade is 5. t_average :: Double -> Double -> Double t_average t1 t2 = weighted_sum [(0.2, t1), (0.3, t2)] -- Course grade at the end of the period: If both the practical and the test -- average grades are at least half the maximum average, then the course grade -- is the sum of the averages. Otherwise, the course grade is the minimum of the -- practical and the test grade. course_grade :: Double -> Double -> Double -> Double -> Double -> Double course_grade p1 p2 p3 t1 t2 | p >= 2.5 && t >= 2.5 = p + t | otherwise = min p t where p = p_average p1 p2 p3 t = t_average t1 t2 -- Course grade after the resit test ("aanvullende toets"): The course grade -- after the resit test is the maximum possible grade where the resit test grade -- is substituted for one of the practical or test grades. resit_course_grade :: Double -> Double -> Double -> Double -> Double -> Double -> Double resit_course_grade p1 p2 p3 t1 t2 t_new = maximum [ course_grade t_new p2 p3 t1 t2 , course_grade p1 t_new p3 t1 t2 , course_grade p1 p2 t_new t1 t2 , course_grade p1 p2 p3 t_new t2 , course_grade p1 p2 p3 t1 t_new ]