Custom part types#
Custom part types allow you to reuse marking algorithms you’ve written, while providing fields for the part’s settings, like the built-in parts.
Creating a new part type#
To create a new custom part type, click on your user icon at the top of the page, and then Profile. Once on your profile, click Part types, and then Create a new part type.
The first step is to pick a name for your part type. It should concisely describe what the part type is for, ideally by describing how the student should answer it or how it is marked. For example, “Give a root of a function” is a good name for a part type where the student has to provide a value which is mapped to zero by a function defined by the question author.
You can change the name of your part type later on if you need to.
The editing interface for custom part types is arranged similarly to the question and exam editors: the sections are separated into tabs, and you should work through them all in order to define how the part type works.
Description#
- Name#
The name of the part type as it appears in the question editor. It should concisely describe what the part type is for, ideally by describing how the student should answer it or how it is marked. For example, “Give a root of a function” is a good name for a part type where the student has to provide a value which is mapped to zero by a function defined by the question author.
- Description#
Use this field to describe how this part type works, and what kinds of questions it is appropriate for. This text will appear in the list of part types on your profile, and in the public list if you make your part type public, to help question authors decide if the part type is right for their use.
- URL of documentation#
Use this field to provide a link to any more documentation about your custom part type. You might link to a blog post explaining what the part type is for, or a page giving more information on the theory behind the part type.
Required extensions#
If your part type requires functions from a Numbas extension, select it here. Any questions using this part type will automatically load the required extensions.
Part settings#
Define setting fields to allow question authors to configure your part type. They appear in the question editor’s Marking settings tab for any parts of this type.
Each setting produces a JME value which can be used to set up the part type’s answer input and in the marking algorithm.
There is a dictionary variable called settings
with keys for each setting.
For example, a setting with name correct_answer
will be available as settings["correct_answer"]
.
The following fields are common to all setting types:
- Name#
A short name for this setting, used to refer to it in the part type’s answer input or marking algorithm. The name should uniquely identify the setting, but doesn’t need to be very descriptive - the label can do that.
- Label#
The label shown next to the setting in the question editor. Try to make it as clear as possible what the setting is for. For example, a checkbox which dictates whether an input hint is shown should be labelled something like “Hide the input hint?” rather than “Input hint visibility” - the latter doesn’t tell the question author whether ticking the checkbox will result in the input hint appearing or not.
- Help URL#
The address of documentation explaining this setting in further depth. This is optional.
Use this field to give further guidance to question authors about this setting, if the label is not enough. For example, you might use this to say what data type a JME code setting should evaluate to.
- Default value#
The initial value of the setting in the question editor. If the setting has a sensible default value, set it here. If the value of the setting is likely to be different for each instance of this part type, leave this blank. (Not present for Drop-down box or Choose one or more
Setting types#
String#
A string of text. If Substitute values into text is ticked, then JME expressions enclosed in curly braces will be evaluated and the results substituted back into the text when the question is run. Otherwise, the string will be untouched.
Mathematical expression#
A mathematical expression, in JME syntax. If Substitute variables into value? is ticked, then JME expressions enclosed in curly braces will be evaluated and the results substituted back into the string.
This setting type produces a value of type expression
.
Checkbox#
If the question author ticks the checkbox, this setting type produces true
, otherwise it produces false
.
Drop-down box#
The question author must pick one option from a list that you provide. The Label field is shown to the question author, and the setting produces the Value field as a string.
Choose one or more#
The choices are presented to the question author as a list, with a checkbox next to each label. This setting type produces a list containing the Value fields of ticked choices, as strings.
If Default on? is ticked for a particular choice, that choice is selected when a new part of this type is created.
JME code#
A code editing area for the question author to write a JME expression.
If Evaluate? is ticked, the expression will be evaluated when the question is run, and the setting produces the resulting value. The evaluation happens inside the question’s scope, so any variables and functions defined by the question author are substituted in before evaluation.
If Evaluate? is not ticked, this setting will produce a expression
value representing the question author’s expression.
Percentage#
A sliding scale between 0% and 100%.
This setting type produces a number between 0 and 1.
HTML content#
An HTML content area.
If Substitute variables into value? is ticked, then JME expressions enclosed in curly braces will be evaluated and the results substituted back into the text.
List of strings#
This setting type produces a list of strings entered by the question author.
If Substitute variables into value? is ticked, then JME expressions enclosed in curly braces in each string will be evaluated and the results substituted back in.
Answer input#
The answer input method determines how the student enters their answer to the part.
The following fields are common to all input methods:
- Expected answer#
A JME expression which evaluates to the expected answer to the part.
Available in the marking algorithm as
input_options["correctAnswer"]
.- Input hint#
A string displayed next to the input field, giving any necessary information about how to enter their answer.
If there are any requirements the student’s answer must meet that aren’t obvious from the way the input is displayed, for example a maximum length or required number of decimal places, these should be described here.
Available in the marking algorithm as
input_options["hint"]
.
Many of the fields can be either static or dynamic.
A static field takes the same value in every instance of the part type.
A dynamic field is defined by a JME expression which is evaluated when the question is run.
You can use the part’s settings in these expressions with the settings
variable.
The values of input_options are available in the marking script under the input_options
dictionary.
In the tables below, the Name column gives the key in the dictionary corresponding to the option.
Answer input methods#
String#
The student enters a single line of text.
Label |
Name |
Data type |
Description |
---|---|---|---|
Allow student to submit an empty string? |
|
If |
The answer is a string
.
Number#
The student enters a number, using any of the allowed notation styles. If the student’s answer is not a valid number, they are shown a warning and can not submit the part.
Label |
Name |
Data type |
Description |
---|---|---|---|
Allow fractions? |
|
Allow the student to enter their answer as a fraction? |
|
Allowed notation styles |
|
The allowed styles of number notation. |
The answer is a number
, as interpreted by parsenumber
.
If the student’s answer is not a valid representation of a number, the part will not be submitted.
If you wish to allow number notation styles other than those built-in, a string input is more appropriate, so you can parse the student’s answer yourself in the marking script.
Mathematical expression#
The student enters a JME expression.
Label |
Name |
Data type |
Description |
---|---|---|---|
Show preview of student’s answer? |
|
If |
The answer is an expression
value corresponding to the student’s input.
If the student’s answer is not a valid expression, the part will not be marked.
Matrix#
The student enters a two-dimensional array of values.
Label |
Name |
Data type |
Description |
---|---|---|---|
Allow student to change size of matrix? |
|
If |
|
Number of rows |
|
The initial number of rows in the input matrix. |
|
Number of columns |
|
The initial number of rows in the input matrix. |
|
Parse cell values |
|
If |
|
Allowed notation styles |
|
The allowed styles of number notation. |
|
Allow fractions? |
|
Allow the student to enter numbers as fractions? |
|
Show brackets? |
|
If |
|
Row headers |
|
Text to show on the left of each row. One string for each row. |
|
Column headers |
|
Text to show above each column. One string for each column. |
If parseCells
is true
, the answer is a matrix
value corresponding to the student’s input.
The part will not be marked unless all of the cells in the student’s matrix are valid numbers.
If parseCells
is false
, the answer is a list
of lists of string
values.
Choose several from a list#
The student chooses any number of items from a list of choices by ticking checkboxes.
Label |
Name |
Data type |
Description |
---|---|---|---|
Choices |
|
The labels for the choices to offer to the student. |
The answer is a list
of booleans
describing whether the student ticked the corresponding choice.
Drop-down box#
The student chooses one from a list of choices in a drop-down box.
Label |
Name |
Data type |
Description |
---|---|---|---|
Choices |
|
The labels for the choices to offer to the student. |
The answer is the index of the student’s choice in the list. The first item in the list is index 0.
The part will not be marked unless the student selects one of the choices.
Marking#
The Marking tab is where you construct the marking algorithm for your part type.
The interface is similar to that for question variables - a list of defined notes is shown on the right-hand side, and the currently selected note is shown on the left.
The two required notes, mark
and interpreted_answer
, can not be deleted.
- Name#
The name of the note. This must be a valid JME variable name.
- Definition#
A JME expression used to evaluate the note.
See the list of variables available in a marking script, in particular
studentAnswer
,settings
andinput_options
.- Description#
Describe what the note means, and how it is used.
You should try to describe the value the note produces, as well as any feedback.
Note
Don’t underestimate the value of the description field! Notes whose meaning seems clear when you write them have a habit of becoming indecipherable months later.
- Depends on#
A list of all notes used in this note’s definition. You can click on a note’s name to go to its definition. If the note hasn’t been defined yet, it’ll be created.
- Used by#
A list of all notes which use this note in their definition. You can click on a note name to go to its definition.
Making sure that the marking algorithm works#
You must make sure that your part type will mark all possible answers that a student can enter.
Decide how you want to handle different kinds of “invalid” input - do you want to strip space characters from the student’s answer, for example?
Use the fail
function to stop the marking algorithm and force the student to change their answer before resubmitting, if the student’s answer is of a form .
However, it’s important not to reject plausible answers that are simply incorrect - you should make every effort to accept answers that follow the input hints you’ve given.
There’s no facility to test the marking algorithm inside the custom part type editor - for this, you need to create an instance of the part type inside a question so you can configure its settings.
When a student attempts a question using a custom part type, if any errors are encountered while evaluating your part type’s marking algorithm, the student will be shown a generic error asking them to report the problem. In order to see what the problem is, you’ll have to reproduce the student’s input in the question editor’s marking algorithm tab. A more descriptive error message, detailing the note affected and the exact nature of the error, will be shown.
Access#
Your custom part types are available only to you, and other members of projects you belong to. If you’ve created a part type that could be useful to others, please consider publishing it.
Before a custom part type can be published, the following conditions must be met:
The part type must have a name and a description.
There must be at least one setting, and all settings must be complete.
The expected answer and input hint must be set.
The
mark
andinterpreted_answer
notes must be defined.
To publish a part type, click the Publish button in the Access tab.
You can unpublish a part type by clicking the Unpublish button. It will no longer be available to other users when creating new parts, but any instances of the part in existing questions will remain in place.
Examples#
A question in the Numbas demo demonstrates a few custom part types.