Rumbas (Rust + Numbas)

What is Rumbas ?

  • A system to create online (randomized) (math) exercises, build on top of Numbas.
    • It is useful to https://docs.numbas.org.uk/en/latest/jme-reference.html
  • All features of Numbas, are available in rumbas.
    • Randomised questions
      • You can use the Numbas JME language to generate random numbers, do calculations, etc.
    • Diagnostic mode: the exam reacts to the student's performance to choose appropriate questions.
    • Rich interaction: easy to include graphics, videos and interactive diagrams (GeoGebra and JSXGraph) through extensions.
    • Many answer types: numbers, mathematical expressions, multiple choice, matrix ...
    • Automatic and immediate marking
    • In your language: translated in 19 languages and counting.
    • LTI Integration: The Numbas LTI tool makes it easy to add Numbas assessments to virtual learning environments such as Blackboard, Canvas, Moodle and Brightspace.
      • The result of a rumbas compilation is a Numbas exam, so all information you find about using numbas exams, can be used for rumbas exams.
    • Extensions: a specific subset of all Numbas extensions is supported
  • More features:
    • Multi language: easily make the same exam available in different languages
    • Templating: when you create different questions/exams that are almost identical, you can extract these identical parts to a template to reduce redundancy.
    • Version control systems (like git) can be used 🎉:
      • Text-based: yaml (and html and tex) specifications are converted to an web-based exam.
  • Currently in beta, not all features are implemented yet.
  • Do you want to use it? Read the Tutorial.

How does rumbas work?

  • The content of exams and questions are specified in a subset of YAML. Please consult our reference for the specifics.
  • The rumbas program converts these descriptions in YAML subset to a Numbas exam
  • The rumbas program uses the Numbas codebase to convert these Numbas exams to an html exam.

Getting Started

This Getting Started Guide will learn you

  • how to setup your own rumbas repo on Github, with a complete development environment using Github Codespaces
  • to write and run your first question
  • to write and run your first exam (TODO?)
  • to get familiar with possible next steps to make more advanced use of rumbas (TODO).

It assumes a minimal familiarity with VSCode.

Create an empty rumbas repository

While you can use rumbas locally on your PC, the quickest way to get started is to use a Github Codespace from a template:

Task

  • Create a free Github account if you don't have one yet.

  • Click on Open in GitHub Codespaces and accept all settings and clich the green 'Create codespace' button. Don't panic on the 'Codespace usage for this repository is paid for by ' message: basic usage is free, and you'll be warning if charges would apply after using your codespace for hours...

  • You now have a VSCode interface in your browser with a mostly empty folder, but with the most recent rumbas version installed and ready to go.

    • Open a terminal, and run rumbas --version to check if the setup is working.

