This is the specification for both the contents and the structure of the rubric archive to be used for grading.
If you aren't familiar with JSON, you'll need to learn that first...
You'll need all of the following files:
These files represent the homework solutions. They must be named without the _soln
suffix, and must be the original .m
file.
This file must be called submission.json
or resub.json
, and contains the JSON (specified later) for this homework set.
These files contain all the variables needed by a specific function (as specified in the rubric). They must be called problemName.mat
.
If your code needs external file resources (i.e., a text file
or image file
) include these as well.
submission
folder is for grading the original submissionresub
folder is for grading the resubmissionassets
folder holds all the releasable zip
filesstudent
folder holds what will be given to the student, and has no rubricsSolutions
SupportingFiles
The organization of the archive is simple and intuitive.
At the top level of the archive, you should have:
A folder for the zipped assets (assets
).
A folder for the submission grader (submission
).
A folder for the resubmission grader (resub
).
A folder for the student data (student
).
Inside the submission
and resub
folders, you have the following organization:
A folder for the solutions (Solutions
). This folder contains all the .m
files.
A folder for the supporting files (SupportingFiles
). This folder contains all .mat
(variables), as well as any other supporting files.
Note that the input variable mat
file must be called problemName.mat
The JSON files specifying the rubric, called rubric.json
A visual rendering of this format is shown below:
assets
student.zip
submission.zip
resub.zip
student
problemOne_soln.p
problemOne.mat
submission
rubric.json
Solutions
problemOne.m
problemTwo.m
SupportingFiles
problemOne.mat
problemTwo.mat
problemOneSupport.txt
resub
rubric.json
Solutions
problemOne.m
problemTwo.m
SupportingFiles
problemOne.mat
problemTwo.mat
problemOneSupport.txt
All fields must be present, though their value can be empty. Values can not be null
Additionally, fields marked as an array
must be an array, even if 0 or 1 element(s) long.
The JSON is made up of Problem
s, which represent the complete information to grade a single homework problem.
A Problem
has the following fields:
name
: A string. The name of the problem, such as myProblem
. This name should be identical to the solution file name without the extension.banned
: An array of strings. The names of banned functions.isRecursive
: A boolean. If true, the student code must be recursive to receive any points. To learn more about recursion checking, see checkRecur
.supportingFiles
: An array of strings. The full names (including extensions) or supporting files. This should include the myFunction.mat
file.testCases
: An array of TestCase
s. See below for more information.
A Problem
is made up of TestCase
s, which represent individual calls.
A TestCase
has the following fields:
inputs
: An array of strings. Each string represents the name of that input (i.e., the first string is the first input name, etc.). These names should match the inputs.mat
variables.outputs
: An array of strings. Each string represents the name of that output, just like with inputs
.points
: A number. The amount of absolute points this test case is worth. Note that the total points need not add up to 100 - any points after 100 are considered to be extra credit.Below is an example of what the JSON could possibly look like...
[ { "name": "luge", "banned": [ "find", "strfind", "textscan" ], "isRecursive": false, "supportingFiles": [ "luge_submission.mat" ], "testCases": [ { "inputs": [ "in1" ], "outputs": [ "str1" ], "points": 6 }, { "inputs": [ "in2" ], "outputs": [ "str2" ], "points": 6 }, { "inputs": [ "in3" ], "outputs": [ "str3" ], "points": 7 } ] }, { "name": "olympicTorch", "banned": [], "isRecursive": false, "supportingFiles": [ "olympicTorch_submission.mat" ], "testCases": [ { "inputs": [ "in1", "in2" ], "outputs": [ "result1" ], "points": 6 }, { "inputs": [ "in3", "in4" ], "outputs": [ "result2" ], "points": 6 }, { "inputs": [ "in5", "in6" ], "outputs": [ "result3" ], "points": 6 } ] }, { "name": "zamboni", "banned": [], "isRecursive": false, "supportingFiles": [ "zamboni_submission.mat", "bruins2.png", "checkerboard2.png", "flag2.png", "spongebobimg2.png" ], "testCases": [ { "inputs": [ "in1" ], "outputs": [], "points": 4 }, { "inputs": [ "in2" ], "outputs": [], "points": 5 }, { "inputs": [ "in3" ], "outputs": [], "points": 5 }, { "inputs": [ "in4" ], "outputs": [], "points": 5 } ] }, { "name": "pascalsPodium", "banned": [ "nchoosek", "pascal" ], "isRecursive": false, "supportingFiles": [ "pascalsPodium_submission.mat" ], "testCases": [ { "inputs": [ "in1" ], "outputs": [ "podium1" ], "points": 6 }, { "inputs": [ "in2" ], "outputs": [ "podium2" ], "points": 6 }, { "inputs": [ "in3" ], "outputs": [ "podium3" ], "points": 7 } ] }, { "name": "roundRobin", "banned": [], "isRecursive": false, "supportingFiles": [ "roundRobin_submission.mat" ], "testCases": [ { "inputs": [ "in1" ], "outputs": [ "result1" ], "points": 6 }, { "inputs": [ "in2" ], "outputs": [ "result2" ], "points": 6 }, { "inputs": [ "in3" ], "outputs": [ "result3" ], "points": 7 } ] }, { "name": "cryptex", "banned": [], "isRecursive": false, "supportingFiles": [ "cryptex_submission.mat", "charStruct.mat", "letterChecker.p", "day.png", "funTimesAreFun.png", "scary.png" ], "testCases": [ { "inputs": [ "in1", "in2" ], "outputs": [], "points": 6 }, { "inputs": [ "in3", "in4" ], "outputs": [], "points": 7 }, { "inputs": [ "in5", "in6" ], "outputs": [], "points": 7 } ] } ]