diff --git a/src/prod/CurProdCombiner.sml b/src/prod/CurProdCombiner.sml new file mode 100644 index 0000000..bc1c344 --- /dev/null +++ b/src/prod/CurProdCombiner.sml @@ -0,0 +1,39 @@ +functor CurProdCombiner ( + val descriptions : string list + val weights : int list +) = +struct + local + val fst = fn (x, _) => x + val snd = fn (_, x) => x + + val total = List.foldr Int.+ 0 weights + val fractions = List.map ( + case total of + 0 => Fn.const Rational.one + | _ => Fn.curry (Fn.flip Rational.//) total + ) weights + + val combine = fn (percent,description) => percent ^ " " ^ description + val format = fn L => (* todo: better name? *) + String.concat ( + ListPair.map format ( + ListPair.map combine ( + ListPair.map FormatUtil.showPercents ( + List.map snd L, + fractions + ), + descriptions + ), + (List.map fst L) + ) + ) + + val weightedAverage = + List.foldr Rational.+ Rational.zero + o Fn.curry (ListPair.map Rational.*) fractions + in + val combine = fn L => (* todo: better name? *) + ( format L, weightedAverage (List.map snd L) ) + end +end diff --git a/src/prod/CurProdGrader2.sml b/src/prod/CurProdGrader2.sml new file mode 100644 index 0000000..d134c3b --- /dev/null +++ b/src/prod/CurProdGrader2.sml @@ -0,0 +1,25 @@ +functor CurProdGrader2 ( + val description : string + structure Grader1 : GRADER + structure Grader2 : GRADER + (* val descriptions : string * string *) + (* ^ maybe include with weights? *) + val weights : int * int +) :> GRADER = NewProdGrader2( + val description = description (* remove? *) + structure Grader1 = Grader1 + structure Grader2 = Grader2 + + local + val (w1, w2) = weights + structure Combiner = CurProdCombiner ( + val descriptions = [ + Grader1.Rubric.description, + Grader2.Rubric.description + ] + val weights = [w1, w2] + ) + in + open Combiner + end +) diff --git a/src/prod/NewProdGrader2.sml b/src/prod/NewProdGrader2.sml new file mode 100644 index 0000000..e255050 --- /dev/null +++ b/src/prod/NewProdGrader2.sml @@ -0,0 +1,43 @@ +functor NewProdGrader2 ( + val description : string + structure Grader1 : GRADER + structure Grader2 : GRADER + val combine : (string * Rational.t) list -> (string * Rational.t) +) :> GRADER = + struct + structure Rubric = + struct + val description = description + + type t = { + g1 : Grader1.Rubric.t, + g2 : Grader2.Rubric.t + } + + local + val fst = fn (x,_) => x + val snd = fn (_,x) => x + + val strings = fn {g1=g1,g2=g2} => [ + Grader1.Rubric.toString g1, + Grader2.Rubric.toString g2 + ] + val scores = fn {g1=g1,g2=g2} => [ + Grader1.Rubric.score g1, + Grader2.Rubric.score g2 + ] + + val combined = fn rubric => + combine (ListPair.zip (strings rubric, scores rubric)) + in + val toString = fst o combined + + val score = snd o combined + end + end + + val process = fn () => { + g1 = Grader1.process (), + g2 = Grader2.process () + } + end