Note that you won't be able to easily save your work. If you've decided to make more serious use of rumbas, consider creating your own repo, and/or run rumbas locally on your PC with Docker:

  • Go to https://github.com/m8rex/rumbas-codespaces-template, and click on the green 'Use this template' button to create your personal rumbas-repository by choosing the 'Create a new repository' option.

    • Place it under your personal account
    • Choose a name
    • Decide whether it should be a private or public repo.
    • You'll be sent to your new repo.
  • In your newly created repo, click on the green 'Code' button, use the 'Codespaces' tab and click on the green 'Create codespace on main' button (or on the plus icon if you've already used Codespaces before...).

More information and different options to use rumbas can be found in the installation guide

Initialise you new rumbas project

Task

Run the command rumbas init to initialise the a rumbas project.

You can either do this in a Terminal, or click on the Initialise Project button on the taskbar at the bottom of the screen. The create rumbas project button

This command will create a bunch of folders and files that you can explore later. Important for now is that all your questions will go in separate files in questions, and all your exams similarly go into files in the folder exams.

Info

The folder structure of a rumbas project is important. Some names are reserved and have a special meaning.

  • A folder named defaults that contains the default specifications
  • A folder named questions that contains the questions
  • A folder named exams that contains the exams
  • A folder named themes the contains your custom themes
  • A folder named custom_part_types that contains custom_part_types
  • A folder named resources that contains the resources that are used in exams or questions.

Create our first question

Create a first question about the price for shoes after a discount by pasting the appropriate YAML content into a new file questions/shoes.yaml.

Task

  • Create the file questions/shoes.yaml (this is a shoes.yaml file in the questions folder), (e.g. by right clicking on the questions folder, selecting New File and naming the file shoes.yaml)
  • Add the following yaml code to the questions/shoes.yaml file (with Copy/Paste):
---
type: normal # This is just a normal questions
# set the statement
statement: |
      You want to buy a pair of shoes, but wait for the sales to start.
      <br/>
      Originally, a pair of shoes was priced $\var{price_orig}$ euro.
      You now get a $\var{percent}$% reduction.
parts: # specifythe parts of the questions
  - type: gapfill # the first (and only) part is of type gapfill
    prompt: How much are the shoes now? [[0]] # [[0]] is used to place the first gap (index 0)
    gaps: # specify each gap
      - type: number_entry # the first (and only) gap has type number_entry
        answer: price_now # this is the correct answer (the variable `price_now`)
        marks: 1 # the amount of marks awarded when answered correctly
variables: # The variables for our question
  price_orig: random(15,20,25,30,35) # a random element of this list
  percent:    random(20,30,40,50,60) # a random element of this list
  price_now:  price_orig*(1-percent/100) # the answer

Compile our first question

Task

Compile the question.

You can either run the command rumbas compile questions/shoes.yaml in a Terminal, or click the Compile file button on the taskbar at the bottom of the screen.

(The Compile filebutton will compile the current file !)

There will now be a completely standard Numbas preview in the folder _output/en/questions/shoes.

View and test your first question

Task

Start the Live Server extension by clicking on the Go Live button on the taskbar at the bottom of the screen. It is located on the right side.

This will open a browser window with the contents of the _output folder.

Click through the folder structure to reach you question.

Task

Answer the question and check if the answer is correct.

Use the Try another question like this one button to try another question, with different random values.

Installation

  • The easiest way to experiment with rumbas, is by using it in Github Codespaces.
  • You can also install it on your own device by installing docker
  • It is also possible to install it completely manual, but this is not recommended.

Github Codespace

The easiest way to try out rumbas is in Github Codespaces. You don't need any installation. You do, however, need a Github Account. Which you can create for free.

It is best to use the last released version as described here.

Running the last released version

  • Log in to your Github account (or create one if you don't have one yet).
  • Follow the steps in the rumbas codespaces template repo to load a github codespace with the latest released version of rumbas.
  • You will now have a VSCode interface in your browser.
  • Open a terminal within the VSCode interface and type rumbas --version to check if the setup is working.
  • You can (after generating exams) use the installed Live Server extension to show the generated exams. Click on the 'Go Live' button in the right bottom corner.

Running the latest (non released) version

Danger

This setup is not recommended. Only use this section if you want to test features of a rumbas version that is not yet released.

Log in to your Github account (or create one if you don't have one yet).

Click on the following link to open the examples of this book in Github Codespaces. You can then run the examples in the browser.

Open in GitHub Codespaces

Github Codespaces will do the following:

  • Build the latest rumbas version, this might take a few minutes.
  • Open a visual studio code window in the browser
  • Open the main folder of the rumbas repo

What should you do:

  • Click on the menu ocon in the left top corner.
  • Go to 'File' -> 'Open folder'.
  • Select one of the subfolders of the /workspaces/rumbas/examples folder.
  • The codespace will reload.
  • All exams and questions in the folder will be compiled.
  • You can use the installed Live Server extension to show the generated exams. Click on the 'Go Live' button in the right bottom corner.
  • You can use the 'Open folder' trick again to open a different example.
  • You can close the codespace by clicking on 'Codespaces' in the left bottom corner and then clicking on 'Stop current codespace'.
  • After closing the codespace, you can open it again by going to https://github.com/codespaces and it will be in the same state as before.

Install docker

  • All information about docker can be found on the docker website.

  • Make sure that it is added to the PATH environment variable. This might be a checkbox during the installation.

  • Validate the installation by typing docker ps in a terminal / command prompt.

Simplifying docker usage

In principe, installing docker is enough to run rumbas but the commands will be cumbersome.

In this section we describe how to create bat or sh files to make the docker usage of rumbas transparant for the user.

Important: Make sure to explicitly use the latest version of rumbas (or at least a specific version, not latest)

Explanation

In the Windows and Unix sections below, we will explain how you can run rumbas in your terminal / command prompt by just writing rumbas or rumbas_shell.

  • rumbas: You will be able to write rumbas in the terminal, instead of needing to type the whole docker command with the volume mount.
  • rumbas_shell: Always starting a container might be a bit to slow and overkill. With this script you can run rumbas-shell to get a docker container where you can repeatedly execute rumbas commands. Because of the current implementation of the docker container, it is best to call /usr/app/entrypoint.sh <path> instead of calling rumbas directly. Just calling rumbas will only work if you don't use custom themes.

Windows

We will create a folder docker_scripts on the C drive and add it to the PATH environment variable. In this folder you can create a file for each of the following two scripts.

Creating the docker_scripts folder
  • Create a folder 'docker_scripts' on the C drive
  • Click on the window icon in the left bottom corner
  • Search for 'Edit environment variables' and click on it
  • Select 'Path' and click 'edit'
  • Click on 'New'
  • Typ 'C:\docker_scripts'
  • Click on 'Ok'
  • Open a new terminal so the new PATH variable is set

In this folder you need to create a file for each of the following two scripts.

rumbas.bat

Place the following text in the file rumbas.bat in the docker_scripts folder.

@echo off
set str=%*
set "str=%str:\=/%"
docker run --rm -v %cd%:/rumbas ghcr.io/m8rex/rumbas:0.7.1 %str%
rumbas_shell.bat

Place the following text in the file rumbas_shell.bat in the docker_scripts folder.

@echo off
docker run -it --rm -v %cd%:/rumbas --entrypoint=sh ghcr.io/m8rex/rumbas:0.7.1

Unix

We will create a folder docker_scripts in /usr/local/bin

sudo mkdir /usr/local/bin/docker_scripts

And add it to the path by adding to following line to the ~/.bashrc file:

export PATH=$PATH:/usr/local/bin/docker_scripts

In this folder you can create a file for each of the following two scripts.

rumbas

Place the following text in the file rumbas.bat in the docker_scripts folder.

#!/bin/sh
docker run --rm -v $PWD:/rumbas ghcr.io/m8rex/rumbas:0.7.1 $@

Afterwards execute: sudo chmod +x /usr/local/bin/docker_scripts/rumbas

rumbas_shell

Place the following text in the file rumbas_shell.bat in the docker_scripts folder.

#!/bin/sh
docker run -it --rm -v $PWD:/rumbas --entrypoint=sh ghcr.io/m8rex/rumbas:0.7.1

Afterwards execute: sudo chmod +x /usr/local/bin/docker_scripts/rumbas_shell

Explicit docker usage

It is possible to run rumbas in docker without using the docker_scripts setup.

  • Run docker run --rm -it -v <absolute_path_to_rumbas_repo>:/rumbas ghcr.io/m8rex/rumbas:0.7.1 rumbas <command>
    • e.g.docker run --rm -it -v C:\Users\jesse\Documents\rumbas-examples:/rumbas ghcr.io/m8rex/rumbas:0.7.1 compile exams/M0/algebra/begintest.yaml

Installation

Manual Installation (Advanced Usage)

It is possible to use rumbas without using docker, but this implies some manual installation of software.

Prerequisites

Python 3

Python 3 should be installed and added to the PATH

Running python --version in the terminal / command prompt should yield a version bigger than 3.

The Numbas codebase

rumbas uses Numbas to compile the exams to html.

Clone / Download the numbas code from Github and place it in a folder on your machine.

Set the environment variable NUMBAS_FOLDER to the path of this new folder.

The Numbas extensions

You will need to download all extensions that you want to use and place them in the extensions folder of the NUMBAS_FOLDER.

You can find most extensions at Github.

It is important that you name the folder of the extension exactly as they are named in rumbas.

You can always look at the Dockerfile of rumbas to see how the naming should happen and where you can find the extensions.

The Numbas themes

The themes that are being used in the rumbas repo, should be copied to the themes folder in the NUMBAS_FOLDER.

The Dockerfile uses this script to make sure that the themes are correct.

The rumbas binary

In the future, you might find these binaries on the rumbas Github Releases.

For now, you will need to build the binary yourself.

Building the binary
  • Install the rust
  • Execute cargo build --release in the rumbas folder.

You can also use cargo install --path . in the rumbas folder to build and install the binary.

Tutorial

This tutorial will give you some hands on experience with the rumbas system.

Task

Before starting with the tutorial, please read the Yaml Reference. After going through that section, please return here.

To follow along with the tutorials, you will need an installation of rumbas.

Task

Follow the steps in the installation guide to start a github codespace with the latest released version of rumbas installed.

Your first question

We will start your journey with rumbas by creating a simple question in the rumbas system. This question will be a simple calculation question.

Task

Create a folder first_project in which we will create our 'rumbas project'.

You can create a folder by right clicking on the left bar that shows the file system.

Step 1: Questions folder

Task

Create the folder questions within the folder of your rumbas project.

Info

The folder structure of a rumbas project is important. Some names are reserved and have a special meaning.

  • A folder named defaults that contains the default specifications
  • A folder named questions that contains the questions
  • A folder named exams that contains the exams
  • A folder named themes the contains your custom themes
  • A folder named custom_part_types that contains custom_part_types
  • A folder named resources that contains the resources that are used in exams or questions.

Step 2: Create a question

Task

Create a file named first_question.yaml within the folder questions.

This file will contain the yaml code for the question. To know which fields we can set for a question, you can look at the Reference for question page. For now we will show the fields that can be set for a question:

Reference

QuestionFileType

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
templateTemplateFileA question that uses a template
normalQuestionA normal question

For now we will just look at the 'normal' question type.

Task

Read the reference below and try to understand what each field means.

Reference

Question

fieldtypedescription
statementTranslationThe statement is a content area which appears at the top of the question, before any input boxes. Use the statement to set up the question and provide any information the student needs to answer it.
adviceTranslationAdvice is a content area which is shown when the student presses the Reveal button to reveal the question’s answers, or at the end of the exam. The advice area is normally used to present a worked solution to the question.
partsArray of QuestionPartA question consists of one or more parts. Each part can have a different type to create elaborate questions.
builtin_constantsBuiltinConstantsSpecifies which constants are enabled. You might want to disable the constant e so it can be used as a variable in the questions.
custom_constantsArray of CustomConstantCustom constants that are used in your question.
variablesMap from String to VariableRepresentationThe (ungrouped) variables that are used in this question.
grouped_variables"none" or Map from String to Map from String to VariableRepresentationThe (grouped) variables that are used in this question. This is a map from a group name to a map of variables. Should mainly be used to make it easier to template multiple variables at once.
variables_testVariablesTestThe test to which your variables should comply. Sometimes it’s hard to define randomised question variables so they’re guaranteed to produce a usable set of values. In these cases, it’s easier to state the condition you want the variables to satisfy, Variable values are generated until this condition passes.
While this tool allows you to pick sets of variables that would be hard to generate constructively, it’s a random process so you must be aware that there’s a chance no suitable set of values will ever be found.
functionsMap from String to FunctionThe functions that are used in this question
preamblePreambleSpecify custom javascript and css code that should be loaded.
navigationQuestionNavigationSpecify some navigation options for the question.
extensionsExtensionsUse this to enable the extensions that are used in the question
diagnostic_topic_namesArray of TranslationThe names of the topics used in diagnostic exams that this question belongs to
resourcesArray of ResourcePathThe paths to the resources
custom_part_typesArray of CustomPartTypeDefinitionPathThe custom part types used in this exam
rulesetsMap from String to JMERulesetItemThe rulesets defined in this question. A “ruleset” defines a list of named simplification rules used to manipulate mathematical expressions. https://numbas-editor.readthedocs.io/en/latest/question/reference.html#rulesets

We can set a value for each of these fields.

---
type: normal # set the type to normal
# type has to be set as an 'internal tag' so all fields of 'Question' are set on the samen level
statement: How much is 9 * 3?
advice: You could calculate 10 * 3 and then subtract 3. This yields 3 * 10 - 3 = 30 - 3 = 27
# Add one part
parts:
  - type: number_entry
    prompt: Enter your answer in the inputbox
    marks: 5 # Give 5 points for a correct answer
    answer: 27 # Set the correct answer
    show_correct_answer: true
    show_feedback_icon: true
    display_correct_as_fraction: false
    allow_fractions: false
    fractions_must_be_reduced: false
    fractions_must_be_reduced_hint: false
    partial_credit_if_fraction_not_reduced: 0
    display_correct_in_style: &style english-plain
    allowed_notation_styles:
      - *style
    custom_marking: none
    steps: []
    steps_penalty: 0
    adaptive_marking: none
    part_name: none
# All fields below are not imporant yet, but need to be specified. Rumbas doesn't use any internal default values.
builtin_constants: # all constants will be disabled
  e: false
  pi: false
  i: false
custom_constants: []
variables: {}
grouped_variables: none
variables_test:
  condition: ""
  max_runs: 1
functions: {}
preamble:
  css: ""
  js: ""
navigation:
  can_regenerate: false
  show_title_page: false
  confirm_when_leaving: false
extensions:
  jsx_graph: false
  stats: false
  geogebra: false
  eukleides: false
  chemistry: false
  download_text_file: false
  graphs: false
  linear_algebra: false
  linear_codes: false
  optimisation: false
  permutations: false
  polynomials: false
  quantities: false
  random_person: false
  written_number: false
  sqlite: false
  text: false
diagnostic_topic_names: []
resources: []
custom_part_types: []
rulesets: {}

Task

Place this yaml in the first_question.yaml.

Step 3: Try compiling the first question

Now we can compile the question. To do this, we need to open a terminal in the folder of your rumbas project. Then we can run the following command:

rumbas check questions/first_question.yaml

Task

Run the command above in the terminal.

This command will now show an error about the question not belonging to a rumbas project. This is because our rumbas repository is missing a crucial file. This file is the .rumbasrc.yaml - mind the dot (.) at the start - file. This file contains the settings for the rumbas repository.

Task

Create the file and add the content below.

---
version: 0.8.0 # The rumbas version that this repository uses.

Info

The .rumbasrc.yaml file is used to check whether you are in a rumbas project and whether you are using the right rumbas version for the rumbas project. If you are using the wrong version, you will get an error.

Step 4: Try compiling the first question again

Now we can try compiling the question again.

Task

Recompile the question.

This time we will get a different error. This error is because we are missing another crucial file in our rumbas project. This file is the exams/questions_preview.yaml file.

Info

The exams/questions_preview.yaml file is used to create a preview exam for a question.

Because this file makes use a feature of rumbas that we will explain later (templating), we will create an exam that uses our question and compile that exam.

Task

Create the exams folder in the project folder and add a first_exam.yaml file in this new exams folder.

To know which fields we can set for a question, you can look at the Reference for exam page. For now we will show the fields that can be set for a question.

Reference

ExamFileType

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
templateTemplateFileAn exam that uses a template.
normalNormalExamA normal exam.
diagnosticDiagnosticExamAn exam in diagnostic mode.

For now we will just look at the normal exam type. This is the exam type that we will use for our first exam.

Reference

NormalExam

fieldtypedescription
nameTranslationThe name of the exam
localesArray of LocaleAll locales for which the exam should be generated
navigationNormalNavigationThe navigation settings for this exam
timingTimingThe timing settings for this exam
feedbackFeedbackThe feedback settings for this exam
question_groupsArray of QuestionGroupThe questions groups for this exam
numbas_settingsNumbasSettingsThe settings to set for numbas

We can set a value for each of these fields.

---
type: normal # set the type to normal
# type has to be set as an 'internal tag' so all fields of 'NormalExam' are set on the samen level
name: First Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - first_question.yaml
navigation:
  mode: sequential
  start_password: none
  can_regenerate: true
  show_steps: false
  show_title_page: false
  confirm_when_leaving: false
  show_names_of_question_groups: true
  allow_printing: false
  can_move_to_previous: true 
  browsing_enabled: true
  show_results_page: never
  on_leave: 
    action: none
feedback:
  percentage_needed_to_pass: 50
  show_name_of_student: false
  show_current_marks: true # whether the current score is shown
  show_maximum_marks: true
  show_answer_state: true
  allow_reveal_answer: true
  review:
    show_score: true
    show_feedback: true
    show_expected_answer: true
    show_advice: true
  advice: "Please practice more"
  intro: "An introductory text"
  feedback_messages: []
timing:
  duration_in_seconds: none # no time limit
  allow_pause: true 
  on_timeout: 
    action: none
  timed_warning: 
    action: none
locales: # this can be used to localize your exams (have it available in multiple languages)
  - name: en # custom name
    numbas_locale: en-GB # English (United Kingdom)
numbas_settings:
  theme: default # use the default numbas theme

Task

Place this yaml in the first_exam.yaml file.

Step 5: Compiling our first exam

Now we can compile the exam. To do this, we need to open a terminal in the folder of your rumbas project. Then we can run the following command:

rumbas check exams/first_exam.yaml

Task

Run the command above in the terminal.

Success

It should result in All 1 checks passed!. This means that the exam is valid and can be compiled.

rumbas compile exams/first_exam.yaml

Task

Run the command above in the terminal.

This command will create a folder in _output/en/exams/first_exam with the compiled exam.

Warning

To view this in the browser you should run a local webserver that hosts the _output folder.

Some options are:

  • Live server extension in visual studio code (this is installed in our Github Codespaces setup). Click on the Go Live option in the right bottom corner.
  • The Web Server for Chrome extension
  • Python: execute python -m http.server in the _output folder
  • ...

Step 6: Try the exam

After starting your local webserver, you should be able to browse to the exam. You can find the url in the terminal. It should be something like http://localhost:8000/en/exams/first_exam/.

Task

Open the exam in your browser.

Task

Try answering the question and see if it works.

Task

Also try the following things:

  • Reload the page and use the Reveal answers button to see the correct answer.
  • Try the Try another question like this one button. It won't do anything yet, because we are not using variables yet.

You can also find the exam in the online demo.

Step 7: Using variables

This question will always ask the same question (3 * 9). We can make this question more interesting by using variables to do any number times 9.

Let's copy our first_question.yaml file to first_question_with_variables.yaml and add variables. To do this we will:

  • Add a variable named a with a value of 3
  • Change the statement, answer and correct_answer so it uses the variable a instead of the number 3.
---
type: normal
statement: How much is 9 * {a}? # this changed
advice: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9} # this changed
parts:
  - type: number_entry
    prompt: Enter your answer in the inputbox
    marks: 5 
    answer: a * 9 # this changed
    show_correct_answer: true
    show_feedback_icon: true
    display_correct_as_fraction: false
    allow_fractions: false
    fractions_must_be_reduced: false
    fractions_must_be_reduced_hint: false
    partial_credit_if_fraction_not_reduced: 0
    display_correct_in_style: &style english-plain
    allowed_notation_styles:
      - *style
    custom_marking: none
    steps: []
    steps_penalty: 0
    adaptive_marking: none
    part_name: none
variables:
  a: 3 # this changed
# All fields below are not imporant yet, but need to be specified. Rumbas doesn't use any internal default values.
builtin_constants: # all constants will be disabled
  e: false
  pi: false
  i: false
custom_constants: []
grouped_variables: none
variables_test:
  condition: ""
  max_runs: 1
functions: {}
preamble:
  css: ""
  js: ""
navigation:
  can_regenerate: false
  show_title_page: false
  confirm_when_leaving: false
extensions:
  jsx_graph: false
  stats: false
  geogebra: false
  eukleides: false
  chemistry: false
  download_text_file: false
  graphs: false
  linear_algebra: false
  linear_codes: false
  optimisation: false
  permutations: false
  polynomials: false
  quantities: false
  random_person: false
  written_number: false
  sqlite: false
  text: false
diagnostic_topic_names: []
resources: []
custom_part_types: []
rulesets: {}

Task

Copy the first_question.yaml file to first_question_with_variables.yaml and change the parts indicated in the file above.

Now we will create a new exam that uses this question. We will copy the first_exam.yaml file to first_exam_with_variables.yaml and add the new question to the questions field.

---
type: normal
name: First Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - first_question.yaml
      - first_question_with_variables.yaml # We added this
navigation:
  mode: sequential
  start_password: none
  can_regenerate: true
  show_steps: false
  show_title_page: false
  confirm_when_leaving: false
  show_names_of_question_groups: true
  allow_printing: false
  can_move_to_previous: true 
  browsing_enabled: true
  show_results_page: never
  on_leave: 
    action: none
feedback:
  percentage_needed_to_pass: 50
  show_name_of_student: false
  show_current_marks: true
  show_maximum_marks: true
  show_answer_state: true
  allow_reveal_answer: true
  review:
    show_score: true
    show_feedback: true
    show_expected_answer: true
    show_advice: true
  advice: "Please practice more"
  intro: "An introductory text"
  feedback_messages: []
timing:
  duration_in_seconds: none 
  allow_pause: true 
  on_timeout: 
    action: none
  timed_warning: 
    action: none
locales: 
  - name: en 
    numbas_locale: en-GB
numbas_settings:
  theme: default

Task

Copy the first_exam.yaml file to first_exam_with_variables.yaml and add the question as indicated in the file above.

We can then compile all exams with the following command:

rumbas compile exams

And open the new exam in the browser by browsing to http://localhost:8000/en/exams/first_exam_with_variables/.

Task

Try answering the second question and see if it works.

Task

Also try the following things for the second question:

  • Reload the page and use the Reveal answers button to see the correct answer. You will see that the calculations in the marks and advice fields are calculated.
  • Try the Try another question like this one button. It won't do anything yet, because we are not using randomisation yet.

You can also find the exam in the online demo.

Step 8: Using randomisation

Now we will create a question that uses randomisation. We will copy the first_question_with_variables.yaml file to first_question_with_randomisation.yaml and change the value of variable a to random(1..10). This will choose a random integer between 1 and 10 as value for a.

---
type: normal
statement: How much is 9 * {a}? 
advice: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9}
parts:
  - type: number_entry
    prompt: Enter your answer in the inputbox
    marks: 5 
    answer: a * 9 
    show_correct_answer: true
    show_feedback_icon: true
    display_correct_as_fraction: false
    allow_fractions: false
    fractions_must_be_reduced: false
    fractions_must_be_reduced_hint: false
    partial_credit_if_fraction_not_reduced: 0
    display_correct_in_style: &style english-plain
    allowed_notation_styles:
      - *style
    custom_marking: none
    steps: []
    steps_penalty: 0
    adaptive_marking: none
    part_name: none
variables:
  a: random(1..10) # this changed
# All fields below are not imporant yet, but need to be specified. Rumbas doesn't use any internal default values.
builtin_constants: # all constants will be disabled
  e: false
  pi: false
  i: false
custom_constants: []
grouped_variables: none
variables_test:
  condition: ""
  max_runs: 1
functions: {}
preamble:
  css: ""
  js: ""
navigation:
  can_regenerate: false
  show_title_page: false
  confirm_when_leaving: false
extensions:
  jsx_graph: false
  stats: false
  geogebra: false
  eukleides: false
  chemistry: false
  download_text_file: false
  graphs: false
  linear_algebra: false
  linear_codes: false
  optimisation: false
  permutations: false
  polynomials: false
  quantities: false
  random_person: false
  written_number: false
  sqlite: false
  text: false
diagnostic_topic_names: []
resources: []
custom_part_types: []
rulesets: {}

Task

Copy the first_question_with_variables.yaml file to first_question_with_randomisation.yaml and change the definition of the variables a as indicated in the file above.

Now we will create a new exam that uses this question. We will copy the first_exam_with_variables.yaml file to first_exam_with_randomisation.yaml and add the new question to the questions field.

---
type: normal
name: First Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - first_question.yaml
      - first_question_with_variables.yaml
      - first_question_with_randomisation.yaml # We added this
navigation:
  mode: sequential
  start_password: none
  can_regenerate: true
  show_steps: false
  show_title_page: false
  confirm_when_leaving: false
  show_names_of_question_groups: true
  allow_printing: false
  can_move_to_previous: true 
  browsing_enabled: true
  show_results_page: never
  on_leave: 
    action: none
feedback:
  percentage_needed_to_pass: 50
  show_name_of_student: false
  show_current_marks: true
  show_maximum_marks: true
  show_answer_state: true
  allow_reveal_answer: true
  review:
    show_score: true
    show_feedback: true
    show_expected_answer: true
    show_advice: true
  advice: "Please practice more"
  intro: "An introductory text"
  feedback_messages: []
timing:
  duration_in_seconds: none 
  allow_pause: true 
  on_timeout: 
    action: none
  timed_warning: 
    action: none
locales: 
  - name: en 
    numbas_locale: en-GB
numbas_settings:
  theme: default

Task

Copy the first_exam_with_variables.yaml file to first_exam_with_randomisation.yaml and add the question as indicated in the file above.

We can then compile all exams with the following command:

rumbas compile exams

And open the new exam in the browser by browsing to http://localhost:8000/en/exams/first_exam_with_randomisation/.

Task

Try answering the third question and see if it works.

Task

Also try the following things for the third question:

  • Reload the page and use the Reveal answers button to see the correct answer. You will see that the calculations in the marks and advice fields are calculated.
  • Try the Try another question like this one button.
    • For the third question, this will generate a new question with a new value for a.
    • You will see that after trying another question and using the 'Reveal answers' button, the advice is changed to use the new value of a.

You can also find the exam in the online demo.

Congratulations

This concludes our very first example of rumbas. In the next example we will look at the default value files to reduce the size of our question and exam files.

Using defaults

In the previous example we saw how to create a question and an exam. In this example we will look at how to use default files to reduce the size of our question and exam files.

Create a new rumbas project

Task

  • Create a new folder using_defaults for this tutorial.
  • Create a .rumbasrc.yaml file (with the right content) in this folder.
  • Create a questions folder in this folder.
  • Create an exams folder in this folder.

Task

Copy the questions and exams from your first question rumbas project to this project.

Default files folder

Task

Create a folder named defaults in the root of your project.

This folder will contain default files that you want to use in your project. These files specify global defaults for your project.

Default exam files

For an exam we can specify a couple of different default files to specify global defaults for exams.

Our three exams use exactly the same navigation. We can therefore move the navigation field to a default file.

The navigation field of an exam can be specified in a file named navigation.yaml in the defaults folder.

Task

Place the value of the navigation field of the exam in this file. For example:

---
mode: sequential
start_password: none
can_regenerate: true
show_steps: false
show_title_page: false
confirm_when_leaving: false
show_names_of_question_groups: true
allow_printing: false
can_move_to_previous: true 
browsing_enabled: true
show_results_page: never
on_leave: 
  action: none

Task

You can now remove the navigation field from the 3 exam files.

Task

Try compiling the exams again. You should see that the compilation works and that the navigation is still the same within the exams.

Feedback

Our three exams use exactly the same feedback. We can therefore move the feedback field to a default file.

The feedback field of an exam can be specified in a file named feedback.yaml in the defaults folder.

Task

Place the value of the feedback field of the exam in this file. For example:

---
percentage_needed_to_pass: 50
show_name_of_student: false
show_current_marks: true
show_maximum_marks: true
show_answer_state: true
allow_reveal_answer: true
review:
  show_score: true
  show_feedback: true
  show_expected_answer: true
  show_advice: true
advice: "Please practice more"
intro: "An introductory text"
feedback_messages: []

Task

You can now remove the feedback field from the 3 exam files.

Task

Try compiling the exams again. You should see that the compilation works and that the feedback is still the same within the exams.

Timing

Our three exams use exactly the same timing. We can therefore move the timing field to a default file.

The timing field of an exam can be specified in a file named timing.yaml in the defaults folder.

Task

Place the value of the timing field of the exam in this file. For example:

---
duration_in_seconds: none # no time limit
allow_pause: true 
on_timeout: 
  action: none
timed_warning: 
  action: none

Task

You can now remove the timing field from the 3 exam files.

Task

Try compiling the exams again. You should see that the compilation works and that the timing is still the same within the exams.

Locales

Our three exams use exactly the same locales. We can therefore move the locales field to a default file.

The locales field of an exam can be specified in a file named locales.yaml in the defaults folder.

Task

Place the value of the locales field of the exam in this file. For example:

---
- name: en # custom name
  numbas_locale: en-GB # English (United Kingdom)

Task

You can now remove the locales field from the 3 exam files.

Task

Try compiling the exams again. You should see that the compilation works and that the locales are still the same within the exams.

Numbas Settings

Our three exams use exactly the same Numbas settings. We can therefore move the numbas_settings field to a default file.

The numbas_settings field of an exam can be specified in a file named numbas_settings.yaml in the defaults folder.

Task

Place the value of the numbas_settings field of the exam in this file. For example:

---
theme: default # use the default numbas theme

Task

You can now remove the numbas_settings field from the 3 exam files.

Task

Try compiling the exams again. You should see that the compilation works and that the Numbas settings are still the same within the exams.

Resulting exam files

Our exam files are now a lot smaller. Our exam with randomisation is now:

---
type: normal
name: First Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - first_question.yaml
      - first_question_with_variables.yaml
      - first_question_with_randomisation.yaml

Overriding defaults

These defaults are useful to reduce the size of your exam files. However, sometimes you will want to override the default values. For example, you might want to change the show_current_marks field of the feedback field for a specific exam. This can easily be done without needing to specify all fields of feedback.

Task

Override the show_current_marks field of the feedback field.

---
type: normal
name: First Exam
feedback:
  show_current_marks: false # overrride this field
  # all other feedback settings are taken from the default file
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - first_question.yaml
      - first_question_with_variables.yaml
      - first_question_with_randomisation.yaml

Task

Try compiling this exam. You should see that the compilation works and that the current total score is not shown in the exam.

You can also find the exam in the online demo.

Step 4: Default question files

Default question files

We can do the same thing for question files. For example, we can move the all question fields (except question_groups) to a default file.

Task

Move all fields of the questions that are equal to the question.yaml file in the defaults folder. For example:

---
builtin_constants: # all constants will be disabled
  e: false
  pi: false
  i: false
custom_constants: []
variables: {}
grouped_variables: none
variables_test:
  condition: ""
  max_runs: 1
functions: {}
preamble:
  css: ""
  js: ""
navigation:
  can_regenerate: false
  show_title_page: false
  confirm_when_leaving: false
extensions:
  jsx_graph: false
  stats: false
  geogebra: false
  eukleides: false
  chemistry: false
  download_text_file: false
  graphs: false
  linear_algebra: false
  linear_codes: false
  optimisation: false
  permutations: false
  polynomials: false
  quantities: false
  random_person: false
  written_number: false
  sqlite: false
  text: false
diagnostic_topic_names: []
resources: []
custom_part_types: []
rulesets: {}

We also add the variables field in here and set it to an empty hash by default. This is because we will be able to override the variables field in the question files that do use variables.

Task

Remove the fields from the question files.

Task

Try compiling the exams again. You should see that the compilation works and that the questions are still the same within the exams.

Our question files are now a lot smaller. Our question with variables is now:

---
type: normal
statement: How much is 9 * {a}?
advice: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9} # this changed
parts:
  - type: number_entry
    prompt: Enter your answer in the inputbox
    marks: 5 
    answer: a * 9
    show_correct_answer: true
    show_feedback_icon: true
    display_correct_as_fraction: false
    allow_fractions: false
    fractions_must_be_reduced: false
    fractions_must_be_reduced_hint: false
    partial_credit_if_fraction_not_reduced: 0
    display_correct_in_style: &style english-plain
    allowed_notation_styles:
      - *style
    custom_marking: none
    steps: []
    steps_penalty: 0
    adaptive_marking: none
    part_name: none
