Custom part types

The custom part type editor

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.

Input hint for question author

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.

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 string input method as it appears to the student: a text input box

The student enters a single line of text.

Input options

Label

Name

Data type

Description

Allow student to submit an empty string?

allowEmpty

boolean

If false, the part will only be marked if their answer is non-empty.

The answer is a string.

Number

The number input method as it appears to the student: a text input box which only accepts numbers.

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.

Input options

Label

Name

Data type

Description

Allow fractions?

allowFractions

boolean

Allow the student to enter their answer as a fraction?

Allowed notation styles

allowedNotationStyles

list of string

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 mathematical expression input method as it appears to the student: a text input box with a LaTeX rendering to the right.

The student enters a JME expression.

Input options

Label

Name

Data type

Description

Show preview of student’s answer?

showPreview

boolean

If true, a LaTeX rendering of the student’s answer will be shown next to the input box.

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 matrix method as it appears to the student: a grid of text inputs under a pair of boxes to set the number of rows and columns.

The student enters a two-dimensional array of values.

Input options

Label

Name

Data type

Description

Allow student to change size of matrix?

allowResize

boolean

If true, the student can change the size of the matrix. Otherwise, it is fixed to the specified size.

Number of rows

numRows

number

The initial number of rows in the input matrix.

Number of columns

numColumns

number

The initial number of rows in the input matrix.

Parse cell values

parseCells

boolean

If true, the answer will be a matrix of numbers. Otherwise, it is a 2-dimensional list of lists of string values.

Allowed notation styles

allowedNotationStyles

list of string

The allowed styles of number notation.

Allow fractions?

allowFractions

boolean

Allow the student to enter numbers as fractions?

Show brackets?

showBrackets

boolean

If true, parentheses are drawn on the left and right of the matrix.

Row headers

rowHeaders

list

Text to show on the left of each row. One string for each row.

Column headers

columnHeaders

list

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.

Radio buttons

The radio buttons input method as it appears to the student: a list of options with radio buttons next to them.

The student chooses one from a list of choices by selecting a radio button.

Input options

Label

Name

Data type

Description

Choices

choices

list of string

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.

Choose several from a list

The "choose several from a list" input method as it appears to the student: a list of options with checkboxes next to them.

The student chooses any number of items from a list of choices by ticking checkboxes.

Input options

Label

Name

Data type

Description

Choices

choices

list of string

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 drop-down box input method as it appears to the student: a drop-down box containing the available choices.

The student chooses one from a list of choices in a drop-down box.

Input options

Label

Name

Data type

Description

Choices

choices

list of string

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 and input_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 and interpreted_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.

Numbas demo: custom part types