Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constraint and Or Graders #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/ConstraintGrader.fun
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
functor ConstraintGrader (structure Constraint : GRADER
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity - what's the benefit of having structure Constraint : GRADER rather than, say, constraint : bool (or unit -> bool)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how you would do this with just bool or a unit->bool?

My idea was that it simply runs the Constraint grader and if it passes that then it would run the normal grader (rather than running the normal grader and having a TA manually grade the code). I'm unsure of any other clean way to use the existing infrastructure to run student code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, gotcha. I was thinking you could use Result.evaluate, but I guess you'd have to rewrite some boilerplate (run a list of tests, etc.).

structure Standard : GRADER
val threshold : Rational.t
val message : string) :> GRADER =
struct
structure Rubric =
struct
val description = Standard.Rubric.description

datatype t = Violation
| Result of Standard.Rubric.t

val toString = fn Violation => message
| Result r => Standard.Rubric.toString r

val score = fn Violation => Rational.zero
| Result r => Standard.Rubric.score r
end

val process = fn () =>
let
val score = Constraint.Rubric.score (Constraint.process ())
in
case Rational.compare (threshold, score) of
GREATER => Rubric.Violation
| _ => Rubric.Result (Standard.process ())
end
end
30 changes: 30 additions & 0 deletions src/OrGrader.fun
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
functor OrGrader (val description : string
structure Grader1 : GRADER
structure Grader2 : GRADER) :> GRADER =
struct
structure Rubric =
struct
val description = description

datatype t = Result1 of Grader1.Rubric.t
| Result2 of Grader2.Rubric.t

val toString = fn Result1 r => Grader1.Rubric.toString r
| Result2 r => Grader2.Rubric.toString r

val score = fn Result1 r => Grader1.Rubric.score r
| Result2 r => Grader2.Rubric.score r
end

val process = fn () =>
let
val rubric1 = Grader1.process ()
val score1 = Grader1.Rubric.score rubric1
val rubric2 = Grader2.process ()
val score2 = Grader2.Rubric.score rubric2
in
case Rational.compare (score1, score2) of
LESS => Rubric.Result2 process2
| _ => Rubric.Result1 process1
end
end
6 changes: 6 additions & 0 deletions src/sources.cm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Library
functor EquivGraderBucketList
functor EquivGraderList

functor ConstraintGrader
functor OrGrader

functor Preamble

structure FormatUtil
Expand Down Expand Up @@ -49,6 +52,9 @@ is
EquivGraderBucket.fun
EquivGrader.fun

ConstraintGrader.fun
OrGrader.fun

Preamble.fun

FormatUtil.sml