variables:
  a: 3

Default question part files

There is still some duplication of settings within the number_entry question parts. We can move the settings of the number_entry question parts to a default file.

Task

Move all fields of the number_entry question parts that are equal to the questionpart.number_entry.yaml file in the defaults folder. For example:

---
show_correct_answer: true
show_feedback_icon: true
display_correct_as_fraction: false
allow_fractions: false
fractions_must_be_reduced: false
fractions_must_be_reduced_hint: false
partial_credit_if_fraction_not_reduced: 0
display_correct_in_style: &style english-plain
allowed_notation_styles:
  - *style
custom_marking: none
steps: []
steps_penalty: 0
adaptive_marking: none
part_name: none

Info

For each questionpart type you can specify such a default file.

Our question files are now even smaller. Our question with variables is now:

---
type: normal
statement: How much is 9 * {a}?
advice: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9} # this changed
parts:
  - type: number_entry
    prompt: Enter your answer in the inputbox
    marks: 5 
    answer: a * 9
variables:
  a: 3

Multi language questions

One of the most important features of rumbas is that it is easy to create different language versions of the same question.

Create a new rumbas project

Task

  • Create a new folder multi_language_questions for this tutorial.
  • Create a .rumbasrc.yaml file (with the right content) in this folder.
  • Create a questions folder in this folder.
  • Create an exams folder in this folder.
  • Create a defaults folder in this folder.

Task

Copy the questions, exams and default from your using_defaults rumbas project to this project.

Translating the statement

Currently our question with variables is defined in yaml as follows:

---
type: normal
statement: How much is 9 * {a}?
advice: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9}
parts:
  - type: number_entry
    prompt: Enter your answer in the inputbox
    marks: 5 
    answer: a * 9
variables:
  a: 3

Currently this question is only available in English. We want to make this question available in Dutch as well.

Let's take a look again at the structure of a questions.

Task

Take a good look at the (datatype of the) statement and advice field.

Reference

Question

fieldtypedescription
statementTranslationThe statement is a content area which appears at the top of the question, before any input boxes. Use the statement to set up the question and provide any information the student needs to answer it.
adviceTranslationAdvice is a content area which is shown when the student presses the Reveal button to reveal the question’s answers, or at the end of the exam. The advice area is normally used to present a worked solution to the question.
partsArray of QuestionPartA question consists of one or more parts. Each part can have a different type to create elaborate questions.
builtin_constantsBuiltinConstantsSpecifies which constants are enabled. You might want to disable the constant e so it can be used as a variable in the questions.
custom_constantsArray of CustomConstantCustom constants that are used in your question.
variablesMap from String to VariableRepresentationThe (ungrouped) variables that are used in this question.
grouped_variables"none" or Map from String to Map from String to VariableRepresentationThe (grouped) variables that are used in this question. This is a map from a group name to a map of variables. Should mainly be used to make it easier to template multiple variables at once.
variables_testVariablesTestThe test to which your variables should comply. Sometimes it’s hard to define randomised question variables so they’re guaranteed to produce a usable set of values. In these cases, it’s easier to state the condition you want the variables to satisfy, Variable values are generated until this condition passes.
While this tool allows you to pick sets of variables that would be hard to generate constructively, it’s a random process so you must be aware that there’s a chance no suitable set of values will ever be found.
functionsMap from String to FunctionThe functions that are used in this question
preamblePreambleSpecify custom javascript and css code that should be loaded.
navigationQuestionNavigationSpecify some navigation options for the question.
extensionsExtensionsUse this to enable the extensions that are used in the question
diagnostic_topic_namesArray of TranslationThe names of the topics used in diagnostic exams that this question belongs to
resourcesArray of ResourcePathThe paths to the resources
custom_part_typesArray of CustomPartTypeDefinitionPathThe custom part types used in this exam
rulesetsMap from String to JMERulesetItemThe rulesets defined in this question. A “ruleset” defines a list of named simplification rules used to manipulate mathematical expressions. https://numbas-editor.readthedocs.io/en/latest/question/reference.html#rulesets

We see that the statement and advice fields have the type Translation.

Reference

Translation

One of the following items:

typedescription
TranslationStructA structured translatable string with placeholders.
FileStringA simple filestring. This implies that it can also just be a string.

For now we will focus on the first option, the TranslationStruct.

Reference

TranslationStruct

fieldtypedescription
contentTranslationContentThe content with optional placeholders ({{placeholder-name}}).
placeholdersMap from String to TranslationThe values for the placeholders. It maps the placeholder-name to it's translatable value. The value for a placeholder can thus (if needed) be different for different locales.
---
content: # the content of form TranslationContent
placeholders: {} # empty for now

Let's now have a look at TranslationContent.

Reference

TranslationContent

One of the following items:

typedescription
Map from String to FileStringMap from locale to content. You can use this to specify different content for different locales.
FileStringA filestring. Possibly to a file that is placed in locale folders and is therefore localized.

The first option is the most important for now. It says that we can specify different versions of the content in different languages by using a hash.

---
content:
  en: english content
  nl: dutch content
placeholders: {} # empty for now

Task

Update the statement, advice and prompt fields of the first_question_with_variables.yaml question to make it available in Dutch as shown below.

---
type: normal
statement: 
  content: 
    en: How much is 9 * {a}?
    nl: Hoeveel is 9 * {a}?
  placeholders: {}
advice: 
  content: 
    en: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9}
    nl: Je kan 10 * {a} berekenen en dan {a} daarvan aftrekken. Dit geeft {a} * 10 - {a} = {a * 10} - {a} = {a*9}
  placeholders: {}
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks: 5 
    answer: a * 9
variables:
  a: 3

Task

Recompile all exams

Danger

Take a good look at the output of the compilation. You should see that all successful compilations happened 'with locale en'.

Question

Any idea why this is the case?

Info

Each exams specifies for which locales it needs to be compiled.

Task

Take a look at the default values to see which locales are set.

---
- name: en # custom name
  numbas_locale: en-GB # English (United Kingdom)

Question

Do you see why we used the key en in the content field of the question?

Task

Add the nl locale to the locales.yaml file.

---
- name: en # custom name
  numbas_locale: en-GB # English (United Kingdom)
- name: nl # custom name
  numbas_locale: nl-NL # Dutch (The Netherlands)

Task

Recompile all exams. You should see that the exams are now compiled for both locales.

You can access the dutch exams at http://localhost:8000/nl/exams/first_question_with_variables/

You can also find the dutch exam and english exam in the online demo.

Placeholders

If we look at statement and advice we see that some values (mostly math expressions) are language independant.

---
type: normal
statement: 
  content: 
    en: How much is 9 * {a}?
    nl: Hoeveel is 9 * {a}?
  placeholders: {}
advice: 
  content: 
    en: You could calculate 10 * {a} and then subtract {a}. This yields {a} * 10 - {a} = {a * 10} - {a} = {a*9}
    nl: Je kan 10 * {a} berekenen en dan {a} daarvan aftrekken. Dit geeft {a} * 10 - {a} = {a * 10} - {a} = {a*9}
  placeholders: {}
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks: 5 
    answer: a * 9
variables:
  a: 3

This is where placeholders come in. Placeholders can be specified by name and then be used in the content field by writing {name}.

---
type: normal
statement: 
  content: 
    en: How much is {formula}?
    nl: Hoeveel is {formula}?
  placeholders:
      formula: 9 * {a}
advice: 
  content: 
    en: You could calculate {times10} and then subtract {a}. This yields {result}
    nl: Je kan {times10} berekenen en dan {a} daarvan aftrekken. Dit geeft {result}
  placeholders:
    times10: 10 * {a} 
    result: '{a} * 10 - {a} = {a * 10} - {a} = {a*9}'
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks: 5 
    answer: a * 9
variables:
  a: 3

Task

Recompile all exams. You should see no difference but there are less chances to have different formulas in the different languages.

Info

You can also use the placeholders the other way around. This is mainly useful when almost the whole string is maths and some small parts need to be translated. This might not work for all languages due to different grammar rules etc. For example:

---
content: "{command} $5x^2-10$."
placeholders:
  command: 
    content:
      nl: Ontbind in factoren
      en: Factorize
    placeholders: {}

Locale Folders

It might happen that you want to use the same text in different questions or exams. This is where the FileString type comes in.

Task

