Rubric Specification


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...

Quick Reference


You'll need all of the following files:

  • Solution files
  • JSON rubric files
  • Variable files
  • Supporting files

What You'll Need


Solution Files

These files represent the homework solutions. They must be named without the _soln suffix, and must be the original .m file.

JSON Rubric

This file must be called submission.json or resub.json, and contains the JSON (specified later) for this homework set.

Variable Files

These files contain all the variables needed by a specific function (as specified in the rubric). They must be called problemName.mat.

Supporting Files

If your code needs external file resources (i.e., a text file or image file) include these as well.

Quick Reference


  • The submission folder is for grading the original submission
  • The resub folder is for grading the resubmission
  • The assets folder holds all the releasable zip files
  • The student folder holds what will be given to the student, and has no rubrics
  • Solutions should be placed in Solutions
  • Supporting files should be placed in SupportingFiles
  • JSON rubric files should be at the top level of the submission type

Detailed Structure


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

The Rubric JSON

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.

Problem

The JSON is made up of Problems, 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 TestCases. See below for more information.

Test Case

A Problem is made up of TestCases, 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
			}
		]
	}
]