Take a look at the second option of the Translation type. `

Reference

Translation

One of the following items:

typedescription
TranslationStructA structured translatable string with placeholders.
FileStringA simple filestring. This implies that it can also just be a string.

Let's take a look at the FileString type.

Reference

FileString

One of the following items:

typedescription
StringA string of the form file:<filepath> where filepath is the relative path (within the exams or questions folder) to a file containing content. This content can be localized by placing it in locale folders. e.g. file:examples/basic-explanation.html will search for files in folders with following form: questions/examples/locale-<localename>/basic-explanation.html If a file isn't found for a specific locale, questions/examples/basic-explanation.html will be used.
StringA literal string.

Info

A filestring is thus one of the following:

  1. A string that starts with file: followed by a path to a file
  2. Another string that is interpreted literally as text.

In the first option, it is possible to use locale folders to specify different versions of the file for different locales.

Using the FileString type in combination with locale folders gives us a powerful mechanism to reuse text in different questions and exams.

Task

Move the statement content to localized files.

This yields following yaml code for the question

---
type: normal
statement: 
  content: how-much.html
  placeholders:
      formula: 9 * {a}
advice: 
  content: 
    en: You could calculate {times10} and then subtract {a}. This yields {result}
    nl: Je kan {times10} berekenen en dan {a} daarvan aftrekken. Dit geeft {result}
  placeholders:
    times10: 10 * {a} 
    result: '{a} * 10 - {a} = {a * 10} - {a} = {a*9}'
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks: 5 
    answer: a * 9
variables:
  a: 3

And questions/locale-nl/how-much.html file:

Hoeveel is {formula}?

And questions/locale-en/how-much.html file:

How much is {formula}?

Task

Update all questions and exams so they are available in both English and Dutch. If you don't speak dutch, use any other language. It is also possible to use the locales for different styles of instruction.

Using Templates

Another very important feature of rumbas, is its templating feature. This feature allows you to create a template for a question or exam. This template can then be used to create multiple questions or exams. This is very useful when you have a lot of questions or exams that are very similar.

Create a new rumbas project

Task

  • Create a new folder using_templates for the rumbas project of this tutorial.
  • Create a .rumbasrc.yaml file (with the right content) in this folder.
  • Create a questions folder in this folder.
  • Create an exams folder in this folder.
  • Copy the defaults folder from the previous tutorial.

Add a question and an exam

We will add an exam with the following content:

---
type: normal
name: Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - question.yaml

And also add a question with the following content:

---
type: normal
statement:
  content:
    nl: Hoveel is {formula}?
    en: How much is {formula}?
  placeholders:
    formula: 9 * {a}
advice:
  content: 
    en: You could calculate {times10} and then subtract {a}. This yields {result}
    nl: Je kan {times10} berekenen en dan {a} daarvan aftrekken. Dit geeft {result}
  placeholders:
    times10: 10 * {a} 
    result: '{a} * 10 - {a} = {a * 10} - {a} = {a*9}'
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks: 5 
    answer: a * 9 
variables:
  a: random(1..10)

Task

Add the exam.yaml and question.yaml files to the exams and questions folders respectively.

Task

Run rumbas check exams to check if the setup is correct.

Using a template

Create a template

We might want to create a lot of questions that are very similar to the question we just created. In some cases, we might want to let the variable a go up to 100 or be limited between 1 and 5.

To do this, we copy the contents of question.yaml to question_template.yaml and make the change the value of the variable a to template:a. This yields the following content for question_template.yaml:

---
type: normal
statement:
  content:
    nl: Hoveel is {formula}?
    en: How much is {formula}?
  placeholders:
    formula: 9 * {a}
advice:
  content: 
    en: You could calculate {times10} and then subtract {a}. This yields {result}
    nl: Je kan {times10} berekenen en dan {a} daarvan aftrekken. Dit geeft {result}
  placeholders:
    times10: 10 * {a} 
    result: '{a} * 10 - {a} = {a * 10} - {a} = {a*9}'
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks: 5 
    answer: a * 9 
variables:
  a: template:a # this field is now templatable and has template-key 'a'

There is no meaning behind the _template suffix of the file name, we just use it for the example.

Task

  • Copy the contents of question.yaml to question_template.yaml.
  • Change the value of the variable a.

Now that we have added a value of the form template:<template-key> the question_template.yaml file is a template. We can now use this template to create multiple questions.

Loading the template in an exam

The easiest way to use this templated question, is by loading it in an exam and giving values for each template key.

We will load the template two times in the exam. The first time we will set the value of a to 3 so it will always yield the same question. The second time, we set it to random(10..100) to let a be a random value between 10 and 100.

We will change our exam.yaml file to the following:

---
type: normal
name: Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - question.yaml
      - type: template # we will load it as a template
        template: question_template.yaml # this template will be loaded
        a: 3 # this is filled in for `template:a`
      - type: template # we will load it as a template
        template: question_template.yaml # this template will be loaded
        a: random(10..100) # this is filled in for `template:a`

Task

update the exam.yaml file to the content above.

Task

Recompile all exams with rumbas compile exams.

Task

Try the exam, you should see three questions that work slightly different in their generation of a.

What if we forget to set a template key?

What would happen when we don't set all template keys? Let's try it out.

We will change our exam.yaml file to the following:

---
type: normal
name: Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - question.yaml
      - type: template # we will load it as a template
        template: question_template.yaml # this template will be loaded
        a: 3 # this is filled in for `template:a`
      - type: template # we will load it as a template
        template: question_template.yaml # this template will be loaded
        a: random(10..100) # this is filled in for `template:a`
      - type: template
        template: question_template.yaml

Task

Change the exam.yaml file to the content above.

Task

Check all exams with rumbas check exams.

This will yield an error message like the following:

[2023-01-25][09:48:30][rumbas_support::input][ERROR] Found 1 missing template keys:
[2023-01-25][09:48:30][rumbas_support::input][ERROR] 1  a at question_groups.0.questions.3.question_template.yaml.variables.a

Which says that we forgot to set the value of a for the fourth question (index 3 when you count from 0).

Task

Set a value for the template key a for the fourth question.

Task

Check all exams with rumbas check exams. This should now pass.

Task

Recompile all exams with rumbas compile exams and try out the fourth question in the exam.

Using default values for template keys

It is possible to defined default values for template keys. This allows you to override the value but also have a default value that is used when the value is not set.

We will demonstrate this by allowing the marks for the question to be set by a template key, but also have a default value of 5 marks.

We will change our question_template.yaml file to the following:

---
type: normal
statement:
  content:
    nl: Hoveel is {formula}?
    en: How much is {formula}?
  placeholders:
    formula: 9 * {a}
advice:
  content: 
    en: You could calculate {times10} and then subtract {a}. This yields {result}
    nl: Je kan {times10} berekenen en dan {a} daarvan aftrekken. Dit geeft {result}
  placeholders:
    times10: 10 * {a} 
    result: '{a} * 10 - {a} = {a * 10} - {a} = {a*9}'
parts:
  - type: number_entry
    prompt: 
      content:
        en: Enter your answer in the inputbox
        nl: Geef je antwoord in in het invulveld
      placeholders: {}
    marks:
      template_key: marks
      default_valie: 5 
    answer: a * 9 
variables:
  a: template:a # this field is now templatable and has template-key 'a'

Task

Update the question_template.yaml file to the content above.

This allows us to optionally specify the value of the template key marks in the exam. If we don't specify it, it will use the default value of 5.

We will change our exam.yaml file to the following:

---
type: normal
name: Exam
question_groups:
  - name: Group 1
    picking_strategy:
      type: all_ordered
    questions:
      - question.yaml
      - type: template
        template: question_template.yaml 
        a: 3 # we don't specify the marks here, so it will be 5
      - type: template
        template: question_template.yaml 
        a: random(10..100)
        marks: 10 # assign 10 marks to the more difficult version

Task

Update the exam.yaml file to the content above.

Task

Recompile all exams with rumbas compile exams.

Task

Try the exam, you should see that the third question assigns 10 marks.

Create a question that uses a template

If you want to reuse a version of a question that uses a template, you can create a question that uses a template.

We will create a question that uses the template we created in the previous section.

We will create a question_using_template.yaml file with the following content:

---
type: template
template: question_template.yaml 
a: random([11,55,78])

We can now include this question in an exam.

Task

Add this question to the exam.yaml file.

Task

Recompile all exams with rumbas compile exams.

Task

Try the exam, you should see that the added question uses a value of 11, 55 or 78 for a.

Rumbas CLI commands

All commands

$ rumbas --help
Make online exercises great again!

Usage: rumbas [OPTIONS] <COMMAND>

Commands:
  compile
          Compile a rumbas exam (or question)
  check
          Check a rumbas exam (or question)
  watch
          Watch a path
  fmt
          Format a rumbas exam (or question)
  import
          Import a numbas .exam file
  init
          Initialize a rumbas project in this folder
  update-repo
          Update the repository to the next rumbas version
  export
          Export a rumbas exam as one yaml. All default files and templating is resolved
  schema
          Creates files with the json schemas (beta). See https://github.com/m8rex/rumbas-examples/tree/main/.vscode for usage instructions
  generate-shell-completion
          Generate shell completion file. Placing this file at the right location and reloading your shell, will give you shell completion for rumbas
  editor-output
          Generates a folder structure that can be hosted and used as an 'editor' in the numbas lti provider
  help
          Print this message or the help of the given subcommand(s)

Options:
  -v...
          Sets the level of verbosity
          
          -v    sets the level to ERROR
          
          -vv   sets the level to WARN
          
          -vvv   sets the level to INFO
          
          -vvvv   sets the level to DEBUG
          
          The default is -vvv

  -q
          Enables quiet mode. Nothing is logged. This has precedence over the verbose option

  -h, --help
          Print help information (use `-h` for a summary)

  -V, --version
          Print version information

compile

$ rumbas compile --help
Compile a rumbas exam (or question)

You can pass a path to a folder to compile all files in the folder.

Usage: compile [OPTIONS] <EXAM_OR_QUESTION_PATHS>...

Arguments:
  <EXAM_OR_QUESTION_PATHS>...
          The path to the exam or question file to compile.
          
          If a folder within the questions or exams folder is used, all questions/exams in that folder will be compiled.
          
          It is possible to specify multiple paths to folder/files.

Options:
  -s, --scorm
          Include the files necessary to make a SCORM package

  -z, --zip
          Create a zip file instead of a directory

      --no-minification
          Don't perform minification on the created js in the exam. Useful if you don't have uglifyjs or want to debug something

  -h, --help
          Print help information (use `-h` for a summary)

check

$ rumbas check --help
Check a rumbas exam (or question)

You can pass a path to a folder to check all files in the folder.

Usage: check <EXAM_OR_QUESTION_PATHS>...

Arguments:
  <EXAM_OR_QUESTION_PATHS>...
          The path to the exam or question file to check.
          
          If a folder within the questions or exams folder is used, all questions/exams in that folder will be checked.
          
          It is possible to specify multiple paths to folder/files.

Options:
  -h, --help
          Print help information (use `-h` for a summary)

watch

$ rumbas watch --help
Watch a path

Usage: watch [OPTIONS] <PATH>

Arguments:
  <PATH>
          The path to watch

Options:
  -o
          Only check exams and questions that change due to file changes, but don't compile them with numbas

  -h, --help
          Print help information

fmt

$ rumbas fmt --help
Format a rumbas exam (or question).

You can pass a path to a folder to format all files in the folder.

Usage: fmt <EXAM_OR_QUESTION_PATHS>...

Arguments:
  <EXAM_OR_QUESTION_PATHS>...
          The path to the exam or question file to format.
          
          If a folder within the questions or exams folder is used, all questions/exams in that folder will be formatted.
          
          It is possible to specify multiple paths to folder/files.

Options:
  -h, --help
          Print help information (use `-h` for a summary)

import

$ rumbas import --help
Import a numbas .exam file

Resources have to be manually placed in the resources folder

Usage: import [OPTIONS] <EXAM_PATH>

Arguments:
  <EXAM_PATH>
          The path to the numbas .exam file

Options:
  -q
          Tells rumbas that this is the exam file of a numbas question instead of of a numbas exam

  -h, --help
          Print help information (use `-h` for a summary)

init

$ rumbas init --help
Initialize a rumbas project in this folder

Usage: init [OPTIONS]

Options:
      --summative
          Whether the defaults should be of summative nature (instead of formative)

  -h, --help
          Print help information

update-repo

$ rumbas update-repo --help
Update the repository to the next rumbas version

Usage: update-repo

Options:
  -h, --help
          Print help information

export

$ rumbas export --help
Export a rumbas exam as one yaml. All default files and templating is resolved.

Can be useful to debug exams / questions that don't behave as expected

Usage: export <EXAM_OR_QUESTION_PATHS>...

Arguments:
  <EXAM_OR_QUESTION_PATHS>...
          The path to the exams to export
          
          If a folder within the questions or exams folder is used, all questions/exams in that folder will be exported.
          
          It is possible to specify multiple paths to folder/files.

Options:
  -h, --help
          Print help information (use `-h` for a summary)

schema

$ rumbas schema --help
Creates files with the json schemas (beta). See https://github.com/m8rex/rumbas-examples/tree/main/.vscode for usage instructions

Usage: schema

Options:
  -h, --help
          Print help information

generate-shell-completion

$ rumbas generate-shell-completion --help
Generate shell completion file. Placing this file at the right location and reloading your shell, will give you shell completion for rumbas.

Example for bash: rumbas generate-shell-completion bash | sudo tee /usr/share/bash-completion/completions/rumbas

Usage: generate-shell-completion <SHELL>

Arguments:
  <SHELL>
          The shell for which the shell competion should be generated
          
          [possible values: bash, elvish, fish, powershell, zsh]

Options:
  -h, --help
          Print help information (use `-h` for a summary)

editor-output

$ rumbas editor-output --help
Generates a folder structure that can be hosted and used as an 'editor' in the numbas lti provider

Only exams are compiled.

Usage: editor-output <OUTPUT_PATH> <URL_PREFIX>

Arguments:
  <OUTPUT_PATH>
          The path to the folder where the output should be generated

  <URL_PREFIX>
          The url prefix for all editor api calls

Options:
  -h, --help
          Print help information (use `-h` for a summary)

help

$ rumbas help --help
Print this message or the help of the given subcommand(s)

Usage: help [COMMAND]...

Arguments:
  [COMMAND]...
          Print help for the subcommand(s)

Features

Rumbas is a library for creating and running assessments. It is designed to be used in a variety of ways, and can be used in a variety of contexts. This chapter describes the features of Rumbas, and how they can be used.

Rumbas tries to support all features that Numbas supports, and adds some new features. The new features are:

  • Templating for questions and exams. This allows you to create the format of a question or exam once, and then use it in multiple questions or exams with different values.
  • Multi language support. This allows you to create questions and exams in multiple languages while sharing the language independent parts.
    • Locale folders allow you to specify different values for different languages and to reuse these values in different questions or exams.
  • Explicity: Rumbas does not use any default values within the program. All values must be explicitly set, and the program will not guess what you want. This makes it easier to understand what is going on, and to debug problems.
    • Default value files can (and should) be used to specify default values for your questions and exams.

Default files

Multi language

Locales folders

Templates

Summary

Yaml subset used by Rumbas

The source code for any rumbas exam or question is written in a subset of YAML.

This page sections show you how to write YAML files for Rumbas.

Datatypes

The following datatypes are used in the rumbas yaml files. The following sections will explain how each of these can be represented in the yaml files.

DatatypeWhat is it used for?
stringAnything that has to do with text, numbers or booleans. This can also be used for html and jme content.
arrayAn ordered list of values (of the same type).
hashA list of key-value pairs. The keys are strings and the values can be any datatype.
anchorA way to reference a value multiple times.

Strings

Strings can be written in many ways in yaml, each with their specific advantages and disadvantages.

typeWhen to use?
Unquoted stringsShort text without hashtags (with a space in front) or colons (with a space behind).
Single quoted stringsShort text where unquoted strings can't be used.
Double quoted stringsAlmost never. When you need to be able to write escaped sequences like \n.
Folded stringsWhen you have a longer piece of text that you would like to write on multiple lines.
Literal stringsWhen you absolutely need to have newlines in the resulting string.

Unquoted strings

Unquoted strings are the most basic form of string. They are written as a sequence of characters, without any quotes.

This is an unquoted string

Advantages:

  • Easy to write
  • Backslashes (\) are not interpreted as escape characters. This means that you can write a string containing a backslash without having to escape it.
    • Special characters like newlines and tabs are not interpreted as escape characters.
    • Makes it easy to type a string containing jme commands.

Disadvantages:

  • Newlines (enters) can only be inserted by leaving a blank line.
  • Can't contain colons (:) followed by a space or a hashtag (#) after a space.

Single quoted strings

Single quoted strings are written between single quotes.

'This is a single quoted string'

means

This is a single quoted string

Advantages:

  • Can contain colons (:) followed by a space or a hashtag (#) after a space.
  • Backslashes (\) are not interpreted as escape characters. This means that you can write a string containing a backslash without having to escape it.
    • Special characters like newlines and tabs are not interpreted as escape characters.
    • Makes it easy to type a string containing jme commands.

Disadvantages:

  • Newlines (enters) can only be inserted by leaving a blank line.
  • Can't contain single quotes ('). They need to be escaped with a single quote (').
'It''s a single quoted string with a jme simplify command \simplify{2x+3}'

means

It's a single quoted string  with a jme simplify command \simplify{2x+3}

As you can see we need to type two single quotes to get one single quote in the string. This is because the single quote is used to mark the start and end of the string. If we want to type a single quote in the string we need to escape it with another single quote.

Double quoted strings

Double quoted strings are written between double quotes.

"This is a double quoted string"

means

This is a double quoted string

Advantages:

  • Can contain colons (:) followed by a space or a hashtag (#) after a space.
  • Can contain single quotes (') without having to escape them.
  • Newlines can be added by placing an escape character (\) at the end of the line.

Disadvantages:

  • Can't contain double quotes ("). They need to be escaped with a backslash (\).
  • Backslashes (\) are interpreted as escape characters. This means that you can't write a string containing a backslash without escaping it.
    • Special characters like newlines and tabs are interpreted as escape characters.
    • Makes it hard to type a string containing jme commands. Because you will need to escape each backslash.
"It's a double quoted string with a jme simplify command \\simplify{2x+3}"

means

It's a double quoted string with a jme simplify command \simplify{2x+3}

We need to write two backslashes to get one backslash in the string. This is because the backslash is used as the escape character. If we want to type a backslash in the string we need to escape it with another backslash.

Folded strings

Folded strings are written after a greater than sign (>). Newlines are not preserved, they are replaced by a space. Blank lines can be used to insert a newline.

>
    This is a folded string.
    It can contain newlines.

    It can contain colons (:) followed by a space or a hashtag (#) after a space.

    It can contain single quotes (') without having to escape them.
    It can contain double quotes (") without having to escape them.

    It can contain backslashes (\) without having to escape them.

means

This is a folded string. It can contain newlines.
It can contain colons (:) followed by a space or a hashtag (#) after a space.
It can contain single quotes (') without having to escape them. It can contain double quotes (") without having to escape them.
It can contain backslashes (\) without having to escape them.

As you can see, newline are replaced by a space. Blank lines are replaced by a newline.

Literal strings

Literal strings are written after a pipe (|). Newlines are preserved.

|
    This is a literal string.
    It can contain newlines.
    It can contain colons (:) followed by a space or a hashtag (#) after a space.

    It can contain single quotes (') without having to escape them.
    It can contain double quotes (") without having to escape them.
    It can contain backslashes (\) without having to escape them.

means

This is a literal string.
It can contain newlines.
It can contain colons (:) followed by a space or a hashtag (#) after a space.

It can contain single quotes (') without having to escape them.
It can contain double quotes (") without having to escape them.
It can contain backslashes (\) without having to escape them.

As you can see, newlines are preserved. The text is literally as typed, except for the leading spaces that are removed.

Hashes

Hashes map keys to values. They are written as a list of key-value pairs, separated by colons (:). The keys may only contain letters, numbers, and underscores.

key1: value1
key2: value2

The values can be any yaml value, even other hashes.

key1: value1
level1: # the value of this key is a hash
  key2: value2
  level2: # the value of this key is a hash
    key3: value3

The order of the keys in a hash has no meaning. The following two hashes are identical.

some_key: value1
another_key: value2
another_key: value2
some_key: value1

An empty hash can be written as {}.

empty_subhash: {}

Arrays

Arrays are an ordered list of values. They can be written inline or as a block.

Block arrays

Block arrays are written after a dash (-) and a space. Each value is written on a new line.

- value1
- value2

The values can be any yaml value, even other arrays or hashes.

hash_key: 
  - value1
  - value2
other_key: # the value of this key is an array
  - key: value # the value of the first element of the array is a hash
    other: value
  - other_element
list_of_lists:
   # the value of the elements of the array below, are arrays themselves
   - - value1 
     - value2
   - - value3
     - value4

Inline arrays

Inline arrays can be used to write a list of values on a single line. They are written between square brackets ([ and ]), with values separated by commas (,).

[ value1, value2 ]

These values can be any value, except for block hashes or block arrays.

This is mostly used to represent an empty array [] or an array of a small amount of strings.

Anchors and aliases

Anchors and aliases can be used to reference a value multiple times. This is useful when you want to use the same value multiple times, but don't want to write it multiple times.

Anchors are written after an ampersand (&). They are then followed by a key. The key can be any string, but it is recommended to use a unique key.

key1: &anchor_key value
key2: *anchor_key

which is identical to

key1: value
key2: value

It is also possible to use anchors for whole hashes and arrays.

hash_value: &hash
  key1: value1
  key2: value2
also_hash_value: *hash

which is identical to

hash_value:
  key1: value1
  key2: value2
also_hash_value:
  key1: value1
  key2: value2

It is obviously also possible to reference an anchor multiple times.

a_key: &value_to_reuse This can be some long text or any other datatype
another_key: *value_to_reuse
third_key: *value_to_reuse

which is identical to

a_key: This can be some long text or any other datatype
another_key: This can be some long text or any other datatype
third_key: This can be some long text or any other datatype

Yaml files

Each yaml file start with three dashes: --- and is then followed by either a hash or an array.

---
key1: value1
key2: value2
---
- value1
- value2

Comments

Comments can be written after a hashtag (#) The hashtag needs to be the first character on a line or there should be a space in front of it (in unquoted strings). They can be written on a separate line or after a value.

# This is a comment before the opening dashes
---
key1: value1 # This is a comment
# This is a comment before a key
key2: value2 # This is another comment

Writing Rumbas Yaml

The source code for any rumbas exam or question is written in a subset of YAML.

This section will show you how to write YAML files for Rumbas.

Basic objects

The Exam, Question and Custom Part Type reference shows tables that explain the dataformat for rumbas. In its most basic form, it looks like the following reference for the QuestionPartMatrixRangedDimension type which is used to specify the possible sizes for a matrix. If you are new to rumbas, you don't need to (and can't) understand yet what this type is used for. It is just used as an example to explain how to read such a table.

Reference

QuestionPartMatrixRangedDimension

fieldtypedescription
defaultjme-string or IntegerThe default size
minjme-string or IntegerThe minimal size
max"none" or jme-string or IntegerThe maximal size, if this is none, there is no limit

The tables lists three fields that has to be present in the yaml for the object. The first column is the name of the field, the second column is the datatype of the field and the third column is a description of the field.

Info

To represent this datatype in yaml we use hashes.

  • The field name is used as a key
  • The value should have the datatype as described in the second column.

An example would be the following:

default: 2
min: 1
max: 4 # could also be set to none to indicate no maximum

The order of the keys has no meaning, so we could just as well write:

max: 4
min: 1
default: 2

Object with an [any] field

Some objects have a field name [any] in their reference. This means that any other key-value pair can be added to the object.

Reference

TemplateFile

fieldtypedescription
templateStringThe path to the template to use. Relative to the exams or questions folder.
[any]YAML-valueThe data to insert into the template. Maps template keys onto values.

This can be represented in yaml by adding any key-value pair to the hash.

template: path_to_template
# we can add as many other key-value pairs as we want (due to the [any] field)
any_key: any_value
another_key: another_value

Choice object

Some of the datatypes in the reference can take multiple forms.

This following datatype is either a TranslationStruct or a FileString. See the One of the following items: text.

Reference

Translation

One of the following items:

typedescription
TranslationStructA structured translatable string with placeholders.
FileStringA simple filestring. This implies that it can also just be a string.

To represent this datatype in yaml, you would either write a TranslationStruct or a FileString.

A TranslationStruct is specified as follows:

Reference

TranslationStruct

fieldtypedescription
contentTranslationContentThe content with optional placeholders ({{placeholder-name}}).
placeholdersMap from String to TranslationThe values for the placeholders. It maps the placeholder-name to it's translatable value. The value for a placeholder can thus (if needed) be different for different locales.

Which could be represented in yaml as follows:

# TranslationStruct
content: Some content
placeholders: {}

The yaml above is thus also a valid yaml for a Translation.

A FileString is specified as follows:

Reference

FileString

One of the following items:

typedescription
StringA string of the form file:<filepath> where filepath is the relative path (within the exams or questions folder) to a file containing content. This content can be localized by placing it in locale folders. e.g. file:examples/basic-explanation.html will search for files in folders with following form: questions/examples/locale-<localename>/basic-explanation.html If a file isn't found for a specific locale, questions/examples/basic-explanation.html will be used.
StringA literal string.

Which could be represented in yaml as follows:

# FileString
file:path/to/file

or

# FileString
any string value

The yaml above is thus also a valid yaml for a Translation.

Choice object with explicit tag

Sometimes it is needed to explicitly specify the type of a choice object. This is done by adding a specific key-value pair to the object.

This specification below says that we should write the yaml as one of the three given options and add the key-value pair type: <tag-value> to the object to specify which option we chose. This is denoted by the Internal tag named type text.

Reference

ExamFileType

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
templateTemplateFileAn exam that uses a template.
normalNormalExamA normal exam.
diagnosticDiagnosticExamAn exam in diagnostic mode.

If we want to choose the template option, we would write the following yaml for an ExamFileType:

type: template # set the internal tag
# TemplateFile
template: path_to_template 
any_key: any_value

If we want to choose the normal option, we would write the following yaml for an ExamFileType:

type: normal # set the internal tag
# NormalExam
name: The name of the exam
# ... more fields

If we want to choose the diagnostic option, we would write the following yaml for an ExamFileType:

type: diagnostic # set the internal tag
# DiagnosticExam
name: The name of the diagnostic exam
# ... more fields

Folder structure

The folder structure of a rumbas project is important. Some names are reserved and have a special meaning.

  • A folder named defaults that contains the default specifications
  • A folder named questions that contains the questions
  • A folder named exams that contains the exams
  • A folder named themes the contains your custom themes
  • A folder named custom_part_types that contains custom_part_types
  • A folder named resources that contains the resources that are used in exams or questions.

Default folders

TODO: list the files that can be set

It is important to note that rumbas does not specify any default value by itself. Numbas does however have a quite extensive range of options that can be set. Setting all these options for every question and exam would be a real hassle and the files would not be readable.

To prevent this problem, the default folders were created.

Folders named default can be specified:

  • In the root of the rumbas project
  • In any (sub)folder in the exams folder
  • In any (sub)folder in the questions folder

When the description of a question/exam is read:

  • All default folders in ancestor folders are examined for default values:
    • e.g. if a question is positioned in questions/M0/algebra/H1/nul_in_N_and_Z.yaml the following default folders will be checked:
      • questions/M0/algebra/H1/default
      • questions/M0/algebra/default
      • questions/M0/default/
      • questions/default
      • default
  • The default folders are examined in order: first the 'closer' ones.
    • e.g. The folders will be examined in the order shown above

Locale folders

Each subfolder of the exams and questions folder can have a locale folder. This are folders with a name of the form locale-<locale-key>. They allow easily translating things that are used many times.

ExamFileType

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
templateTemplateFileAn exam that uses a template.
normalNormalExamA normal exam.
diagnosticDiagnosticExamAn exam in diagnostic mode.

TemplateFile

fieldtypedescription
templateStringThe path to the template to use. Relative to the exams or questions folder.
[any]YAML-valueThe data to insert into the template. Maps template keys onto values.

NormalExam

fieldtypedescription
nameTranslationThe name of the exam
localesArray of LocaleAll locales for which the exam should be generated
navigationNormalNavigationThe navigation settings for this exam
timingTimingThe timing settings for this exam
feedbackFeedbackThe feedback settings for this exam
question_groupsArray of QuestionGroupThe questions groups for this exam
numbas_settingsNumbasSettingsThe settings to set for numbas

Translation

One of the following items:

typedescription
TranslationStructA structured translatable string with placeholders.
FileStringA simple filestring. This implies that it can also just be a string.

TranslationStruct

fieldtypedescription
contentTranslationContentThe content with optional placeholders ({{placeholder-name}}).
placeholdersMap from String to TranslationThe values for the placeholders. It maps the placeholder-name to it's translatable value. The value for a placeholder can thus (if needed) be different for different locales.

TranslationContent

One of the following items:

typedescription
Map from String to FileStringMap from locale to content. You can use this to specify different content for different locales.
FileStringA filestring. Possibly to a file that is placed in locale folders and is therefore localized.

FileString

One of the following items:

typedescription
StringA string of the form file:<filepath> where filepath is the relative path (within the exams or questions folder) to a file containing content. This content can be localized by placing it in locale folders. e.g. file:examples/basic-explanation.html will search for files in folders with following form: questions/examples/locale-<localename>/basic-explanation.html If a file isn't found for a specific locale, questions/examples/basic-explanation.html will be used.
StringA literal string.

Locale

fieldtypedescription
nameStringThe internal name used for the locale. It is best to use en for English, nl for dutch etc
numbas_localeSupportedLocaleThe locale to use in the Numbas interface

SupportedLocale

One of the following items:

namedescription
"ar-SA"Arabic (Saudi Arabia)
"de-DE"German (Germany)
"en-GB"English (United Kingdom)
"es-ES"Spanish (Spain)
"fr-FR"French (France)
"he-IL"Hebrew (Israel)
"in-ID"Indonesian (Indonesia)
"it-IT"Italian (Italy)
"ja-JP"Japanese (Japan)
"ko-KR"Korean (Korea)
"nb-NO"Norwegian (Norway)
"nl-NL"Dutch (Netherlands)
"pl-PL"Polish (Poland)
"pt-BR"Portuguese (Brazil)
"sq-AL"Albanian (Albania)
"sv-SE"Swedish (Sweden)
"tr-TR"Turkish (Turkey)
"vi-VN"Vietnamese (Viet Nam)
"zg-CN"Chinese (S)

NormalNavigation

Internal tag named mode.

One of the following items:

tag-valuedatatype of valuedescription
sequentialSequentialNavigationQuestions are shown in sequential order. Whether student can browse trough questions in any order, can be set.
menuMenuNavigationQuestions are shown in a menu and there is no real order of the questions.

SequentialNavigation

fieldtypedescription
start_password"none" or FileStringPassword to begin the exam none and "" are the same
can_regenerateBooleanWhether the student can regenerate questions Old name was allow_regenerate
show_stepsBooleanIf false, then part steps will not be offered to the student, regardless of whether any have been defined in the exam’s questions Old name was allow_steps
show_title_pageBooleanWhether the title page should be shown. Old name was show_frontpage
confirm_when_leavingBooleanWhether the student will be asked to confirm when leaving the exam.
show_names_of_question_groupsBooleanWhether the names of the question groups should be shown.
allow_printingBooleanWhether the student is allowed to print the exam
can_move_to_previousBooleanWhether the student can move back to previous question (Old name was reverse)
browsing_enabledBooleanWhether the student can jump to any question.
show_results_pageShowResultsPageWhen the results page should be shown
on_leaveLeaveActionAction to execute when a student changes question or tries to end the exam.

ShowResultsPage

One of the following items:

namedescription
"on_completion"When the exam is completed.
"never"Never show it.

LeaveAction

Internal tag named action.

One of the following items:

tag-valuedatatype of valuedescription
"none"Don't show a warning
warn_if_not_attemptedLeaveActionMessageWarn when a question is not attempted.
prevent_if_not_attemptedLeaveActionMessagePrevent when a question is not attempted

LeaveActionMessage

fieldtypedescription
messageTranslationThe message to show.

MenuNavigation

fieldtypedescription
start_password"none" or FileStringPassword to begin the exam none and "" are the same
can_regenerateBooleanWhether the student can regenerate questions Old name was allow_regenerate
show_stepsBooleanIf false, then part steps will not be offered to the student, regardless of whether any have been defined in the exam’s questions Old name was allow_steps
show_title_pageBooleanWhether the title page should be shown. Old name was show_frontpage
confirm_when_leavingBooleanWhether the student will be asked to confirm when leaving the exam.
show_names_of_question_groupsBooleanWhether the names of the question groups should be shown.
allow_printingBooleanWhether the student is allowed to print the exam

Timing

fieldtypedescription
duration_in_seconds"none" or IntegerThe maximal time that can be spend on the exam. If this value is none or 0, the student gets unlimited time.
allow_pauseBooleanWhether the 'pause' button is available.
on_timeoutTimeoutActionAction to do on timeout
timed_warningTimeoutActionAction to do five minutes before timeout

TimeoutAction

Internal tag named action.

One of the following items:

tag-valuedatatype of valuedescription
"none"Do nothing
warnTimeoutActionWarnShow a warning

TimeoutActionWarn

fieldtypedescription
messageTranslationThe message to show

Feedback

fieldtypedescription
percentage_needed_to_pass"none" or FloatSpecifies when a student passes the test. When set to "none" or 0, no percentage will be shown in frontpage.
show_name_of_studentBooleanWhether the student's name should be shown in the exam.
show_current_marksBooleanWhether current marks are shown during exam or not (show_actual_mark in numbas)
show_maximum_marksBooleanWhether the maximal mark for a question (or the total exam) is shown (show_total_mark of numbas)
show_answer_stateBooleanWhether answer feedback is shown (right or wrong etc)
allow_reveal_answerBooleanWhether the 'reveal answer' button is present
reviewReviewThe review settings
adviceTranslationThe advice shown at the end.
introTranslationThe introductory text
feedback_messagesArray of FeedbackMessageDifferent feedback messages based on their score.

Review

fieldtypedescription
show_scoreBooleanWhether to show score in result overview page
show_feedbackBooleanShow feedback while reviewing
show_expected_answerBooleanShow expected answer while reviewing
show_adviceBooleanShow advice while reviewing

FeedbackMessage

fieldtypedescription
messageStringThe message to show
thresholdStringThe minimum score that is needed to get this feedback

QuestionGroup

fieldtypedescription
nameTranslationThe name of the question group. Might be shown to students, based on the show_names_of_question_groups setting of the exam navigation.
picking_strategyPickingStrategyThe strategy to use to pick the questions to show
questionsArray of QuestionPathOrTemplateThe questions

PickingStrategy

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
"all_ordered"All questions in the group are shown in the given order
"all_shuffled"All questions in the group are shown in a random order for each attempt
random_subsetPickingStrategyRandomSubsetA random subset of the questions in this group will be shown. The amount of random questions to show, needs to be specified

PickingStrategyRandomSubset

fieldtypedescription
pick_questionsIntegerThe amount of questions to pick

QuestionPathOrTemplate

One of the following items:

typedescription
StringThe path to the question. Relative to the questions folder.
TemplateFileDirectly load a templated question by specifying the template values.

NumbasSettings

fieldtypedescription
themeStringThe numbas theme to use

DiagnosticExam

fieldtypedescription
nameTranslationThe name of the exam
localesArray of LocaleAll locales for which the exam should be generated
navigationDiagnosticNavigationThe navigation settings for this exam
timingTimingThe timing settings for this exam
feedbackFeedbackThe feedback settings for this exam
question_groupsArray of QuestionGroupThe questions groups for this exam
numbas_settingsNumbasSettingsThe settings to set for numbas
diagnosticDiagnosticThe diagnostic data

DiagnosticNavigation

fieldtypedescription
start_password"none" or FileStringPassword to begin the exam none and "" are the same
can_regenerateBooleanWhether the student can regenerate questions Old name was allow_regenerate
show_stepsBooleanIf false, then part steps will not be offered to the student, regardless of whether any have been defined in the exam’s questions Old name was allow_steps
show_title_pageBooleanWhether the title page should be shown. Old name was show_frontpage
confirm_when_leavingBooleanWhether the student will be asked to confirm when leaving the exam.
show_names_of_question_groupsBooleanWhether the names of the question groups should be shown.
allow_printingBooleanWhether the student is allowed to print the exam
on_leaveLeaveActionAction to execute when a student changes question or tries to end the exam.

Diagnostic

fieldtypedescription
scriptDiagnosticScriptThe script to use
objectivesArray of LearningObjectiveThe learning objectives,
topicsArray of LearningTopicThe learning topics

DiagnosticScript

One of the following items:

namedescription
"mastery"The aim of the Mastery algorithm is to repeatedly test topics until the student passes them. Once all topics are passed, the exam ends. see https://docs.numbas.org.uk/en/latest/exam/diagnostic.html#mastery
"diagnosys"The aim of the DIAGNOSYS algorithm is to efficiently establish which topics the student understands, and which they don’t. see https://docs.numbas.org.uk/en/latest/exam/diagnostic.html#diagnosys
"custom"A custom diagnostic script. See https://docs.numbas.org.uk/en/latest/exam/diagnostic.html#writing-a-diagnostic-algorithm

LearningObjective

fieldtypedescription
nameTranslationThe name of the learning objective
descriptionTranslationA description of the learning objective

LearningTopic

fieldtypedescription
nameTranslationThe name of the learning topic
descriptionTranslationA description of the learning topic
objectivesArray of TranslationList of names of objectives of which this topic consists
depends_onArray of TranslationList of names of topics on which this topic depends

QuestionFileType

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
templateTemplateFileA question that uses a template
normalQuestionA normal question

TemplateFile

fieldtypedescription
templateStringThe path to the template to use. Relative to the exams or questions folder.
[any]YAML-valueThe data to insert into the template. Maps template keys onto values.

Question

fieldtypedescription
statementTranslationThe statement is a content area which appears at the top of the question, before any input boxes. Use the statement to set up the question and provide any information the student needs to answer it.
adviceTranslationAdvice is a content area which is shown when the student presses the Reveal button to reveal the question’s answers, or at the end of the exam. The advice area is normally used to present a worked solution to the question.
partsArray of QuestionPartA question consists of one or more parts. Each part can have a different type to create elaborate questions.
builtin_constantsBuiltinConstantsSpecifies which constants are enabled. You might want to disable the constant e so it can be used as a variable in the questions.
custom_constantsArray of CustomConstantCustom constants that are used in your question.
variablesMap from String to VariableRepresentationThe (ungrouped) variables that are used in this question.
grouped_variables"none" or Map from String to Map from String to VariableRepresentationThe (grouped) variables that are used in this question. This is a map from a group name to a map of variables. Should mainly be used to make it easier to template multiple variables at once.
variables_testVariablesTestThe test to which your variables should comply. Sometimes it’s hard to define randomised question variables so they’re guaranteed to produce a usable set of values. In these cases, it’s easier to state the condition you want the variables to satisfy, Variable values are generated until this condition passes.
While this tool allows you to pick sets of variables that would be hard to generate constructively, it’s a random process so you must be aware that there’s a chance no suitable set of values will ever be found.
functionsMap from String to FunctionThe functions that are used in this question
preamblePreambleSpecify custom javascript and css code that should be loaded.
navigationQuestionNavigationSpecify some navigation options for the question.
extensionsExtensionsUse this to enable the extensions that are used in the question
diagnostic_topic_namesArray of TranslationThe names of the topics used in diagnostic exams that this question belongs to
resourcesArray of ResourcePathThe paths to the resources
custom_part_typesArray of CustomPartTypeDefinitionPathThe custom part types used in this exam
rulesetsMap from String to JMERulesetItemThe rulesets defined in this question. A “ruleset” defines a list of named simplification rules used to manipulate mathematical expressions. https://numbas-editor.readthedocs.io/en/latest/question/reference.html#rulesets

Translation

One of the following items:

typedescription
TranslationStructA structured translatable string with placeholders.
FileStringA simple filestring. This implies that it can also just be a string.

TranslationStruct

fieldtypedescription
contentTranslationContentThe content with optional placeholders ({{placeholder-name}}).
placeholdersMap from String to TranslationThe values for the placeholders. It maps the placeholder-name to it's translatable value. The value for a placeholder can thus (if needed) be different for different locales.

TranslationContent

One of the following items:

typedescription
Map from String to FileStringMap from locale to content. You can use this to specify different content for different locales.
FileStringA filestring. Possibly to a file that is placed in locale folders and is therefore localized.

FileString

One of the following items:

typedescription
StringA string of the form file:<filepath> where filepath is the relative path (within the exams or questions folder) to a file containing content. This content can be localized by placing it in locale folders. e.g. file:examples/basic-explanation.html will search for files in folders with following form: questions/examples/locale-<localename>/basic-explanation.html If a file isn't found for a specific locale, questions/examples/basic-explanation.html will be used.
StringA literal string.

QuestionPart

One of the following items:

typedescription
QuestionPartBuiltinA question part using a builtin question part type
QuestionPartCustomA question part using a custom question part type

QuestionPartBuiltin

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
jmeQuestionPartJMEMathematical expression parts require the student to enter an algebraic expression, using JME syntax.
gapfillQuestionPartGapFillGap-fill parts allow you to include answer inputs inline with the prompt text, instead of at the end of the part. Each gap is a question part in itself.
choose_oneQuestionPartChooseOneMultiple choice part where the student must choose one of several options
choose_multipleQuestionPartChooseMultipleMultiple choice part where the student can choose any of a list of options
match_answersQuestionPartMatchAnswersWithItemsThe student is presented with a 2D grid of choices and answers. Depending on how the part is set up, they must either match up each choice with an answer, or select any number of choice-answer pairs.
number_entryQuestionPartNumberEntryNumber entry parts ask the student to enter a number, which is marked if it is in a specified range
pattern_matchQuestionPartPatternMatchUse a text pattern part when you want the student to enter short, non-mathematical text.
informationQuestionPartInformationAn information part contains only a prompt and no answer input. It is most often used as a Step to provide a hint for a parent part.
extensionQuestionPartExtensionAn extension part acts as a placeholder for any interactive element added by an extension, or custom code in the question, which awards marks to the student.
matrixQuestionPartMatrixMatrix entry parts ask the student to enter a matrix of numbers. Marks are awarded if every cell in the student’s answer is equal to the corresponding cell in the correct answer, within the allowed margin of error.

QuestionPartJME

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
answerTranslationThe expected answer to the part.
answer_simplificationJMEAnswerSimplificationSimplification rules to apply to the correct answer, if it is displayed to the student (for example, after clicking the Reveal answers button). This shouldn’t affect marking. The simplification rules to apply to the answer
answer_displayJMEAnswerDisplayThe display rules to apply to the answer
show_previewBooleanIf ticked, a rendering of the student’s answer in mathematical notation is displayed beside the input box.
accuracyJMEAccuracyDefines the range of points over which the student’s answer will be compared with the correct answer, and the method used to compare them
check_variable_namesBooleanIf this is ticked, all variable names used in the student’s are checked against the variable names used in the correct answer. The first variable name which is not used in the correct answer will trigger a warning. You can use this option to prevent students incorrectly entering answers such as xy, which is interpreted as a single variable, when they mean x*y, the product of two variables.
single_letter_variablesBooleanIf this is ticked, long variable names will be interpreted as implicit multiplication of variables with single-letter names. For example, xyz will be interpreted as x * y * z. Digits, primes and single-letter underscores are still valid in variable names: a'x12y_z will be interpreted as a' * x12 * y_z. Greek letters are considered to be a single letter: pix will be interpreted as pi * x.
allow_unknown_functionsBooleanIf this is not ticked, the application of a function that is not defined in JME will be reinterpreted. If the function name can be split into several shorter names, each of which is defined in JME, it will be: for example, lnabs(x) will be interpreted as ln(abs(x)). Function names are recognised from right to left. Any remaining characters are interpreted as implicit multiplication by a variable. For example, xsin(x) will be interpreted as x * sin(x).
implicit_function_compositionBooleanIf this is ticked, the multiplication symbol (or implicit multiplication) will be interpreted as function composition when the right-hand side is a function application with one argument, and the left-hand side is the name of a function defined in JME. For example, ln * abs(x) and ln abs(x) will be interpreted as ln(abs(x)).
must_match_pattern"none" or JMEPatternRestrictionThe student’s answer must match the given pattern. If it does not, then a penalty is applied.
value_generators"none" or Array of JMEValueGeneratorVariable value generators override the default method used to pick values for variables when comparing the correct answer with the student’s answer. The expression for each variable can be written in terms of the other variables, as long as there are no circular dependencies. The values will be evaluated in order, like question variables. Each variable specified in the expected answer can be overriden The variable vRange represents the checking range defined for this part: a continuous interval between the checking range start and checking range end.
max_length"none" or JMELengthRestrictionDEPRECATED String restrictions are an unreliable method of restricting the form of a student’s answer. They are deprecated and retained only for backwards compatibility; use a pattern restriction instead.
Before string restrictions are applied, surplus brackets and whitespace are removed, and spaces are inserted between some operations, to minimise the possibility of the length restrictions being triggered for the wrong reasons.
If the student’s answer contains more than this many characters, the penalty is applied. A value of zero means no restriction is applied. The student’s answer is tidied up slightly so that things like extra or missing space characters don’t affect the calculated length. All spaces are removed, and then spaces are inserted between binary operations. For example, the answer 1+x (three characters) is marked as 1 + x (five characters).
min_length"none" or JMELengthRestrictionDEPRECATED String restrictions are an unreliable method of restricting the form of a student’s answer. They are deprecated and retained only for backwards compatibility; use a pattern restriction instead.
Before string restrictions are applied, surplus brackets and whitespace are removed, and spaces are inserted between some operations, to minimise the possibility of the length restrictions being triggered for the wrong reasons.
If the student’s answer contains fewer than this many characters, the penalty is applied. A value of zero means no restriction is applied.
must_have"none" or JMEStringRestrictionDEPRECATED String restrictions are an unreliable method of restricting the form of a student’s answer. They are deprecated and retained only for backwards compatibility; use a pattern restriction instead.
Before string restrictions are applied, surplus brackets and whitespace are removed, and spaces are inserted between some operations, to minimise the possibility of the length restrictions being triggered for the wrong reasons.
If the student’s answer doesn’t contain all of these strings, the penalty is applied.
may_not_have"none" or JMEStringRestrictionDEPRECATED String restrictions are an unreliable method of restricting the form of a student’s answer. They are deprecated and retained only for backwards compatibility; use a pattern restriction instead.
Before string restrictions are applied, surplus brackets and whitespace are removed, and spaces are inserted between some operations, to minimise the possibility of the length restrictions being triggered for the wrong reasons.
If the student’s answer contains any of these strings, the penalty is applied.

Number

One of the following items:

typedescription
IntegerAn integer / whole number
FloatA real number

CustomMarking

fieldtypedescription
algorithm_notesArray of JMENoteThis allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
extend_base_marking_algorithmBooleanIf this is ticked, all marking notes provided by the part’s standard marking algorithm will be available. If the same note is defined in both the standard algorithm and your custom algorithm, your version will be used.

JMENote

fieldtypedescription
nameStringThe name of the note
description"none" or StringA description of the note
expressionTranslationThe jme expression representing the note

AdaptiveMarking

fieldtypedescription
variable_replacementsArray of VariableReplacementThe variable replacements to do
variable_replacement_strategyVariableReplacementStrategyThe circumstances under which the variable replacements are used, and adaptive marking is applied.
penaltyIntegerIf adaptive marking is used, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. See steps_penalty for an example.

VariableReplacement

fieldtypedescription
variableStringThe name of the variable to replace
part_answer_to_useStringThe path to the part whose answer the variable’s value should be replaced with. Different part types produce different types of values.
must_be_answeredBooleanIf this is ticked, the student must submit an answer to the referenced part before they can submit an answer to this part.

VariableReplacementStrategy

One of the following items:

namedescription
"original_first"The student’s answer is first marked using the original values of the question variables. If the credit given by this method is less than the maximum available, the marking is repeated using the defined variable replacements. If the credit gained with variable replacements is greater than the credit gained under the original marking, that score is used, and the student is told that their answers to previous parts have been used in the marking for this part.
"always_replace"The student’s answer is only marked once, with the defined variable replacements applied.

JMEAnswerSimplification

fieldtypedescription
simplify_basicBooleanSome basic rules: https://numbas-editor.readthedocs.io/en/latest/simplification.html?highlight=simplification#term-basic
cancel_unit_factorsBooleanCancel products of 1
cancel_unit_powersBooleanCancel exponents of 1
cancel_unit_denominatorsBooleanCancel fractions with denominator 1
cancel_zero_factorsBooleanCancel products of zero to zero
omit_zero_termsBooleanOmit zero terms
cancel_zero_powersBooleanCancel exponents of 0
cancel_powers_with_base_zeroBooleanCancel any power of zero
collect_numbersBooleanCollect together numerical (as opposed to variable) products and sums.
constants_firstBooleanNumbers go to the left of multiplications
collect_sqrt_productsBooleanCollect products of square roots
collect_sqrt_divisionsBooleanCollect fractions of square roots
cancel_sqrt_squareBooleanCancel square roots of squares, and squares of square roots
evaluate_powers_of_numbersBooleanEvaluate powers of numbers.
rewrite_to_no_leading_minusBooleanRearrange expressions so they don’t start with a unary minus
simplify_fractionsBooleanCancel fractions to lowest form
simplify_trigonometricBooleanSimplify some trigonometric identities
collect_termsBooleanCollect together and cancel terms. Like collectNumbers, but for any kind of term.
collect_powers_of_common_factorsBooleanCollect together powers of common factors.
collect_like_fractionsBooleanCollect together fractions over the same denominator.
order_canonicalBooleanRearrange the expression into a “canonical” order, using canonical_compare.
Note: This rule can not be used at the same time as rewrite_to_no_leading_minus - it can lead to an infinite loop.
expand_bracketsBooleanExpand out products of sums.

JMEAnswerDisplay

fieldtypedescription
broken_as_fractionsBooleanThis rule doesn’t rewrite expressions, but tells the maths renderer that you’d like non-integer numbers to be displayed as fractions instead of decimals.
mixed_fractionsBooleanImproper fractions (with numerator larger than the denominator) are displayed in mixed form, as an integer next to a proper fraction.
flat_fractionsBooleanFractions are displayed on a single line, with a slash between the numerator and denominator.
vector_as_rowBooleanThis rule doesn’t rewrite expressions, but tells the maths renderer that you’d like vectors to be rendered as rows instead of columns.
always_show_multiplication_signBooleanThe multiplication symbol is always included between multiplicands.
use_dot_as_multiplication_signBooleanUse a dot for the multiplication symbol instead of a cross.
matrices_without_parenthesesBooleanMatrices are rendered without parentheses.

JMEAccuracy

fieldtypedescription
checking_typeCheckingTypeThe rule to use to compare the student’s answer with the correct answer.
checking_rangeArray of FloatThe minimum and maximum value sample points can take [minimum, maximum]
points_to_checkIntegerThe number of comparisons to make between the student’s answer and the correct answer.
max_failuresFloatIf the comparison fails this many times or more, the student’s answer is marked as wrong.

CheckingType

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
relative_differenceCheckingTypeDataFloatFail if studentanswer / expectedanswer - 1 > amount
absolute_differenceCheckingTypeDataFloatFail if abs(studentanswer - expectedanswer) > amount
decimal_placesCheckingTypeDataNaturalx and y are rounded to a certain amount of decimal places, and the test fails if the rounded values are unequal
significant_figuresCheckingTypeDataNaturalx and y are rounded to significant figures, and the test fails if the rounded values are unequal.

CheckingTypeDataFloat

fieldtypedescription
max_differenceFloatMaximum relative or absolute difference

CheckingTypeDataNatural

fieldtypedescription
amountIntegerAmount of decimal places or significant figures

JMEPatternRestriction

fieldtypedescription
partial_creditFloatIf the student’s answer does not match the given pattern, their score is multiplied by this percentage.
messageTranslationWarning message
patternStringSee https://numbas-editor.readthedocs.io/en/latest/pattern-matching/examples.html#pattern-matching-examples for example patterns
name_to_compareStringThe part of the expression to mark

JMEValueGenerator

fieldtypedescription
nameFileStringThe name of the variable
valueJMEFileStringThe expression to generate the value

JMEFileString

One of the following items:

typedescription
StringA string of the form file:<filepath> where filepath is the relative path (within the exams or questions folder) to a file containing content. This content can be localized by placing it in locale folders. e.g. file:examples/basic-explanation.html will search for files in folders with following form: questions/examples/locale-<localename>/basic-explanation.html If a file isn't found for a specific locale, questions/examples/basic-explanation.html will be used.
StringA literal string.

JMELengthRestriction

fieldtypedescription
partial_creditFloatThe partial credit (percentage) attributed when failing the restriction
messageTranslationWarning message
lengthIntegerThe minimum or maximum length

JMEStringRestriction

fieldtypedescription
partial_creditFloatThe partial credit (percentage) attributed when failing the restriction
messageTranslationWarning message
stringsArray of TranslationThe strings that are required or forbidden
show_stringsBooleanWhether to show the strings

QuestionPartGapFill

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
sort_answersBooleanIf ticked, then the student’s answers will be put in ascending order before the gaps are marked. The lowest answer will be submitted against the first gap, and so on. Because the order of marking might not correspond with the order in which the gaps are shown to the student, no feedback icon is shown next to the gap input boxes, only in the feedback summary for the whole part.
gapsArray of QuestionPartThe question parts for the gaps

QuestionPartChooseOne

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
answer_dataMultipleChoiceAnswerDataSpecify the options, score per option and feedback per option. Old name was answers
shuffle_answersBooleanIf this is ticked, the choices are displayed in random order.
show_cell_answer_stateBooleanIf ticked, choices selected by the student will be highlighted as ‘correct’ if they have a positive score, and ‘incorrect’ if they are worth zero or negative marks. If this is not ticked, the ticked choices will be given a neutral highlight regardless of their scores.
displayChooseOneDisplayHow should the options be shown?

MultipleChoiceAnswerData

One of the following items:

typedescription
Array of MultipleChoiceAnswerSpecify a list of answer with it's marks and feedback
MultipleChoiceAnswerDataNumbasLikeSpecify the answers, marks and feedback as separate lists. The first answers, matches the first mark and the first feedback etc

MultipleChoiceAnswer

fieldtypedescription
statementTranslationThe statement of the answer
feedbackTranslationThe feedback shown when this answer is chosen
marksTranslationThe marks to assign when this answer is chosen

MultipleChoiceAnswerDataNumbasLike

fieldtypedescription
answersjme-string or Array of TranslationThe possible answers
marksjme-string or Array of TranslationThe marks for the corresponding answers
feedback"none" or Array of TranslationThe feedback for the corresponding answers.

ChooseOneDisplay

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
"dropdown"“Drop down list” means that the choices are shown as a selection box; the student can click to show the choices in a vertical list.
radioChooseOneDisplay_radio“Radio” means that choices are shown separately, in-line with the part prompt.

ChooseOneDisplay_radio

fieldtypedescription
columnsIntegerThis dictates how many columns the choices are displayed in. If 0, the choices are displayed on a single line, wrapped at the edges of the screen.

QuestionPartChooseMultiple

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
answer_dataMultipleChoiceAnswerDataSpecify the options, score per option and feedback per option. Old name was answers
shuffle_answersBooleanIf this is ticked, the choices are displayed in random order.
show_cell_answer_stateBooleanIf ticked, choices selected by the student will be highlighted as ‘correct’ if they have a positive score, and ‘incorrect’ if they are worth zero or negative marks. If this is not ticked, the ticked choices will be given a neutral highlight regardless of their scores.
should_select_at_leastIntegerThe student must select at least this many choices. The value 0 means “no minimum”, though the student must make at least one choice to submit the part.
should_select_at_most"none" or IntegerThe student must select at most this many choices. The value 0 means “no maximum”.
columnsIntegerThis dictates how many columns the choices are displayed in. If 0, the choices are displayed on a single line, wrapped at the edges of the screen.
wrong_nb_answers_warning_typeMultipleChoiceWarningTypeWhat to do if the student picks the wrong number of responses? Either "none" (do nothing), "prevent" (don’t let the student submit), or "warn" (show a warning but let them submit)
minimal_achievable_marks"none" or IntegerIf the student would have scored less than this many marks, they are instead awarded this many. Useful in combination with negative marking.
maximal_achievable_marks"none" or IntegerIf the student would have scored more than this many marks, they are instead awarded this many. The value 0 means “no maximum mark”.
marking_methodMultipleChoiceMarkingMethodThis determines how the student’s score is determined, based on their selections and the marking matrix.

MultipleChoiceWarningType

One of the following items:

namedescription
"none"Do nothing
"prevent"Prevent submission until they pick an acceptable number of answers

MultipleChoiceMarkingMethod

One of the following items:

namedescription
"sum_ticked_cells"For each checkbox the student ticks, the corresponding entry in the marking matrix is added to their score. Unticked cells are ignored.
This marking method is suitable for situations where the student should only select choices they’re sure about. You could apply negative marks for incorrect choices.
"score_per_matched_cell"For each checkbox, the student is awarded an equal proportion of the Maximum marks, if their selection for that cell matches the marking matrix. A positive value in the marking matrix signifies that the student should tick that checkbox, while a value of zero signifies that the student should not tick that box.
This marking method is suitable for situations where the student must separate the available choices into two sets.
"all_or_nothing"the student is awarded the Maximum marks available if their selection exactly matches the marking matrix, and zero marks otherwise.
This marking method is suitable for situations where the student must exactly match a certain pattern, and there is no meaningful “partially correct” answer.

QuestionPartMatchAnswersWithItems

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
answer_dataMultipleChoiceMatchAnswerDataSpecify the options, score per option and feedback per option. Old name was answers
shuffle_answersBooleanIf this is ticked, the choices are displayed in random order.
shuffle_itemsBooleanIf this is ticked, the items (horizontal) are displayed in random order.
show_cell_answer_stateBooleanIf ticked, choices selected by the student will be highlighted as ‘correct’ if they have a positive score, and ‘incorrect’ if they are worth zero or negative marks. If this is not ticked, the ticked choices will be given a neutral highlight regardless of their scores.
should_select_at_leastIntegerThe student must select at least this many choices. The value 0 means “no minimum”, though the student must make at least one choice to submit the part.
should_select_at_most"none" or IntegerThe student must select at most this many choices. The value 0 means “no maximum”.
displayMatchAnswerWithItemsDisplayHow should the options be shown?
layoutMatchAnswersWithChoicesLayoutHow should the options be shown?
wrong_nb_answers_warning_typeMultipleChoiceWarningTypeWhat to do if the student picks the wrong number of responses? Either "none" (do nothing), "prevent" (don’t let the student submit), or "warn" (show a warning but let them submit)
minimal_achievable_marks"none" or IntegerIf the student would have scored less than this many marks, they are instead awarded this many. Useful in combination with negative marking.
maximal_achievable_marks"none" or IntegerIf the student would have scored more than this many marks, they are instead awarded this many. The value 0 means “no maximum mark”.

MultipleChoiceMatchAnswerData

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
item_basedMultipleChoiceMatchAnswersSpecify a list of answers and a list of items with marks for different answers
numbas_likeMultipleChoiceMatchAnswerDataNumbasLikeSpecify a list of answers, choices and marks in separate lists.

MultipleChoiceMatchAnswers

fieldtypedescription
answersArray of TranslationValues of the answers
itemsArray of MatchAnswersItemItems for which the answer can be selected

MatchAnswersItem

fieldtypedescription
statementTranslationThe statement for the item
answer_marksArray of MatchAnswersItemMarksMap points to strings of answers ! use anchors in yaml

MatchAnswersItemMarks

fieldtypedescription
marksJMEStringThe marks a student get's for selecting the answer
answerTranslationThe answer that yields marks for the item

MultipleChoiceMatchAnswerDataNumbasLike

fieldtypedescription
answersjme-string or Array of TranslationThe possible answers
choicesjme-string or Array of TranslationThe possible choices
marksjme-string or Array of Array of JMEStringThe marks for the corresponding answers

MatchAnswerWithItemsDisplay

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
"radio"One from each row
checkMatchAnswersWithChoicesDisplayCheckAny number from each row

MatchAnswersWithChoicesDisplayCheck

fieldtypedescription
marking_methodMultipleChoiceMarkingMethodThe marking method to use

MatchAnswersWithChoicesLayout

fieldtypedescription
typeMatchAnswersWithChoicesLayoutTypeWhich fields should be shown

MatchAnswersWithChoicesLayoutType

One of the following items:

namedescription
"all"All options are shown
"lower_triangle"Only the lower triangle is shown

QuestionPartNumberEntry

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
answerNumberEntryAnswerThe expected answer
display_correct_as_fractionBooleanIf this is ticked, the correct answer to the part will be rendered as a fraction of two whole numbers instead of a decimal. For example, if the answer is 0.5, it will be displayed as 1/2 instead of 0.5.
allow_fractionsBooleanIf this is ticked, the student can enter a ratio of two whole numbers, e.g. -3/8, as their answer.
fractions_must_be_reducedBooleanThis option only applies when “allow_fractions” is ticked. If this is ticked, the student must enter their fractional answer reduced to lowest terms. For example, consider a part whose correct answer is 5/4. If this is ticked, 10/8 will be marked as incorrect.
fractions_must_be_reduced_hintBooleanIf this is ticked and fractions_must_be_reduced is ticked, then text explaining that the student must reduce their fraction to lowest terms is shown next to the input box.
partial_credit_if_fraction_not_reducedNumberThe proportion of credit to award if the student’s answer is a non-reduced fraction.
allowed_notation_stylesArray of AnswerStyleThe styles of number notation that the student can use to enter their answer. There are different ways of writing numbers, based on culture and context. Tick an option to allow the student to use that style in their answer. Note that some styles conflict with each other: for example, 1.234 is a number between 1 and 2 in English, while it’s the integer 1234 in French. The student’s answer will be interpreted using the first allowed style for which it is a valid representation of a number.
display_correct_in_styleAnswerStyleThe style of number notation to use when displaying the student’s answer.

NumberEntryAnswer

One of the following items:

typedescription
JMEStringThe answer is accepted as correct when it equals this value
NumberEntryAnswerRangeThe answer is accepted as correct when it is within a range

NumberEntryAnswerRange

fieldtypedescription
fromJMEStringThe smallest value accepted as correct.
toJMEStringThe largest value accepted as correct.

AnswerStyle

One of the following items:

namedescription
"english"English style - commas separate thousands, dot for decimal point
"english-plain"Plain English style - no thousands separator, dot for decimal point
"english-si"English SI style - spaces separate thousands, dot for decimal point
"european"Continental European style - dots separate thousands, comma for decimal poin
"european-plain"Plain French style - no thousands separator, comma for decimal point
"french-si"French SI style - spaces separate thousands, comma for decimal point
"indian"Indian style - commas separate groups, dot for decimal point. The rightmost group is three digits, other groups are two digits.
"scientific"Significand-exponent ("scientific") style
"swiss"Swiss style - apostrophes separate thousands, dot for decimal point

QuestionPartPatternMatch

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
case_sensitiveBooleanIf this is ticked, the capitalisation of the student’s answer must match that of the answer pattern. If it doesn’t, partial credit will be awarded.
wrong_case_partial_creditFloatThe partial credits awarded if the students capitalisation is wrong
patternTranslationThe text or pattern the student must match.
display_answerTranslationA representative correct answer string to display to the student, in case they press the Reveal answers button.
match_modePatternMatchModeThe test to use to decide if the student’s answer is correct. Some examples https://numbas-editor.readthedocs.io/en/latest/question/parts/match-text-pattern.html#regular-expressions

PatternMatchMode

One of the following items:

namedescription
"regex"The pattern is interpreted as a regular expression (https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions)
"exact"Marks the student’s answer as correct only if it is exactly the same as the text given in Answer pattern. Space characters are removed from the start and end of the student’s answer as well as the answer pattern before comparison.

QuestionPartInformation

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking

QuestionPartExtension

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking

QuestionPartMatrix

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
correct_answerJMEStringThe expected answer to the part. This is a JME expression which must evaluate to a matrix.
dimensionsQuestionPartMatrixDimensionsThe dimensions of the student's answer field
max_absolute_deviationFloatIf the absolute difference between the student’s value for a particular cell and the correct answer’s is less than this value, then it will be marked as correct.
mark_partial_by_cellsBooleanIf this is set to true, the student will be awarded marks according to the proportion of cells that are marked correctly. If this is not ticked, they will only receive the marks for the part if they get every cell right. If their answer does not have the same dimensions as the correct answer, they are always awarded zero marks.
display_correct_as_fractionBooleanIf this is ticked, then non-integer numbers in the correct answer will be displayed as fractions instead of decimals.
allow_fractionsBooleanIf this is ticked, the student can enter a ratio of two whole numbers, e.g. -3/8, as their answer.

QuestionPartMatrixDimensions

fieldtypedescription
rowsQuestionPartMatrixDimensionThe number of rows in the student’s answer field.
columnsQuestionPartMatrixDimensionThe number of columns in the student’s answer field.

QuestionPartMatrixDimension

One of the following items:

namedescription
"Fixed"The dimensions are fixed
"Resizable"The student can change the dimensions

QuestionPartMatrixRangedDimension

fieldtypedescription
defaultjme-string or IntegerThe default size
minjme-string or IntegerThe minimal size
max"none" or jme-string or IntegerThe maximal size, if this is none, there is no limit

QuestionPartCustom

fieldtypedescription
promptTranslationA content area used to prompt the student for an answer.
marksNumberThe number of marks to award for answering the part correctly.
part_name"none" or StringAn optional custom part name, to use in part path's
show_correct_answerBooleanWhen the student reveals answers to the question, or views the question in review mode, should a correct answer be shown? You might want to turn this off if you’re doing custom marking and the part has no “correct” answer.
show_feedback_iconBooleanAfter the student submits an answer to this part, should an icon describing their score be shown? This is usually shown next to the input field, as well as in the feedback box. This option also controls whether feedback messages are shown for this part. You might want to turn this off if you’ve set up a question with a custom marking script which assigns a score based on the answers to two or more parts (or gapfills), meaning the individual parts have no independent “correct” or “incorrect” state.
stepsArray of QuestionPartA (possibly empty) list of sub-parts which the student can reveal by clicking on a button. Marks awarded for steps don’t increase the total available for the part, but are given in case the student gets a lower score for the main part.
steps_penaltyNumberIf the student reveals the Steps, reduce the total available marks by this amount. Credit for the part is scaled down accordingly. For example, if there are 6 marks available and the penalty for revealing steps is 2 marks, the total available after revealing steps is 4. An answer worth 3 marks without revealing steps is instead worth 3 * 4/6 = 2 marks after revealing steps.
custom_marking"none" or CustomMarkingThe marking algorithm tab allows you to customise the script used to mark the student’s answer, and test that it works correctly on answers that you provide.
adaptive_marking"none" or AdaptiveMarkingAdaptive marking allows you to incorporate the student’s answers to earlier parts when marking their answer to another part. You could use this to allow an “error carried forward” marking scheme, or in more free-form questions where one part has no correct answer - for example, “think of a number and find its square root”. This is achieved by replacing the values of question variables with the student’s answers to other parts. When a variable is replaced, any other variables depending on that one are recalculated using the new value. All other variables keep their original values. See for more info and a warning https://numbas-editor.readthedocs.io/en/latest/question/parts/reference.html#adaptive-marking
typeStringThe name of the custom part name
settingsMap from String to CustomPartInputTypeValueThe settings for the CustomPartType

BuiltinConstants

fieldtypedescription
eBooleanWhether the constant e is enabled
piBooleanWhether the constant pi is enabled
iBooleanWhether the constant i is enabled-

CustomConstant

fieldtypedescription
nameStringThe name of the constant
valueJMEStringThe value of the constant
texStringThe tex code use to display the constant

VariablesTest

fieldtypedescription
conditionJMEStringA JME expression which should evaluate to true when the set of variables generated has the properties you want. For example, if a, b and c are the coefficients of a quadratic equation and you want it to have real roots, the condition could be b^2-4ac>=0.
max_runsIntegerThe maximum number of times the system should regenerate the set of variables without finding a set which satisfies the condition before giving up. If the system exceeds this number in a compiled exam, the entire exam will fail, so try to avoid it!

Preamble

fieldtypedescription
jsFileStringThe JavaScript to add to the outputfiles
cssFileStringThe CSS to add to the outputfiles

QuestionNavigation

fieldtypedescription
can_regenerateBooleanWhether the student can regenerate the question Old name was allow_regenerate
show_title_pageBooleanWhether the title page should be shown. Old name was show_frontpage
confirm_when_leavingBooleanWhether the student will be asked to confirm when leaving the exam.

Extensions

fieldtypedescription
chemistryBoolean
download_text_fileBoolean
eukleidesBooleanThe Eukleides extension provides functions to embed diagrams created using the Eukleides language. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#eukleides
geogebraBooleanThe GeoGebra extension provides functions to embed GeoGebra worksheets in a question. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#geogebra
graphsBooleanThis extension provides some functions for working with and drawing graphs (networks of vertices joined by edges) in Numbas. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#graph-theory
jsx_graphBooleanThe JSXGraph extension provides functions to create and manipulate interactive diagrams with the JSXGraph library. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#eukleides
linear_algebraBoolean
linear_codesBooleanThis extension provides a new data type and some functions to deal with linear codes. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#linear-codes
optimisationBoolean
permutationsBoolean
polynomialsBooleanThis extension provides a new data type and some functions to deal with rational polynomials. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#polynomials
quantitiesBooleanThis extension wraps the js-quantities library to provide a “quantity with units” data type to Numbas. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#quantities
random_personBooleanThe “random person” extension provides a collection of functions to generate random people, for use in word problems. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#random-person
statsBooleanThe statistical functions extension provides many new functions for generating samples from random distributions, and calculating statistics. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#statistical-functions
sqliteBoolean
textBoolean
written_numberBoolean

ResourcePath

fieldtypedescription
resource_nameString
resource_pathFilesystem path

CustomPartTypeDefinition

fieldtypedescription
type_nameTranslation
descriptionTranslation
settingsArray of CustomPartTypeSetting
can_be_gapBoolean
can_be_stepBoolean
marking_notesArray of JMENote
help_urlTranslation
publishedBoolean
extensionsExtensions
input_widgetCustomPartInputWidget

Translation

One of the following items:

typedescription
TranslationStructA structured translatable string with placeholders.
FileStringA simple filestring. This implies that it can also just be a string.

TranslationStruct

fieldtypedescription
contentTranslationContentThe content with optional placeholders ({{placeholder-name}}).
placeholdersMap from String to TranslationThe values for the placeholders. It maps the placeholder-name to it's translatable value. The value for a placeholder can thus (if needed) be different for different locales.

TranslationContent

One of the following items:

typedescription
Map from String to FileStringMap from locale to content. You can use this to specify different content for different locales.
FileStringA filestring. Possibly to a file that is placed in locale folders and is therefore localized.

FileString

One of the following items:

typedescription
StringA string of the form file:<filepath> where filepath is the relative path (within the exams or questions folder) to a file containing content. This content can be localized by placing it in locale folders. e.g. file:examples/basic-explanation.html will search for files in folders with following form: questions/examples/locale-<localename>/basic-explanation.html If a file isn't found for a specific locale, questions/examples/basic-explanation.html will be used.
StringA literal string.

CustomPartTypeSetting

Internal tag named input_type.

One of the following items:

CustomPartTypeSettingCheckBox

fieldtypedescription
nameTranslationA 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.
numbas_labelTranslationThe label shown next to the setting in the numbas 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.
documentation_url"none" or TranslationThe address of documentation explaining this setting in further depth.
numbas_hintTranslationUse 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_valueBooleanThe initial value of the setting in the question editor.

CustomPartTypeSettingCode

fieldtypedescription
nameTranslationA 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.
numbas_labelTranslationThe label shown next to the setting in the numbas 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.
documentation_url"none" or TranslationThe address of documentation explaining this setting in further depth.
numbas_hintTranslationUse 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"none" or TranslationThe 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, set this to none.
evaluateBoolean

CustomPartTypeSettingMathematicalExpression

fieldtypedescription
nameTranslationA 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.
numbas_labelTranslationThe label shown next to the setting in the numbas 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.
documentation_url"none" or TranslationThe address of documentation explaining this setting in further depth.
numbas_hintTranslationUse 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.
evaluate_enclosed_expressionsBooleanIf this is ticked, then JME expressions enclosed in curly braces will be evaluated and the results substituted back into the string.
default_value"none" or TranslationThe 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, set this to none.

CustomPartTypeSettingString

fieldtypedescription
nameTranslationA 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.
numbas_labelTranslationThe label shown next to the setting in the numbas 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.
documentation_url"none" or TranslationThe address of documentation explaining this setting in further depth.
numbas_hintTranslationUse 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.
evaluate_enclosed_expressionsBooleanIf this 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.
default_value"none" or StringThe 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, set this to none.

CustomPartTypeSettingDropDown

fieldtypedescription
nameTranslationA 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.
numbas_labelTranslationThe label shown next to the setting in the numbas 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.
documentation_url"none" or TranslationThe address of documentation explaining this setting in further depth.
numbas_hintTranslationUse 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"none" or TranslationThe 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, set this to none.
choicesArray of CustomPartTypeSettingDropDownChoice

CustomPartTypeSettingDropDownChoice

fieldtypedescription
valueTranslation
labelTranslation

CustomPartTypeSettingPercentage

fieldtypedescription
nameTranslationA 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.
numbas_labelTranslationThe label shown next to the setting in the numbas 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.
documentation_url"none" or TranslationThe address of documentation explaining this setting in further depth.
numbas_hintTranslationUse 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"none" or FloatThe 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, set this to none.

JMENote

fieldtypedescription
nameStringThe name of the note
description"none" or StringA description of the note
expressionTranslationThe jme expression representing the note

Extensions

fieldtypedescription
chemistryBoolean
download_text_fileBoolean
eukleidesBooleanThe Eukleides extension provides functions to embed diagrams created using the Eukleides language. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#eukleides
geogebraBooleanThe GeoGebra extension provides functions to embed GeoGebra worksheets in a question. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#geogebra
graphsBooleanThis extension provides some functions for working with and drawing graphs (networks of vertices joined by edges) in Numbas. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#graph-theory
jsx_graphBooleanThe JSXGraph extension provides functions to create and manipulate interactive diagrams with the JSXGraph library. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#eukleides
linear_algebraBoolean
linear_codesBooleanThis extension provides a new data type and some functions to deal with linear codes. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#linear-codes
optimisationBoolean
permutationsBoolean
polynomialsBooleanThis extension provides a new data type and some functions to deal with rational polynomials. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#polynomials
quantitiesBooleanThis extension wraps the js-quantities library to provide a “quantity with units” data type to Numbas. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#quantities
random_personBooleanThe “random person” extension provides a collection of functions to generate random people, for use in word problems. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#random-person
statsBooleanThe statistical functions extension provides many new functions for generating samples from random distributions, and calculating statistics. https://numbas-editor.readthedocs.io/en/latest/extensions/first-party.html#statistical-functions
sqliteBoolean
textBoolean
written_numberBoolean

CustomPartInputWidget

Internal tag named type.

One of the following items:

tag-valuedatatype of valuedescription
stringCustomPartStringInputOptionsThe student enters a single line of text.
numberCustomPartNumberInputOptionsThe 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.
radiogroupCustomPartRadioGroupInputOptionsThe student chooses one from a list of choices by selecting a radio button.

CustomPartStringInputOptions

fieldtypedescription
hintCustomPartInputOptionValueTranslatableStringA string displayed next to the input field, giving any necessary information about how to enter their answer.
correct_answerTranslationA JME expression which evaluates to the expected answer to the part.
allow_emptyCustomPartInputOptionValueBoolIf false, the part will only be marked if their answer is non-empty.

CustomPartInputOptionValueTranslatableString

fieldtypedescription
valueTranslationThe value
staticBooleanA 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.

CustomPartInputOptionValueBool

fieldtypedescription
valueBooleanThe value
staticBooleanA 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.

CustomPartNumberInputOptions

fieldtypedescription
hintCustomPartInputOptionValueTranslatableStringA string displayed next to the input field, giving any necessary information about how to enter their answer.
correct_answerTranslationA JME expression which evaluates to the expected answer to the part.
allow_fractionsCustomPartInputOptionValueBoolAllow the student to enter their answer as a fraction?
allowed_notation_stylesCustomPartInputOptionValueAnswerStyles

CustomPartInputOptionValueAnswerStyles

fieldtypedescription
valueArray of AnswerStyleThe value
staticBooleanA 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.

AnswerStyle

One of the following items:

namedescription
"english"English style - commas separate thousands, dot for decimal point
"english-plain"Plain English style - no thousands separator, dot for decimal point
"english-si"English SI style - spaces separate thousands, dot for decimal point
"european"Continental European style - dots separate thousands, comma for decimal poin
"european-plain"Plain French style - no thousands separator, comma for decimal point
"french-si"French SI style - spaces separate thousands, comma for decimal point
"indian"Indian style - commas separate groups, dot for decimal point. The rightmost group is three digits, other groups are two digits.
"scientific"Significand-exponent ("scientific") style
"swiss"Swiss style - apostrophes separate thousands, dot for decimal point

CustomPartRadioGroupInputOptions

fieldtypedescription
hintCustomPartInputOptionValueTranslatableStringA string displayed next to the input field, giving any necessary information about how to enter their answer.
correct_answerTranslationA JME expression which evaluates to the expected answer to the part.
choicesCustomPartInputOptionValueTranslatableStringsThe labels for the choices to offer to the student.

CustomPartInputOptionValueTranslatableStrings

fieldtypedescription
valueArray of TranslationThe value
staticBooleanA 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.