Numbas is an opensource eassessment system aimed at mathematics and other numerate disciplines. It generates SCORM 2004compliant, selfcontained assessment packages.
Find out more about Numbas, including case studies and the latest blog posts, at numbas.org.uk.
A free to use Numbas editor is open to the public at numbas.mathcentre.ac.uk.
This documentation is a work in progress. If you have any questions, please email us or join the numbasusers mailing list.
Create an account¶
Click on the create an account button at the top right of the page.
After filling in your details and pressing Register, you will be sent an email with a link to verify your email address. When you’ve opened that link, you can log in: click on the Log in button at the top right of the page and enter the username and password you chose.
Getting Started¶
Once you have logged in you will be prompted to take a look at these tutorials. When you are ready to get started using the editor, click on the Home button to navigate to your home page.
On the left you will find your activity timeline. This will display notifications about activity on content that you have either created or have access to.
On the right you will find buttons to create a question or exam and to browse the public database.
At the bottom of the right column you will find a list of projects of which you are a member. You will already have a project of your own which will be the default home for your questions and exams.
Create an exam¶
Once you have created an account on the editor, you can create your own questions and exams, as well as look at and make copies of those made by others.
Let’s create an exam using questions already in the database.
Creating an exam using existing questions¶
On your home page, click on the Questions link under Browse the public database. You can use the options on the left to filter the results, or use the search box at the top of the page to search for content that you are interested in.
Once you have found a question that you are interested in, click on the Preview icon to try it out. If you are happy with the question, click on the basket icon to add it to your question basket.
Once you’ve collected a few questions, click on the basket icon at the top of the page, and then click Create an exam from these questions. You’ll be taken to the editing page for your new exam.
Enter a name in the text box. Below is a dropdown list of projects that the exam can be assigned to. By default it will be added to your personal project.
Once created, you can try out your exam straight away. Click the Test Run link in the sidebar on the left. The compiled exam will open in a new window and you can have a go at answering the questions.
Once you have tried out the exam, close its window and return to the exam editor. Consider adding some text to the description field. The description should be short – one or two lines – and will appear underneath the exam’s name in the exam listing page.
Adding more questions to your exam¶
On the editing page for your exam, click the Questions link in the sidebar to go to the question selection area. On the left is space for your selected questions, and on the right are tabs offering different ways of finding questions to add. The Recent questions tab shows questions you have recently edited. The Basket tab shows questions you’ve added to your basket: you can browse the question editor to find questions, add them to your basket, and then go back to the exam editing page and add them in.
You can click on any question’s name to open it in a new window, so you can check the question does what you want and give it a test run before including it in your exam.
Click the plus icon on one of the question results to add it to your exam.
You can drag and drop questions in the list on the left to reorder them.
The changes that you make to the exam content are active straight away, so you can see how your exam looks by clicking on Test Run again.
Publish your exam¶
Once you’re happy with your exam, why not publish it the public database, so others can use it? Before you can publish an exam, you must fill out its metadata fields so others can find it easily:
 Give the exam a name.
 Write a description.
 Select a licence under which others can use your exam. Make sure this doesn’t conflict with the licence attached to your exam’s questions.
 Your exam must contain at least one question.
Once you’ve filled out the required fields, click on the Access tab, and then click Publish. Your exam will now be included when anyone searches the public database.
Uploading an exam to the web¶
Numbas exams are, from the point of view of a web browser, just web pages with script files attached. So it’s very easy to put a fully functional Numbas test on the web  all you need is somewhere to put it.
Note
These instructions will show you how to get a version of your exam which runs on the web and doesn’t track scores. For instructions on obtaining and using a version which can be uploaded to a VLE such as Blackboard or Moodle, see Uploading an exam to a virtual learning environment.
Each question and exam has a download link in the sidebar which, when clicked, offers a selecton of options. Click on the standalone .zip (no SCORM) link to download a package suitable for standalone use on the web.
Extract the zip file on your computer, and then upload the resulting files to a new directory on your webspace. Most often you’ll be able to do this through an FTP client  ask your server administrator.
Once you’ve uploaded the exam files, you’re done! The exam will be available at the address you uploaded it to.
Uploading an exam to a virtual learning environment¶
Numbas produces SCORM objects which can be uploaded to any SCORM 2004compatible VLE (virtual learning environment).
This page contains instructions on uploading a Numbas exam to Blackboard and Moodle. The first step is to create a SCORM package of your exam.
Creating a SCORM package¶
Each question and exam has a download link in the sidebar which, when clicked, offers a selecton of options. If you just want to make an exam available on the web and don’t need to track scores, click the standalone .zip (no SCORM) link. For a version which can be uploaded to a VLE such as Blackboard or Moodle, click the SCORM package link.
In both cases, a .zip file containing everything needed to run the exam will be downloaded to your computer.
Uploading to Blackboard¶
Note
At least Blackboard 9.1 Service Pack 6 is required to run Numbas exams. There’s no way of checking your Blackboard version from within Blackboard, so check with your server admin that you’re using a sufficiently recent version.
Log in to Blackboard, and go to the content section of the relevant course. Click on the Content package (SCORM) item under the Build Content menu.
On the next screen, select the .zip file you downloaded earlier, then click Submit.
On the next screen you can set some options for your exam.
The default options are usually fine, but you should make sure that the settings under SCORM availability in particular are how you want them.
Click Submit, and your exam is ready to use!
Uploading to Moodle¶
Log in to Moodle, and go to the relevant course. Turn editing mode on, then click on the Add an activity... dropdown and select SCORM package.
Enter your exam’s name in the Name field, and write a description in the field beneath. Then click on the Choose a file... button in the Package file field and upload the .zip file you downloaded earlier.
Take a look at the rest of the settings on the page to make sure they’re set how you want. The default settings are usually fine, though you might like to set Hide navigation buttons to Yes to save screen space.
When you’re ready, click on Save and display. Your exam is ready to use!
Writing your first question¶
In this tutorial you will learn about the structure and features of a Numbas question by creating a simple arithmetic test, starting with basic functionality and elaborating on that as we cover the more advanced tools available.
We’ve embedded screencasts of someone running through this tutorial at the start of each section. You might like to follow along with the video while reading the tutorial.
To begin, let’s make a question asking the student to add two numbers.
Log in to the Numbas editor and, in the Create box, click on the Question link.
You will be prompted to give your question a name, and to assign it to a project. As this is your first question you will probably want to use the default project, which is your own workspace.
The structure of a question¶
You are taken to the editing page for your new question. It is worth spending a few moments finding your way around this page.
At the top of the page are the question’s name and, above that, a link to the project which it belongs to. Below are options to run, give feedback and download the question. Below this there are options to navigate through the various steps involved in editing a question.
In the Admin box there are links to copy or delete the question. And in the Metadata box you can manage how your question is organised in the Numbas database.
In the centre is the main editing interface. Before moving any further, let’s change your question name from “My First Question” to something more descriptive so that you can find it later. Type “Numbas tutorial: arithmetic” in the Name field.
Every Numbas question consists of three sections: Statement, Parts, and Advice. In the Statement, the context for the question is given to the student. Parts are where the student enters their answers. A question can have one or more parts, each of which is one of several types, depending on what kind of input you want from the student. Finally, the optional Advice section can be used to give a full solution to the question, which the student can request to see if they’re stuck.
Each of these sections of the editor can be accessed from the links in the sidebar, or you can use the buttons at the bottom of each section to guide you through in a logical order.
Let’s make a question with a short statement, one part asking for a number to be entered, and a little bit of advice.
A very basic arithmetic question¶
We’re going to ask the student to add together the numbers \(3\) and \(5\). If you are still on the Settings page, click on the Statement button at the bottom, or on the Statement link in the sidebar. Type
What is 3+5?
in the Question statement box.
Click on the Test Run button. Your question will open in a new browser window. There is a statement, but nowhere to enter an answer. We need to create a number entry part. Go back to the editing window and click on Parts in the sidebar, or follow the navigation buttons at the bottom of the page, skipping past Variables, which we will consider later.
Once on the Parts page, click on the Add a part button. The default part type is Information only; change it to Number entry by clicking on the dropdown box.
Every part has a Prompt, which you can use to ask the student for the particular answer the part assesses. We’ve already asked our question in the question’s statement, so we can leave this part’s prompt empty. Instead, click on the Marking link, where you’ll state the correct answer for the part.
Enter 1
in the Marks field, so the student is given one mark if their answer is marked correct.
Number entry parts are marked by checking if the student’s answer is within the range defined by the Minimum accepted value and Maximum accepted value fields.
For this question the answer is exactly \(8\), so put that in both fields.
Now press Test Run again to try out the question.
If you put 8
in the entry box and press Submit part, the answer is marked correct; any other number is marked incorrect.
To finish off this question, add a solution to the Advice section. There isn’t much to explain for this particular question, so just click on the Advice tab and enter
3+5 = 8
in the box.
Now click Test Run again; if you press the Reveal button at the top of the question page, the number input is filled in with the correct answer, and the advice text you wrote is displayed at the bottom.
You have created your first complete question!
Things to try before moving on:
 Enter a decimal number as the correct answer, and set the minimum and maximum accepted values to allow an error of plus or minus \(0.005\).
 Look at the documentation for the Number entry part and try out the precision restrictions.
Better maths display and randomised numbers¶
Now let’s add another part to the question, asking the student to multiply two numbers.
Add another Number entry part to your question. Now that we have two parts, it doesn’t make sense to ask for the answer to the first part in the question statement, so remove the text from the Statement and put it back in the first part’s Prompt.
Now, for the second part’s Prompt, enter:
What is 3*5?
And set the correct answer to 15
.
When you Test Run the question, you should be immediately offended by the unattractiveness of the rendering of the multiplication 3*5.
Mathematical notation is distinct from normal text and needs to be treated separately.
For this reason, Numbas uses LaTeX to mark up mathematical notation.
Note
While LaTeX is wonderfully expressive, it has quite a steep learning curve; if you’re not familiar with it, see LaTeX notation.
Replace the Prompt for the second part with
What is $3 \times 5$?
The dollar symbols delimit the LaTeX notation. Now when you Test Run the question again, you will see neatly typeset maths:
For consistency, go back and change the prompt for the first part to:
What is $3 + 5$?
The most important feature of computerbased assessment is the ability to dynamically generate questions which are different every time they are run. In Numbas this is achieved using variables.
Let’s change the question so that the two numbers to be added are picked at random.
Click on the Variables link. Click on the Add a variable button. Every variable needs a name and a definition. The definition is given in JME syntax.
Note
For information on what constitutes a valid variable name, see Variable names.
For more on JME syntax, see the JME reference.
Call this variable a
, and give it the definition:
random(1..9)
The variable will take a random wholenumber value between \(1\) and \(9\) (inclusive).
To the right of the variable’s name, a possible value for the variable is displayed. You can get a feel for what values a variable can take by pressing the Regenerate values button a few times.
Add a second variable called b
and give it the same definition.
The next step is to use these variables to define the prompts and acceptable values for both parts.
Change the prompt for the first part to
What is $\var{a} + \var{b}$?
\var{}
is a special LaTeX command which inserts the calculated value of the given expression directly into the LaTeX.
It doesn’t do anything to cancel out redundant terms or symbols  more on that later.
Now go to the Marking tab and change both accepted values to a+b
.
Click Test Run to see how your changes have affected the question. You can use the Try another question like this one button to regenerate the question without having to go back to the editor.
Now your question has nicely rendered maths and uses randomised numbers.
Things to try before moving on:
 Add two new variables
c
andd
, and change the second part to use them instead ofa
andb
.  Make sure that
a
andb
don’t both take the same value by using theexcept
operator in the definition ofb
.  Add a solution for the second part to the Advice section.
More complicated mathematical expressions¶
Until now, you’ve only written very simple mathematical expressions, where the randomised variables could be substituted in without any changes to the surrounding symbols.
Often, this isn’t the case; for such occasions, there is the \simplify
command.
\simplify
is a special LaTeX command which takes an expression in JME syntax, like \var
does, but rather than evaluating it to a number, tidies it up using a set of simplification rules.
Let’s add another part to the question, using \simplify
to present a quadratic equation with random coefficients, and ask the student to factorise it.
Add a new part and set its type to Mathematical expression.
This part will be constructed in reverse  we’ll generate the roots of the equation randomly, and use those to calculate the coefficients of the quadratic shown to the student. This way, the question is guaranteed to have a nice answer.
Add two new variables x0
and x1
:
x0 = random(9..9)
x1 = random(9..9 except x0)
The except
operator in the definition of x1
ensures that it doesn’t take the same value as x0
, so the quadratic doesn’t have repeated roots.
Note
It’s a good idea to add comments to your variable definitions to explain what they represent and how they’re generated.
A comment starts with two forward slashes //
and continues until the end of the line.
Now the Prompt for the part might go something like this:
Factorise $x^2 + \var{x0+x1}x + \var{x0*x1}$.
But that can produce unnatural expressions, like these:
In the first, only a subtraction sign should be shown; in the second the x term should be omitted.
Rewrite the prompt using the \simplify
command:
Factorise $\simplify{ x^2 + {x0+x1}*x + {x0*x1} }$
The command takes an expression in JME syntax. The expressions between curly braces are evaluated to numbers using the defined variables, and then the whole expression is rearranged to produce something that looks more natural.
Note
For more on what exactly the \simplify
command does, see Simplification rules.
Click on the part’s Marking tab and set the Correct answer to:
(x+{x0})(x+{x1})
(Again, expressions in curly braces are evaluated as numbers when the question is run.)
Numbas marks Mathematical expression parts by choosing a random sample of points on which to evaluate them, and comparing the result given by the student’s answer with that given by the Correct answer. Because it doesn’t pay any attention to the form of the student’s answer, it has no way of distinguishing between the factorised and expanded forms of our quadratic  the student could just enter the same expression they’re given and it would be marked correct.
To prevent this, you can specify some string restrictions to constrain the student’s answer. It isn’t a perfect method, but it’s usually good enough.
Go to the part’s Accuracy and string restrictions tab and enter (
and )
in the Required strings field, and ^
in the Forbidden strings field.
Click Test Run and check that your question is marked correctly.
That’s it for this tutorial. You’ve created a very simple Numbas question asking the student to enter some numbers and a mathematical expression, with randomised parameters and neatly rendered maths. If you got lost along the way, you can compare what you’ve got with this question we prepared earlier.
Collaborating using Numbas¶
Numbas has several features to make collaborating with colleagues easier.
Note
# New bits
Project¶
Don’t collaborate in your own workspace  create a separate project instead.
Projects grant automatic editing access to their members.
Timeline¶
Use the project timeline, and the editing history tab on individual items, to keep track of changes you and your colleagues make. Write comments to discuss changes or problems.
Restore points¶
Set a restore point to save a snapshot of your question when you make a change.
Write an informative description of the current state of the question, and what you’ve changed since the last restore point.
Give feedback¶
Use the feedback stamps to tell your colleagues which of your questions are ready to use, and which need more attention.
Check over your colleagues’ work and use feedback stamps to alert them to problems.
When you compile an exam, every question in it should be labelled “Ready to use”.
Pull requests¶
If you see a problem in someone else’s question but don’t have editing access, make a copy and fix it, but don’t just leave the original to languish  create a pull request so your changes can be merged back into the original.
Note
# end of new bits
Give editing access to collaborators¶
Use the Access tab to give editing or viewing access for your questions and exams to your colleagues.
Use the editing history tab¶
Each time you make a change to a question, write a description of what you’ve done in the Editing history tab. This is useful when you’re editing your own questions, but doubly so when editing other people’s  they can quickly see what’s different, and decide if they’re happy with the changes.
You can write comments on the editing history. Use this to suggest changes, report bugs, and so on.
Give feedback on quality¶
Use the Feedback button on questions and exams to let other users know whether they’re ready for use or not.
It’s a good idea to have someone else test a question once it’s complete; they should proofread the text and then attempt the question, giving both correct and incorrect answers to check that the marking works as intended.
If a colleague makes a copy of a question and you decide to use that instead, mark the original version as “Should not be used” to avoid confusion later on.
Add descriptions to variables and use sensible names¶
Short variable names are quick to type, but not easy to understand. Try to avoid singleletter variable names as much as possible, and prefer longer names over shorter ones. For example, it isn’t immediately obvious what sm
represents, while sample_mean
is very clear.
In addition, make sure to write a description of each variable in the box under its definition. You should explain what the variable represents, and also describe any important points about how the variable is generated, or what values it can take.
Tag questions¶
Use tags to categorise your questions. Agree with your colleagues how to tag questions  if everyone makes up their own tags, they’re no use at all!
Here are some tagging schemes you might want to use:
 By topic  tag a question with the part of the curriculum it covers, separately from the name of the particular course you’re making it for, so colleagues teaching other courses can find it.
 By level  use a tag to tell other authors which age range or ability level your question is suitable for.
How do I...¶
... include an image?¶
It’s best practice to attach images to questions so that they’re distributed with the final compiled exam, rather than linking to images stored on a webserver.
When editing a content area, click on the Insert/Edit Image button. You can then either pick an image you’ve already uploaded, or click the Choose file button to upload an image from your computer.
You can resize images and add a title attribute by selecting the image in the content area and clicking on the Insert/Edit Image button.
... embed a video?¶
Upload your video to somewhere like YouTube or Vimeo. Including videos in downloaded exam packages is a terrible idea, so we discourage that. Click the Embed image/video button (it’s a blue cloud), and paste in the URL of your video.
... include an interactive diagram?¶
There are a couple of ways of including an interactive diagram in a Numbas question. You can either embed a GeoGebra applet, or use JSXGraph.
For JSXGraph diagrams, there is an extension which takes care of most of the setup. You will need to write a fair amount of JavaScript code to create a diagram using JSXGraph.
GeoGebra applets are much easier to create and use, but are loaded from geogebra.org so the student must have internet access in order to use any questions containing GeoGebra applets.
The screencast below explains how to use a GeoGebra applet in a question. For more information, see the page on the geogebra extension.
... change how the question looks?¶
You can use the formatting tools in the question editor to style your text. However, if you repeat the same styles over and over, or want to change aspects of the layout such as space between elements or decoration, you’ll need to write some CSS.
CSS is a language for defining how things should look  there’s a good introduction at Khan Academy. In the Numbas editor, you can add CSS rules to a question in the Preamble section.
The following questions demonstrate how to use CSS to change the look of a Numbas question:
 Style a table of sales figures 
 Use CSS to style parallel translation  CSS classes “english” and “cymraeg” apply different background colours to English and Welsh portions of text.
 CSS Lemma environment  defines a CSS class in the preamble which styles the “Lemma” environment, used in the statement.
 More space between multiple choice answers
... show one of several images based on a random variables?¶
See the question Using a randomly chosen image for an example of one method.
... show one of several blocks of text based on a random variable?¶
Suppose you have a random variable a
, which has the value 1,2 or 3, corresponding to three different scenarios.
First, write out the text for each scenario.
There is a button in the content editor labelled Conditional visibility.
This allows you to give an expression (in JME syntax) which dictates whether or not the selected text is shown.
For each scenario, select the corresponding text and click on the Conditional visibility button.
Enter a=1
for the first block, a=2
for the second, and a=3
for the third.
When you run the question, only the block of text corresponding to the value of a
is shown.
You can see an example of this technique in the question Conditional visibility.
... make sure my generated variables satisfy a condition?¶
Use the variable testing tools.
... display a dollar sign?¶
Because the dollar symbol is used to delimit portions of LaTeX maths, you need to escape dollar signs intended for display by placing a backslash before them – that is, write \$
.
See this example question.
... include a randomised LaTeX command?¶
If you want to include a LaTeX command in a string variable, remember that backslashes and curly braces in strings must be escaped.
That means you should type two backslashes where you’d normally type one, and add a backslash before each left or right curly brace, for example \\frac\{1\}\{2\}
produces the LaTeX \frac{1}{2}
.
You need to do this because the backslash is used as an escape character in strings so you can include quote marks, which would normally end the string.
(For example, "he said \"hello\" to me"
)
If you substitute a string variable into a mathematical expression using \var
, it’s normally assumed to represent plain text and displayed using the plain text font.
If your string is really a partial LaTeX expression, you must mark it as such by wrapping it in latex()
, e.g. \var{latex(mystring)}
.
Projects¶
Projects provide a way of collecting together all your work on a particular topic or course, and automatically granting access to your collaborators.
In the Numbas editor, every exam or question must belong to a single project. Your account always has one project attached to it  your workspace. When you create a new exam or question, you’ll be asked which project you want to attach it to, and the default option is your workspace.
If you’re putting together content for a course you’re teaching, it’s a good idea to create a new project as a single gathering point for your material. A project is effectively a “fenced off” area of the editor where you can concentrate on just the material you want to work on, without having to wade through unrelated items.
Creating a new project¶
Click on the New button at the top of the page, and then on Project. You need to give some information about your new project:
 A name for the project. This should succinctly describe what the project is for, or what it contains.
 A longer description of the project. You could include a link to your course homepage, or some information about the aims of the project.
 A default language for content created in this project. Any new exams created in this project will use this language by default.
 A default licence for content created in this project. Any new exams created in this project will have this licence attached by default.
The project home page¶
A project’s home page shows a timeline of activity on the project, the list of members, and links to create new content or browse the project’s existing content.
The timeline shows all activity on exams or questions belonging to the question, as well as comments attached to the project itself. Timeline items belonging to each project you’re a member of will also be shown in your personal timeline on the editor homepage.
The cog icon at the top of the page takes you to the project’s options page. On this page you can change any of the project’s settings or, if the project isn’t your personal workspace, delete it.
Finding content inside a project¶
From the project homepage, click on either of the Browse links to see the questions or exams belonging to the project. You can narrow down your search by adding a query in the search bar at the top of the page, or selecting one of the filters.
Adding someone to a project¶
From the project’s homepage, click on the settings icon at the top of the list of members to go to the member settings page. In the Add a member box, type the name of the person you want to invite. If they don’t have an account yet, their email address; they’ll get an email asking them to create an account and when they do, they’ll be given access to your project immediately.
You can control what project members are allowed to do: if you select Can view then the user will be able to look at, comment on, and download all content in the project, but not change anything. If you select Can edit, then they will also be able to create new content or change existing content. You can also give project members access to individual exams or questions using the access controls on their respective edit pages.
Changing or removing a project member’s access¶
From the project’s homepage, click on the settings icon at the top of the list of members to go to the member settings page.
Change a project member’s access rights by selecting an option from the dropdown next to their name.
To remove a user from the project, tick the checkbox corresponding to their name, then click the Save changes button.
Transferring ownership of a project to someone else¶
The owner of a project has certain privileges which no other user does, such as deleting the project.
To transfer ownership of a project to somebody else, go to the Members settings page and click on the Transfer ownership button, then enter the name of the person you’d like to transfer ownership to. That user will become the owner of the project, and you will be given editing access to the project.
Deleting a project¶
To delete a project, you must be its owner. You can’t delete your personal workspace.
Warning
Only delete a project if you’re absolutely sure you don’t need it any more. Deleting a project is an irreversible action that will result in the loss of data belonging to the project.
To delete a project, go to the project’s Options page and click on the Delete this project button.
Questions and exams belonging to the project will be reassigned to their authors’ personal workspaces, but any comments on the project’s activity timeline will be deleted.
Exams¶
An exam is a collection of questions which you will give to your students. Within an exam you can set a pass mark, as well as configure how much feedback students can receive and how they can navigate between questions.
For a quick introduction to the workflow involved in putting an exam together, see the tutorial on creating an exam.
Creating an exam¶
To create an exam from any page in the Numbas editor, click on the plus icon at the top of the page, and select Exam.
You must give a name for your exam, and select a project for it to go in. The default project is your personal workspace; you can always move the exam to another of your projects later on.
The exam editor¶
At the top of the exam editor is the exam’s name, as well as any feedback stamp which has been attached. On the left of the screen are Admin controls and labels for each of the editing tabs.
Admin controls¶
 Test Run
Opens a preview of the exam in a new window.
Warning
Do NOT use this link to deliver the exam to students. This link is not permanent and could stop working at any time. Instead, download the exam and put it either on your own webspace or in a VLE.
 Feedback
Use this button to give feedback about the quality of an exam, after test running it. The options are listed in descending order of “suitability for use”:
 Ready to use  this exam is of sufficient quality to give to students.
 Should not be used  this exam works, but you deprecate its use  for example, if it’s not intended for use by students, or there’s a better version elsewhere.
 Has some problems  this exam works, but has some problems which mean it’s not ready for use by students  for example, the exam is incomplete, or changes need to be made to the text. Further work is needed before this exam can be given to students.
 Doesn’t work  this exam doesn’t even run!
 Needs to be tested  this exam looks alright to me, but it should be checked thoroughly before being used.
 Download
Links to download standalone packages of the exam.
 SCORM package  a compiled package of the exam with SCORM files included, so it can be uploaded to a VLE and communicate with its gradebook.
 standalone .zip  a compiled package of the exam, ready to run anywhere without connecting to a VLE.
 source  a plaintext representation of the exam, to be used with the Numbas commandline tools or as a backup.
Settings¶
The settings tab is where you set up metadata describing the exam.
Try to make sure not to ignore the settings tab, even if you just want to get a working exam as quickly as possible  a good name and description will make it much easier to find your exam again in the future!
 Name
 This is shown to the student and used for searching within the editor, so make it something intelligible. “Linear algebra diagnostic test” is a good name; “L.A. t1 v1” is not.
 Description
 Use this field to describe the exam’s contents, what it assesses, and so on. This is shown in the exams index, so make sure it’s fairly concise.
Use tags to categorise exams so they can be found through the search function. Your guiding principle should be “more is better”  try to write down all words that someone searching for this exam might use.
After typing a tag in the box, press the
Enter
key to add it to the list. Make a copy of this exam
 Create a copy of the exam. Use this to make changes to an exam which does not belong to you.
 Delete this exam
 Delete the exam permanently from the database. The associated questions are not deleted  you must delete them individually, if you want them to be deleted too.
Metadata¶
 Move to another project
 Click this button to move the exam to another project. You can move an exam to any project to which you have editing access.
 Licence
 You can specify the licence under which you are making your resources available. Different licences allow other users to copy, modify or reuse your content in different ways  consider which licence to choose carefully. CC BY allows other users to reuse your content however you like, as long as they give appropriate credit to you.
 Subjects and Topics
The Subjects and Topics fields provide a more structured way to categorise exams according to the subjects they assess. Database search results can be filtered by subject or topic.
Once you have selected one or more subjects, topics belonging to those subjects appear underneath.
The options for these fields are defined by the server administrator.
 Ability levels
Use this field to describe which ability levels the exam is appropriate for.
Several ability frameworks are available to choose from  pick the framework which most closely matches your own, and select one or more ability levels. An ability level is modelled as an interval in the range 0 to 1, so when you filter database search results by ability level, any items whose ability levels overlap the ones you selected are included in the results.
The options for these fields are defined by the server administrator.
Display¶
 Interface theme
 Themes control the user interface of an exam, changing the look and feel. The default theme is designed for exams which will be delivered over the web. There is also a worksheet theme which can be used to print out multiple, randomised copies of an exam for students to complete on paper.
 Interface language
 Specify which translation to use for the text in the user interface, i.e. button labels, error messages, etc.
Questions¶
Select the questions you want to include in your exam on this tab.
Questions are organised into groups. For each group, you can decide how many of the available questions to show to the student, and the order they should appear. You can use every question selected, or pick a random subset each time the exam is started.
 Show group names?
 If this is ticked, an input box will appear in each group where you can enter a name. The group names will be shown to the student in the navigation menu and in the score breakdown at the end of the exam.
 Questions to use
The strategy for picking questions to show to the student.
 All questions, in this order  all of the questions in the list below are shown to the student, in the order you’ve chosen.
 All questions, in random order  all of the questions in the list below are shown to the student, in a different order for each attempt.
 Pick a random subset  A subset of the questions in the list below are shown to the student. The questions chosen, and the order they appear, will differ for each attempt.
 Number of questions to choose
 If using the “Pick a random subset” strategy, this many questions from this group will be shown to the student.
 Pass threshold
 Define a pass/fail threshold for the student’s total score, as a percentage of the available marks. The pass/fail message will be displayed when the student ends the exam. If this is set to zero, then no message is displayed.
The tabs on the right hand side offer different ways of finding questions to add to the exam.
 The Basket tab shows questions you’ve added to your basket: you can browse the question editor to find questions, add them to your basket, and then go back to the exam editing page and add them in.
 The Recent questions tab shows questions you have recently edited.
You can check a question does what you want and give it a test run before including it in your exam: click on the question’s name to open its editing page in a new window.
Click the plus icon on one of the question results to add it to your exam.
You can drag and drop questions in the list on the left to reorder them, or move them between groups.
The Replace this question with a copy lets you quickly swap in a duplicate of a question you’ve included in your exam. If you’re using a question created by someone else, this is a convenient way of getting a version of the question you can make changes to.
Note
Removing a question from an exam does not remove it from the database. To permanently delete a question, click on its name to open its edit page, and click the Delete button there.
Timing¶
 Exam duration
 The length of time students are allowed to attempt the exam. If set to zero, then there is no time limit.
 Allow pausing?
 If ticked, the student can pause the exam while running it, and the timer will stop. If unticked, there is no pause button, and the end time is fixed when the session starts  leaving and resuming through the VLE will not affect the end time.
 On timeout (event)
 If set to Warn, the given message is displayed when the student runs out of time.
 5 minutes before timeout (event)
 If set to Warn, the given message is displayed five minutes before the student runs out of time.
Feedback¶
 Show current score?
 If ticked, the student will be shown their score for each question and part immediately after submitting their answers.
 Show maximum score?
 If ticked, the student will be shown the maximum attainable score for each question and part.
 Show answer state?
 If ticked, then when the student submits an answer an icon will be displayed to let the student know if their answer was marked correct, partially correct or incorrect.
 Allow reveal answer?
 If ticked, then the Reveal answer button is enabled on each question. If the student chooses to reveal the answer to a question, they are shown the correct answer but lose all their marks and can not reattempt the question.
 Advice threshold
 If the student’s score is below this threshold, then the question advice is displayed.
 Introduction
 This text is shown to the student on the front page, before the exam starts. You could use it to outline the rules of the exam, or just summarise the subjects covered.
 Feedback messages
You can write a list of messages, paired with threshold percentages, to show to the student at the end of the exam. The student’s score is calculated as a percentage, rounded to the nearest 1%, and compared with the thresholds for each message. The message with the largest threshold less than or equal to the student’s score is displayed.
You could use these messages to suggest topics for the student to revise, direct them to support resources, or detail the consequences of failing the test.
Events¶
Some of the properties described above are marked as events. These all have the same structure: an action setting which determines how to react to the event, and a message to display to the student when appropriate.
Access¶
You can control who is allowed to see, and to edit, your exams.
When you create a new exam, access is limited to you and any other members of the project the exam belongs to. You can grant extra access to indvidual users or publish your exam to the public database, where it can be viewed by any other user.
Public visibility
 Only you and users named in the Individual access rights section can see this exam.
 Anyone can see this
 Anyone, even users who are not logged in, can see this exam. Only you and users named in the Individual access rights section can edit this exam.
 Anyone can edit this
 Anyone, even users who are not logged in, can see and edit this exam.
Give access to a user
Type a name into the search box to find a user. Click on a user’s name in the results list to add them to the access list.
Named users can have the following rights:
 Can view this
 The named user can see, but not edit, this exam.
 Can edit this
 The named user can see this exam and make changes to it.
Access Links
The URLs in this section automatically grant access to whoever follows them. You could use these links to share a question with someone who hasn’t yet created an account on the editor (they’ll be prompted to create an account when they click on the link), or to share a question with a group of people without inviting each person individually.
Warning
These URLs grant access to whoever clicks on them, so be careful about how they’re shared.
Other versions¶
In this tab you can see all exams which are related to this one. Exams are related if one is a copy of the other, or they are both copies of a common ancestor. You can use this tab to compare the current exam with related versions, and offer to merge your version of the exam into another.
Click on the Compare link to go to a screen where you can offer to replace the other version with your version, or vice versa. If you have editing access to the destination exam, you can replace it with the other version automatically. If you don’t have editing access, the owner of the exam will be sent a Request to merge, which they must accept before the exams are merged.
Before creating the request, you’ll be asked to describe how your version differs from the one you want to replace. Try to sum up all your changes  this will show up in the exam’s editing history if your request is accepted.
Warning
If the exam you want to replace has changed since you made a copy of it, those changes will be lost if the request to merge is accepted  the exam is completely overwritten with the new version.
You can always restore an old version of an exam after a merge, by clicking on the appropriate restore link in the Editing history tab.
Active requests to merge other versions into the current exam are shown underneath the list of related versions. You can accept the request, in which case your version will be replaced with the other version, or reject it, in which case your version will be unchanged and the person who made the request will be notified that it was rejected.
Editing history¶
Use this tab to keep a record of changes made to your exam. Write comments to discuss problems or suggested changes.
Each time you make a change to an exam, it’s saved to the database. To save a snapshot of the current state of the exam, click the Set a checkpoint button. You’ll be asked to write a description of the exam as it stands  describe what you’ve changed since the last snapshot, and why you’re making a snapshot.
To restore a checkpoint, click its Restore button. The current state of the exam will be overwritten with the saved state.
Other activity on this exam will also be shown in this tab: for example, each time somebody uses the Feedback button to provide feedback on this exam, an entry is added to the editing history.
Questions¶
In Numbas, a question is a selfcontained assessment of a particular scenario. Every Numbas question consists of three sections: Statement, Parts, and Advice.
 In the Statement, the context for the question is given to the student.
 Parts are where the student enters their answers. A question can have one or more parts, each of which is one of several types, depending on what kind of input you want from the student.
 Finally, the optional Advice section can be used to give a full solution to the question, which the student can request to see if they’re stuck, or once they’ve finished the exam.
The content in each section is generated each time the question is run, based on the question’s variables.
Creating a question¶
To create a question from any page in the Numbas editor, click on the plus icon at the top of the page, and select Question.
You must give a name for your question, and select a project for it to go in. The default project is your personal workspace; you can always move the question to another of your projects later on.
The question editor¶
At the top of the question editor is the question’s name, as well as any feedback stamp which has been attached. On the left of the screen are Admin controls and labels for each of the editing tabs.
Admin controls¶
 Test Run
Opens a preview of the question in a new window. A specially simplified theme will be used, different from the one used for exams.
You can also use the keyboard shortcut
Ctrl+B
to open a preview.Warning
Do NOT use this link to deliver the question to students. This link is not permanent and could stop working at any time. Instead, download the question and put it either on your own webspace or in a VLE.
 Feedback
Use this button to give feedback about the quality of a question, after test running it. The options are listed in descending order of “suitability for use”:
 Ready to use  this question is of sufficient quality to give to students.
 Should not be used  this question works, but you deprecate its use  for example, if it’s not intended for use by students, or there’s a better version elsewhere.
 Has some problems  this question works, but has some problems which mean it’s not ready for use by students  for example, the question is incomplete, or changes need to be made to the text. Further work is needed before this question can be given to students.
 Doesn’t work  this question doesn’t even run!
 Needs to be tested  this question looks alright to me, but it should be checked thoroughly before being used.
 Download
Links to download standalone packages of the question.
 standalone .zip  a compiled package of the question, ready to run anywhere without connecting to a VLE.
 SCORM package  a compiled package of the question with SCORM files included, so it can be uploaded to a VLE and communicate with its gradebook.
 source  a plaintext representation of the question, to be used with the Numbas commandline tools.
 Add to your basket
 Add this question to your basket, so you can include it in an exam.
Content areas¶
Each portion of text displayed to the student (for example, the statement, advice, and part prompts) is a content area. A content area can include text, images, or more dynamic content such as videos and interactive diagrams.
By default, text is edited using the rich text editor. Click on the Toggle rich text editor button to edit the raw HTML code for the content area.
You can write mathematical notation in content areas using LaTeX; see the section on LaTeX notation.
Substituting variables into content areas¶
There are two modes of variable subsitution: substitution into plain text (or HTML), and substitution into mathematical expressions.
Substitution of variables into plain text is straightforward: just enclose the variable name (or any JME expression) in curly braces. For example:
Bob the farmer has {num_animals} {animal_name}.
produces:
Bob the farmer has 12 sheep.
when num_animals = 12
and animal_name = "sheep"
.
The substitution of variables into a mathematical expression is more complicated: depending on context, the surrounding expression may need to be change for different values of the substituted variables. Numbas provides a simple system to handle substitution of variables into mathematical expressions; see the section on Substituting variables into displayed maths.
Settings¶
 Name
 This is shown to the student and used for searching within the editor, so make it something intelligible. “Find the roots of a quadratic equation” is a good name; “Alg102 q2” is not.
 Licence
 You can specify the licence under which you are making your resources available. Different licences allow other users to copy, modify or reuse your content in differnet ways  consider which licence to choose carefully. CC BY allows other users to reuse your content however you like, as long as they give appropriate credit to you.
 Description
 Use this field to describe the question’s contents, what it assesses, and so on. This is shown in the questions index and in the questions list of any exams containing this question, so make sure it’s fairly concise.
Use tags to categorise questions so they can be found through the search function. Your guiding principle should be “more is better”  try to write down all words that someone searching for this question might use.
After typing a tag in the box, press the Enter key to add it to the list.
Statement¶
The 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.
Variables¶
The Generated value column shows a generated value for each variable. Note that when the question is delivered to students, the variable values are generated with each new attempt, so students won’t necessarily see the same values as those displayed here. It’s a good idea to use the Regenerate values button a few times to check that randomised variables don’t take unsuitable values.
You can reorder the variables in the list by dragging them. Doing this doesn’t affect the way values are computed.
This screencast gives a quick summary of how the variable editing interface works:
This screencast describes which variable names are valid, and gives some advice on how you should pick names:
Definition¶
 Name
 The name of the variable. See the section on variable names.
 Data type
Specify what type of data the variable should hold. The JME code option allows you to define the variable using JME syntax, while the other options provide simplified forms.
The JSON data option allows you to enter raw JSON data, which is parsed into JME data.
 Value
 Define the variable’s value. The format of this field depends on the data type.
 Description
Describe what the variable means, and how it is used. It’s also often helpful to explain how it’s defined, and what changes can be made to it.
Note
Don’t underestimate the value of the description field! Variables whose meaning seems clear when you write them have a habit of becoming indecipherable months later.
 Depends on
 A list of all variables used in this variable’s definition. You can click on a variable name to go to its definition. If the variable hasn’t been defined yet, it’ll be created.
 Used by
 A list of all variables which use this variable in their definition. You can click on a variable name to go to its definition.
Locking variable values¶
The preview values for each question variable are regenerated each time you click on the Regenerate variables button or, if the Automatically regenerate variables when changes are made option is ticked, whenever a variable definition is changed.
You can lock the value of a variable so that it doesn’t change when the other variables are regenerated. To do so, click on the padlock icon next to the variable’s name. Any variables used in the definition of the locked variable (those which appear in the Depends on list) will also be locked implicitly, so that you don’t end up with an inconsistent set of variables. You can unlock a variable by clicking on the padlock icon again.
Warning
Variables are only locked inside the editor’s preview area  when you test run the question, or include it in an exam, a fresh value for the variable will be generated.
Variable testing¶
This tab provides tools to test your variables for desired properties, so you can automatically rerandomise your questions’ variables until you get a suitable set of values.
Example question using variable testing tools.
Warning
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. Use the Test condition button to see how likely this is.
 Condition to satisfy
A 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^24*a*c>=0.
When the student runs this question, the system will regenerate the set of variables until it finds one which satisfies this condition.
 Test condition
When you press this button, the editor will generate as many sets of variables as possible within the time given. When it finishes, you’ll be presented with statistics including the proportion of runs which produced acceptable sets of values, and the expected number of runs before an acceptable set of values is found.
If the calculate probability of getting an acceptable set of variables within 1 second is lower than 99%, you should make changes to your variable definitions.
 Maximum number of runs
 The 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!
Parts¶
Each question has one or more parts. The student is given a separate score for each part of the question, and their total score is the sum of their scores for each part.
In the editor, parts are displated in a list; you can click on the title bar of a part to hide it, making room for the others. Use the Expand every part and Collapse every part buttons to show or hide every part at once.
Generic part properties¶
 Prompt
 A content area used to prompt the student for an answer.
 Marks
 The number of marks to award for answering the part correctly.
 Steps
 An optional list of subparts 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.
 Penalty for revealing steps
 If 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 \times \frac{4}{6} = 2\) marks after revealing steps.
 Show correct answer on reveal?
 When 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 score feedback icon?
 After 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. 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.
Part types¶
Information only¶
An 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.
Extension¶
An 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.
To use an extension part, your code must implement the following methods: (links go to the relevant pages in the Numbas JavaScript API documentation)
If you can create a JME value representing the student’s answer to the part, you should also implement studentAnswerAsJME so that it can be used in adaptive marking by later parts.
See the GeoGebra extension for an example of how to use the extension part.
Gapfill¶
Gapfill parts allow you to include answer inputs inline with the prompt text, instead of at the end of the part.
The “gaps” are subparts. Include them in text by clicking on the Insert gap button on the toolbar, and entering the number of the gap you want to insert in the dialog box. You can doubleclick on a gap placeholder to change its number.
To insert a gap in the plain text editor, type the gap’s number between two square brackets, e.g. [[0]] for the first gap.
Mathematical expression¶
Mathematical expression parts require the student to enter an algebraic expression, using JME syntax.
These parts are marked by picking a sample of points uniformly from a given range for the free variables in the expression, and evaluating both the student’s answer and the correct answer on those points. If the two expressions agree on enough inputs, then they are considered to be equivalent and the student’s answer is marked as correct.
For questions where the student is asked to rearrange an expression, clearly just evaluating both answers won’t detect the difference. For those cases, you can use a somewhat blunt method of string and length restrictions. We’re working on a more sophisticated method.
Before length 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.
Marking
 Correct answer
 The expected answer to the part. Question variables (or, more broadly, JME expressions which should be evaluated to a single value when the question is generated), can be included by enclosing them in curly braces.
 Show preview of student’s answer?
 If ticked, a rendering of the student’s answer in mathematical notation is displayed beeside the input box. You should leave this on unless you expect the answer to be veery simple and need the space  the feedback about how their answer is interpreted is very useful to students.
 Answer simplification rules
 Simplification 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.
Accuracy and string restrictions
 Checking type
The rule to use to compare the student’s answer with the correct answer. In the lines below, \(x\) represents the value of the student’s answer at a particular point and \(y\) represents the value of the correct answer, while \(\delta\) is the value of the checking accuracy property.
 Absolute difference. Fail if \(\left xy \right > \delta\).
 Relative difference. Fail if \(\left \frac{x}{y}  1 \right > \delta\).
 Decimal points. \(x\) and \(y\) are rounded to \(\delta\) decimal places, and the test fails if the rounded values are unequal.
 Significant figures. \(x\) and \(y\) are rounded to \(\delta\) significant figures, and the test fails if the rounded values are unequal.
 Checking accuracy
 The parameter for the checking type.
 Points to check
 The number of comparisons to make between the student’s answer and the correct answer.
 Maximum no. of failures
 If the comparison fails this many times or more, the student’s answer is marked as wrong.
 Checking range start
 The minimum value sample points can take.
 Checking range end
 The maximum value sample points can take.
 Maximum length restriction
 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 as1 + x
(five characters).  Minimum length restriction
 If the student’s answer contains fewer than this many characters, the penalty is applied. A value of zero means no restriction is applied. See the comment above on how the length is calculated.
 Required strings
 If the student’s answer doesn’t contain all of these strings, the penalty is applied.
 Forbidden strings
 If the student’s answer contains any of these strings, the penalty is applied.
 Warn if student uses an unexpected variable name?
 If this is ticked, all variable names used in the student’s are checked against the list you provide. The first variable name which is not in the list 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 meanx*y
, the product of two variables.  Expected variable names
 Variable names in this list will not prompt the “unexpected variable name” warning when the student uses them.
Number entry¶
Number entry parts ask the student to enter a number, which is marked if it is in a specified range.
Marking
 Minimum accepted value
 The smallest value accepted as correct.
 Maximum accepted value
 The largest value accepted as correct.
 Must the answer be an integer?
 If this is ticked and the student’s answer is not a whole number, the penalty is applied.
 Precision restriction
 You can insist that the student gives their answer to a particular number of decimal places or significant figures. For example, if you want the answer to be given to 3 decimal places, \(3.1\) will fail this restriction, while \(3.100\) will pass. If the precision doesn’t matter, select None.
 Allow the student to enter a fraction?
 This option is only available when no precision restriction is applied, since they apply to decimal numbers. If this is ticked, the student can enter a ratio of two whole numbers, e.g.
3/8
, as their answer.  Require trailing zeroes?
 This option only applies when a precision restriction is selected. If this is ticked, the student must add zeroes to the end of their answer (when appropriate) to make it represent the correct precision. For example, consider a part whose correct answer is \(1.4\), and you want the student’s answer to be correct to three decimal places. If “Require trailing zeroes?” is ticked, only the answer \(1.400\) will be marked correct. If it is not ticked, any of \(1.4\), \(1.40\) or \(1.400\) will be marked as correct. If too many zeroes are used, e.g. \(1.4000\), the answer is marked as incorrect.
 Show precision restriction hint?
 If this is ticked, then some text describing the rounding the student must perform is shown next to the input box. For example, “round your answer to 3 decimal places”.
 Display the correct answer as a fraction?
 This option is only available when no precision restriction is applied. If 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 of0.5
.  Allowed notation
 The 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. See Number notation for more on styles of notation.  Correct answer style
 The style of number notation to use when displaying the student’s answer.
Matrix entry¶
Matrix 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.
Marking
 Correct answer
 The expected answer to the part. This is a JME expression which must evaluate to a
matrix
.  Display numbers in the correct answer as fractions?
 If this is ticked, then noninteger numbers in the correct answer will be displayed as fractions instead of decimals.
 Number of rows
 The default number of rows in the student’s answer field.
 Number of columns
 The default number of columns in the student’s answer field.
 Allow student to change size of matrix?
 If this is ticked, then the student can change the number of rows or columns in their answer. USe this if you don’t want to give a hint about the dimensions of the answer.
 Margin of error allowed in each cell
 If 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.
 Gain marks for each correct cell?
 If this is ticked, 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.
 Precision restriction
 You can insist that the student gives their answer to a particular number of decimal places or significant figures. For example, if you want the answer to be given to 3 decimal places, \(3.1\) will fail this restriction, while \(3.100\) will pass. If the precision doesn’t matter, select None.
 Require trailing zeroes?
 This option only applies when a precision restriction is selected. If this is ticked, the student must add zeroes to the end of their answer (when appropriate) to make it represent the correct precision. For example, consider a part whose correct answer is \(1.4\), and you want the student’s answer to be correct to three decimal places. If “Require trailing zeroes?” is ticked, only the answer \(1.400\) will be marked correct. If it is not ticked, any of \(1.4\), \(1.40\) or \(1.400\) will be marked as correct. If too many zeroes are used, e.g. \(1.4000\), the answer is marked as incorrect.
 Allow the student to enter fractions?
 This option is only available when no precision restriction is applied, since they apply to decimal numbers. If this is ticked, the student can enter a ratio of two whole numbers, e.g.
3/8
, as their answer.
Match text pattern¶
Use a text pattern part when you want the student to enter short, nonmathematical text.
Marking
 Match test
The test to use to decide if the student’s answer is correct.
 The Regular expression test checks that the student’s answer matches the regular expression given in Answer pattern.
 The Exact match test 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.
 Answer pattern
The text or pattern the student must match.
When Match test is Regular expression, this is a regular expression defining the strings to be accepted as correct. If there are several valid answers, separate them with a

character. If you’re using the full regular expression functionality, note that^
and$
are automatically added to the start and end of the answer pattern to ensure that the student’s whole answer matches the pattern.You can substitute variables, the same as in content areas, by enclosing expressions in curly braces, e.g.
{answervar}
. Display answer
 A representative correct answer string to display to the student, in case they press the Reveal answers button. You can substitute variables by enclosing expressions in curly braces, the same as in content areas.
 Must the answer be in the correct case?
 If this is ticked, the capitalisation of the student’s answer must match that of the answer pattern. If it doesn’t, partial credit (defined using the slider below the checkbox) will be awarded.
Examples¶
In the following examples, the variable name
has the value Epictetus
Regular expressions¶
Correct answer  Must be correct case?  Student answer  Correct? 
Hello 
✓  Hello 
✓ 
Hello 
✓  hello 
✗ 
Hello 
✗  hello 
✓ 
HelloHi 
✓  Hi 
✓ 
(ab)+ 
✓  ababab 
✓ 
[^d]+ 
✓  abcefgh 
✓ 
[^d]+ 
✓  abcdefgh 
✗ 
{name} 
✓  Epictetus 
✓ 
{name}( {name})+ 
✓  Epictetus Epictetus 
✓ 
Exact match¶
Answer pattern  Must be correct case?  Student answer  Correct? 
Hello 
✓  Hello 
✓ 
Hello 
✓  hello 
✗ 
HelloHi 
✓  Hi 
✗ 
HelloHi 
✓  HelloHi 
✓ 
{name} 
✓  Epictetus 
✓ 
{name} 
✓  epictetus 
✗ 
{name} 
✗  epictetus 
✓ 
{name} Jr. 
✓  Epictetus Jr. 
✓ 
Choose one from a list / Choose several from a list / Match choices with answers¶
 Choose one from a list
 The student must choose one of several options
 Choose several from a list
 The student can choose any of a list of options
 Match choices with answers
 The 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 choiceanswer pairs.
Marking
 Minimum marks
 If the student would have scored less than this many marks, they are instead awarded this many. Useful in combination with negative marking.
 Maximum marks
 If the student would have scored more than this many marks, they are instead awarded this many. The value 0 means “no maximum mark”.
 Minimum answers
 For choose several from a list and match choices with answers parts, the 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.
 Maximum answers
 For choose several from a list and match choices with answers parts, the student must select at most this many choices. The value 0 means “no maximum”.
 What to do if wrong number of answers selected
 If the student selects too few or too many answers, either do nothing, show them a warning but allow them to submit, or prevent submission until they pick an acceptable number of answers.
 Shuffle order of choices?
 If this is ticked, the choices are displayed in random order.
 Shuffle order of answers? (Match choices with answers only)
 If this is ticked, the answersare displayed in random order.
 Number of display columns
 For choose one from a list and choose several from a list parts, this 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.
 Selection type
 Only applies to match choices with answers parts. “One from each row” means that the student can only select one answer from each row. “Checkboxes” means that the student can select any number of choiceanswer pairs.
 Custom marking matrix
 If the checkbox is ticked, the JME expression in the box below is evaluated and used to assign numbers of marks to choices.
 Custom matrix expression
 Define the number of marks to award for each of the choices. For choose one from a list and choose several from a list parts, the expression should evaluate to a list of numbers, while for match choices with answers it should evaluate to a list of lists of numbers representing a 2d array, or a matrix object, giving the number of marks to associate with each choiceanswer pair.
 Layout (Match choices with answers only)
 Define which choices are available to be picked. If Custom expression is selected, give either a list of lists of boolean values, or a matrix with as many rows as the part has choices and as many columns as the part has answers. Any nonzero value in the matrix indicates that the corresponding choiceanswer pair should be available to the student.
Choices
 Variable list of choices?
 Should the list of choices be defined by a JME expression? If this is ticked, you must give a custom matrix expression.
 List of choices
 If Variable list of choices? is ticked, this JME expression defines the list of choice strings to display to the student.
 Marks (choose one from a list / choose several from a list only)
 The number of marks to award (or take away, if you enter a negative number) when the student picks this choice.
 Distractor message (choose one from a list / choose several from a list only)
 A message to display to the student in the part’s feedback section after they select a particular choice. It can be useful to give some explanation of why a choice is incorrect.
Answers (Match choices with answers only)
 Variable list of answers?
 Should the list of answers be defined by a JME expression? If this is ticked, you must give a custom matrix expression.
 List of answers
 If Variable list of answers? is ticked, this JME expression defines the list of answer strings to display to the student.
Marking matrix (Match choices with answers only)
Assign marks to each pair of choice and answer using the input boxes.
 Custom marking matrix
 If the checkbox is ticked, the JME expression in the box below is evaluated and used to assign numbers of marks to choices.
 Custom matrix expression
 Define the number of marks to award for each of the choices. Either a list of lists representing a 2d array, or a matrix object, giving the number of marks to associate with each choiceanswer pair.
Scripts¶
The script fields allow you to override the builtin algorithms used by Numbas. They take JavaScript code; the Numbas JavaScript API documentation for parts is a useful reference.
Scripts have access to the global Numbas
object, as well as the following variables:

part
¶ The current part

question
¶ The part’s parent question

variables
The question’s variables, unwrapped to JavaScript objects (so numbers can be used as JavaScript numbers, instead of having to go through the JME system)
The following scripts can be customised:
 When the part is created
 This function runs when the part is created (either at the start of the exam, or when the question is regenerated), after the builtin constructor for the part. You could use this to change any of the part’s settings, if it’s not convenient to do so by other means.
 Mark student’s answer
 This function runs when the student clicks the Submit part button.
It should establish what proportion of the available credit to award to the student for their answer, and give feedback messages.
Use
this.setCredit(credit,message)
to set the credit and (optionally) give a message. Note thatthis.answered
should be set to true if the student’s answer can be marked  otherwise, the student will be shown a warning message.  Validate student’s answer
 This functions runs after the marking function, and should return
true
if the student’s answer is in a form that can be marked, orfalse
otherwise. If the answer can’t be marked, you should usethis.giveWarning(message)
to tell the student what’s wrong.
There are several example questions using custom scripts at numbas.mathcentre.ac.uk/exam/1016/custommarking/.
Adaptive marking¶
Adaptive 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 freeform 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.
As an example, suppose part a of your question asks the student to calculate the mean of a set of numbers.
The correct answer for this part is the variable sample_mean
.
Part b then asks the student to calculate a zstatistic based on the mean of the sample.
The correct answer to this part is the variable z_statistic
, which is defined as (sample_meanpopulation_mean)/sqrt(population_variance)
.
(population_mean
and population_variance
in this case are random numbers)
If the student makes an error in calculating the sample mean but uses the right method to find a zstatistic, they shouldn’t be penalised in part b.
We can ensure this by replacing the value of sample_mean
with the student’s answer to part a when marking part b.
When the student submits an answer to part b, the value of z_statistic
will be automatically recalculated using the student’s value of sample_mean
.
Then, if the student correctly applies the formula, their answer will match the new value of z_statistic
and they will receive full credit for the part.
Warning
This feature can be very powerful, but make sure you don’t introduce any new random variation in these dependent variables, or the correct answer will change each time the student submits their answer.
The editor will try to catch these cases and show you a warning, with a list of the problematic variables. Resolve this by moving the random elements to new variables.
For example, in the following set of variables, b
depends on a
and also has a random element:
a = random(1..5)
b = a*random(1,1)
In a part where a
is replaced with the answer to a previous part, b
will be regenerated with the new value of a
.
However, each time this happens, it will be multiplied by a random value.
To fix this, create a new variable b_sign
:
a = random(1..6)
b_sign = random(1,1)
b = a*b_sign
With this setup, b
is always multiplied by the same value because b_sign
does not depend on the replaced variable a
, so it is not regenerated when the part is submitted.
Variable replacements
 Variable
 The name of the variable to replace
 Answer to use
 The part whose answer the variable’s value should be replaced with. Different part types produce different types of values.
 Must be answered?
 If this is ticked, the student must submit an answer to the referenced part before they can submit an answer to this part.
There are two variable replacement strategies:
 Try without replacements 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 variables
 The student’s answer is only marked once, with the defined variable replacements applied.
Values obtained from the answers to each part types
Part type  Value obtained 

Gapfill  A list containing the values obtained from each of the gaps 
Mathematical expression  A JME subexpression. When used in a variable definition, the subexpression will be substituted in, and any references to question variables in the subexpression will be replaced with their respective values. 
Number entry  A number 
Matrix entry  A matrix 
Match text pattern  A string 
Choose one from a list  The index of the answer the student chose 
Choose several from a list  A list of booleans: true if the student ticked the corresponding choice, false otherwise 
Match choices with answers  A 2D list of lists of boolean values, in the same format as a custom marking matrix for this part  cells are addressed by choice first, and answer second. 
The following screencast shows the addition of adaptive marking to a question:
Advice¶
Advice 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.
Access¶
You can control who is allowed to see, and to edit, your questions.
When you create a new question, access is limited to you and any other members of the project the question belongs to. You can grant extra access to indvidual users or publish your question to the public database, where it can be viewed by any other user.
Public visibility
 Only you and users named in the Individual access rights section can see this question.
 Anyone can see this
 Anyone, even users who are not logged in, can see this question. Only you and users named in the Individual access rights section can edit this question.
 Anyone can edit this
 Anyone, even users who are not logged in, can see and edit this question.
Give access to a user
Type a name into the search box to find a user. Click on a user’s name in the results list to add them to the access list.
Named users can have the following rights:
 Can view this
 The named user can see, but not edit, this question.
 Can edit this
 The named user can see this question and make changes to it.
Access Links
The URLs in this section automatically grant access to whoever follows them. You could use these links to share a question with someone who hasn’t yet created an account on the editor, or to share a question with a group of people without inviting each person individually.
Warning
These URLs grant access to whoever clicks on them, so be careful about how they’re shared.
Extensions & scripts¶
This tab contains tools to change the behaviour of your question, using prebuilt extensions or by adding custom JME functions and JavaScript.
Extensions¶
Extensions can provide new functionality, such as extra JME functions or content types. To use an extension in your question, tick its checkbox here. All functionality provided by the extension will become available immediately. See the section on Extensions.
Functions¶
If you need to do something a bit more complicated with variables, or you find yourself repeating the same pattern over and over, you can define a custom function. Custom functions can be used in any JME expression in the question, such as variable definitions or part answers.
 Name
 The name of the function. Should be a valid JME name  it should start with a letter, and contain only letters and numbers, with no spaces or punctuation.
 Language
Functions can be defined either with a JME expression or with JavaScript code. In the case of a JME expression, the value returned is the result of evaluating the expression on the function’s parameters. You can also refer to the question’s variables.
JavaScript functions should return their result with a
return
expression. You don’t need to write thefunction(parameters) {}
part  just write the function body. Output type
 The type of the value returned by the function.
 Parameters
 The parameters given to the function. You can refer to them by name in the function’s definition. Make sure you correctly set the types of the parameters. You can define several functions with the same name but different parameter types, if it makes sense to do so.
JME functions¶
Functions defined using JME work similarly to variables  the function’s parameters are substituted into the expression, which is then evaluated.
Comments can be added to function definitions in the same way as variable definitions  anything on a line after two forward slashes is interpreted as a comment and not evaluated. For example:
map(
log(n), //take log of n
n, //for n in
1..10 //the range 1 to 10 (inclusive)
)
JME does not allow for much control over program flow. Most importantly, there are no loops. Some functions can naturally be defined recursively, but note that recursive function calls can be very slow, since recursion isn’t optimised.
Here’s an example of a function which computes the \(n\)^{th} Fibonacci number recursively:
//nth fibonacci number
//f(0) = f(1) = 1
//f(n+2) = f(n)+f(n+1)
if(n<=1,
1,
//else
f(n2)+f(n1)
)
Javascript functions¶
Writing a function in Javascript allows you to use all of that language’s features, such as loops, anonymous functions and DOM manipulation.
Functions defined in Javasript don’t need the function(parameters) { ... }
enclosure  that’s provided by Numbas  but they do need to return a value.
Numbas provides a large library of functions which you can use.
These are accessed from the objects Numbas.math
and Numbas.util
.
The best way to see what’s available is to look at the Numbas code documentation.
jQuery is also available.
While the JME system has its own type system for variables, separate from Javascript’s, function parameters are unwrapped to native Javascript values on evaluation so you normally don’t need to worry about it.
Examples
This function takes a list of strings and returns an HTML bullet list:
var ol = $('<ol>'); // create list element
for(var i=0; i<things.length; i++) {
ol.append($('<li>').html(things[i])); //append list item to list
}
return ol; //return list
This function creates an HTML5 canvas
element and draws a rectangle with the given dimensions, along with labels:
var c = document.createElement('canvas');
$(c).attr('width',w+40).attr('height',h+40);
var context = c.getContext('2d');
//fill in rectangle with a light shade
context.fillStyle = '#eee';
context.fillRect(5,5,w,h);
//draw outline
context.strokeStyle = '#000';
context.lineWidth = 3;
context.strokeRect(5,5,w,h);
//draw labels
context.fillStyle = '#000';
context.font = '20px sansserif';
var wstring = w+'m';
var tw = context.measureText(wstring).width;
context.fillText(wstring,5+(wtw)/2,5+h+25);
var hstring = h+'m';
var hw = context.measureText(hstring).width;
context.save();
context.translate(5+w+25,5+(h+hw)/2);
context.rotate(Math.PI/2);
context.fillText(hstring,0,0);
return c;
You can see this function in use at https://numbas.mathcentre.ac.uk/question/759/usecanvastodrawarectangle/.
This function formats a number with commas to separate every third digit, i.e. \(1,\!000,\!000\) instead of \(1000000\):
var parts=n.toString().split(".");
if(parts[1] && parts[1].length<2) {
parts[1]+='0';
}
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
You can see this function in use at https://numbas.mathcentre.ac.uk/question/396/numericalreasoningaveragesalary/.
Rulesets¶
A “ruleset” defines a list of named simplification rules used to manipulate mathematical expressions.
If you find yourself using the same set of rules repeatedly in \simplify
commands, define a new ruleset with a shorter name to save yourself some typing.
Preamble¶
The preambles allow you to add some code which affects the entire question.
The code written in the Javascript preamble is executed when the question is generated, just before the question’s variables are calculated. The Javascript preamble can access the question’s properties through the question variable. You can see an example of the Javascript preamble in use at https://numbas.mathcentre.ac.uk/question/2705/jsxgraphtestpreambleversion/.
You can see what functions are available in JavaScript at the Numbas code documentation.
If you want to do something with the display of the question on the page, you have to wait until its HTML has been generated, using the onHTMLAttached
method.
Here’s an example which hides an element in the statement with a given id:
question.onHTMLAttached(function() {
question.display.html.find('.statement #secret').hide();
});
The preamble also runs before the question’s variables are generated; if you’d like to do something that uses the question’s variables, you can either wait for onHTMLAttached
, or use question.onVariablesGenerated
if you need to do something before the HTML is generated.
The question’s variables are stored in question.scope.variables
as JME data types, or in question.unwrappedVariables
as simple JavaScript data.
Here’s an example use:
question.onVariablesGenerated(function() {
alert("a = "+question.unwrappedVariables.a);
});
The CSS preamble can be used to change the look of elements in your question. You can see an example of the CSS preamble in use at https://numbas.mathcentre.ac.uk/question/2704/csspreamble/.
Resources¶
You can upload any file as a resource to make it available for use elsewhere in the question.
Uploaded files are available from the relative URL resources/questionresources/
.
The URL for each resource you’ve uploaded is displayed next to its thumbnail.
The most common use case is to include images in content areas; see the tutorial on including an image in a question.
Exams using this question¶
A list of links to each of the exams which contain this question, for convenience.
Other versions¶
In this tab you can see all questions which are related to this one. Questions are related if one is a copy of the other, or they are both copies of a common ancestor. You can use this tab to compare the current question with related versions, and offer to merge your version of the question into another.
Click on the Compare link to go to a screen where you can offer to replace the other version with your version, or vice versa. If you have editing access to the destination question, you can replace it with the other version automatically. If you don’t have editing access, the owner of the question will be sent a Request to merge, which they must accept before the questions are merged.
Before creating the request, you’ll be asked to describe how your version differs from the one you want to replace. Try to sum up all your changes  this will show up in the question’s editing history if your request is accepted.
Warning
If the question you want to replace has changed since you made a copy of it, those changes will be lost if the request to merge is accepted  the question is completely overwritten with the new version.
You can always restore an old version of an question after a merge, by clicking on the appropriate restore link in the Editing history tab.
Active requests to merge other versions into the current question are shown underneath the list of related versions. You can accept the request, in which case your version will be replaced with the other version, or reject it, in which case your version will be unchanged and the person who made the request will be notified that it was rejected.
Editing history¶
Use this tab to keep a record of changes made to your question. Write comments to discuss problems or suggested changes.
Each time you make a change to an question, it’s saved to the database. To save a snapshot of the current state of the question, click the Set a checkpoint button. You’ll be asked to write a description of the question as it stands  describe what you’ve changed since the last snapshot, and why you’re making a snapshot.
To restore a checkpoint, click its Restore button. The current state of the question will be overwritten with the saved state.
Other activity on this question will also be shown in this tab: for example, each time somebody uses the Feedback button to provide feedback on this question, an entry is added to the editing history.
Question authoring cheat sheet¶
Click here to see a handy onepage reference on common question authoring topics.
There is also a printable PDF version.
LaTeX notation¶
LaTeX is the de facto standard markup language for mathematical notation. It’s syntactically very simple, but there’s a fairly steep learning curve in learning the names of commands.
In Numbas, inline maths (maths notation that sits on the same line as the surrounding text) is delimited either by dollar signs, e.g.:
Calculate the expansion up to the $x^4$ term.
produces
Calculate the expansion up to the \(x^4\) term.
Displaymode maths, which is displayed on its own line and rendered less compactly, is delimited by \[
and \]
. For example:
The quadratic formula is \[ x = \frac{ b \pm \sqrt{ b^24ac } }{ 2a } \]
produces
The quadratic formula is
\[x = \frac{ b \pm \sqrt{ b^24ac } }{ 2a }\]
If you’ve never used LaTeX before, a couple of good places to start are the LaTeX maths Wikibook and the Art of Problem Solving LaTeX Guide. Bear in mind that LaTeX is only used for mathsmode, so the textmode LaTeX commands don’t apply.
To find the command for a symbol you want to use, draw it in Detexify and it will show you the commands for the most similarlooking symbols.
JME¶
JME expressions are used by students to enter answers to algebraic questions, and by question authors to define variables. JME syntax is similar to what you’d type on a calculator.
Variable names¶
Variable names are caseinsensitive, so y
represents the same thing as Y
.
The first character of a variable name must be an alphabet letter; after that, any combination of letters, numbers and underscroes is allowed, with any number of '
on the end.
 Examples:
x
x_1
time_between_trials
var1
row1val2
y''
e
, i
and pi
are reserved names representing mathematical constants. They are rewritten by the interpreter to their respective numerical values before evaluation.
This screencast describes which variable names are valid, and gives some advice on how you should pick names:
Variable name annotations¶
Names can be given annotations to change how they are displayed. The following annotations are builtin:
verb
– does nothing, but names likei
,pi
ande
are not interpreted as the famous mathematical constants.op
– denote the name as the name of an operator — wraps the name in the LaTeX operatorname command when displayedv
orvector
– denote the name as representing a vector — the name is displayed in boldfaceunit
– denote the name as representing a unit vector — places a hat above the name when displayeddot
– places a dot above the name when displayed, for example when representing a derivativem
ormatrix
– denote the name as representing a matrix — displayed using a nonitalic font
Any other annotation is taken to be a LaTeX command. For example, a name vec:x
is rendered in LaTeX as \vec{x}
, which places an arrow above the name.
You can apply multiple annotations to a single variable.
For example, v:dot:x
produces a bold x with a dot on top: \(\boldsymbol{\dot{x}}\).
Data types¶

number
¶ Numbers include integers, real numbers and complex numbers. There is only one data type for all numbers.
i
,e
,infinity
andpi
are reserved keywords for the imaginary unit, the base of the natural logarithm, ∞ and π, respectively.Examples:
0
,1
,0.234
,i
,e
,pi

boolean
¶ Booleans represent either truth or falsity. The logical operations and, or and xor operate on and return booleans.
Examples:
true
,false

string
¶ Use strings to create nonmathematical text. Either
'
or"
can be used to delimit strings.You can escape a character by placing a single backslash character before it. The following escape codes have special behaviour:
\n
Newline \{
\{
\}
\}
If you want to write a string which contains a mixture of single and double quotes, you can delimit it with tripledoublequotes or triplesinglequotes, to save escaping too many characters.
Examples:
"hello there"
,'hello there'
,""" I said, "I'm Mike's friend" """

list
¶ An ordered list of elements of any data type.
Examples:
[0,1,2,3]
,[a,b,c]
,[true,false,true]

dict
¶ A ‘dictionary’a, mapping key strings to values of any data type.
A dictionary is created by enclosing one or more keyvalue pairs (a string followed by a colon and any JME expression) in square brackets, or with the
dict
function.Key strings are casesensitive.
Examples:
["a": 1, "b": 2]
["name": "Tess Tuser", "age": 106, "hobbies": ["reading","writing","arithmetic"] ]
dict("key1": 0.1, "key2": 1..3)
Warning
Because lists and dicts use similar syntax,
[]
produces an empty list, not an empty dictionary. To create an empty dictionary, usedict()
.

range
¶ A range
a..b#c
represents (roughly) the set of numbers \(\{a+nc \:  \: 0 \leq n \leq \frac{ba}{c} \}\). If the step size is zero, then the range is the continuous interval \([a,b]\).Examples:
1..3
,1..3#0.1
,1..3#0

set
¶ An unordered set of elements of any data type. The elements are pairwise distinct  if you create a set from a list with duplicate elements, the resulting set will not contain the duplicates.
Examples:
set(a,b,c)
,set([1,2,3,4])
,set(1..5)

vector
¶ The components of a vector must be numbers.
When combining vectors of different dimensions, the smaller vector is padded with zeroes to make up the difference.
Examples:
vector(1,2)
,vector([1,2,3,4])

matrix
¶ Matrices are constructed from lists of numbers, representing the rows.
When combining matrices of different dimensions, the smaller matrix is padded with zeroes to make up the difference.
Examples:
matrix([1,2,3],[4,5,6])
,matrix(row1,row2,row3)

html
¶ An HTML DOM node.
Examples:
html("<div>things</div>")
Function reference¶
Arithmetic¶

x+y
Addition. Numbers, vectors, matrices, lists, dicts, or strings can be added together.
list1+list2
concatenates the two lists, whilelist+value
returns a list with the righthandside value appended.dict1+dict2
merges the two dictionaries, with values from the righthand side taking precedence when the same key is present in both dictionaries.
 Examples:
1+2
→3
vector(1,2)+vector(3,4)
→vector(4,6)
matrix([1,2],[3,4])+matrix([5,6],[7,8])
→matrix([6,8],[10,12])
[1,2,3]+4
→[1,2,3,4]
[1,2,3]+[4,5,6]
→[1,2,3,4,5,6]
"hi "+"there"
→"hi there"

xy
Subtraction. Defined for numbers, vectors and matrices.
 Examples:
12
→1
vector(3,2)vector(1,4)
→vector(2,2)
matrix([5,6],[3,4])matrix([1,2],[7,8])
→matrix([4,4],[4,4])

x*y
Multiplication. Numbers, vectors and matrices can be multiplied together.
 Examples:
1*2
→2
2*vector(1,2,3)
→vector(2,4,6)
matrix([1,2],[3,4])*2
→matrix([2,4],[6,8])
matrix([1,2],[3,4])*vector(1,2)
→vector(5,11)

x/y
Division. Only defined for numbers.
Example:
3/4
→0.75
.

x^y
Exponentiation. Only defined for numbers.
 Examples:
3^2
→9
exp(3,2)
→9
e^(pi * i)
→1
Number operations¶

abs
(x)¶ 
len
(x)¶ 
length
(x)¶ Absolute value, or modulus. Defined for numbers, strings, ranges, vectors, lists and dictionaries. In the case of a list, returns the number of elements. For a range, returns the difference between the upper and lower bounds. For a dictionary, returns the number of keys.
 Examples:
abs(8)
→8
abs(34i)
→5
abs("Hello")
→5
abs([1,2,3])
→3
len([1,2,3])
→3
len(set([1,2,2]))
→2
length(vector(3,4))
→5
abs(vector(3,4,12))
→13
len(["a": 1, "b": 2, "c": 1])
→3

arg
(z)¶ Argument of a complex number.
Example:
arg(1)
→pi

re
(z)¶ Real part of a complex number.
Example:
re(1+2i)
→1

im
(z)¶ Imaginary part of a complex number.
Example:
im(1+2i)
→2

conj
(z)¶ Complex conjugate.
Example:
conj(1+i)
→1i

isint
(x)¶ Returns
true
ifx
is an integer.Example:
isint(4.0)
→true

root
(x, n)¶ n
^{th} root ofx
.Example:
root(8,3)
→2
.

ln
(x)¶ Natural logarithm.
Example:
ln(e)
→1

log
(x)¶ Logarithm with base 10.
Example:
log(100)
→2
.

log
(x, b) Logarithm with base
b
.Example:
log(8,2)
→3
.

degrees
(x)¶ Convert radians to degrees.
Examples:
degrees(pi/2)
→90

radians
(x)¶ Convert degrees to radians.
Examples:
radians(180)
→pi

sign
(x)¶ 
sgn
(x)¶ Sign of a number. Equivalent to \(\frac{x}{x}\), or 0 when
x
is 0. Examples:
sign(3)
→1
sign(3)
→1

max
(a, b)¶ Greatest of two numbers.
Example:
max(46,2)
→46

max
(list) Greatest of a list of numbers.
Example:
max([1,2,3])
→3

min
(a, b)¶ Least of two numbers.
Example:
min(3,2)
→2

min
(list) Least of a list of numbers.
Example:
min([1,2,3])
→1

precround
(n, d)¶ Round
n
tod
decimal places. On matrices and vectors, this rounds each element independently. Examples:
precround(pi,5)
→3.14159
precround(matrix([[0.123,4.56],[54,98.765]]),2)
→matrix([[0.12,4.56],[54,98.77]])
precround(vector(1/3,2/3),1)
→vector(0.3,0.7)

siground
(n, f)¶ Round
n
tof
significant figures. On matrices and vectors, this rounds each element independently. Examples:
siground(pi,3)
→3.14
siground(matrix([[0.123,4.56],[54,98.765]]),2)
→matrix([[0.12,4.6],[54,99]])
siground(vector(10/3,20/3),2)
→vector(3.3,6.7)

dpformat
(n, d[, style])¶ Round
n
tod
decimal places and return a string, padding with zeroes if necessary.If
style
is given, the number is rendered using the given notation style. See the page on Number notation for more on notation styles.Example:
dpformat(1.2,4)
→"1.2000"

sigformat
(n, d[, style])¶ Round
n
tod
significant figures and return a string, padding with zeroes if necessary.Example:
sigformat(4,3)
→"4.00"

formatnumber
(n, style)¶ Render the number
n
using the given number notation style.See the page on Number notation for more on notation styles.
Example:
formatnumber(1234.567,"fr")
→"1.234,567"

parsenumber
(string, style)¶ Parse a string representing a number written in the given style.
See the page on Number notation for more on notation styles.
Example:
parsenumber("1 234,567","sifr")
→1234.567
Trigonometry¶
Trigonometric functions all work in radians, and have as their domain the complex numbers.

sin
(x)¶ Sine.

cos
(x)¶ Cosine.

tan
(x)¶ Tangent: \(\tan(x) = \frac{\sin(x)}{\cos(x)}\)

cosec
(x)¶ Cosecant: \(\csc(x) = \frac{1}{sin(x)}\)

sec
(x)¶ Secant: \(\sec(x) = \frac{1}{cos(x)}\)

cot
(x)¶ Cotangent: \(\cot(x) = \frac{1}{\tan(x)}\)

arcsin
(x)¶ Inverse of
sin
. When \(x \in [1,1]\),arcsin(x)
returns a value in \([\frac{\pi}{2}, \frac{\pi}{2}]\).

arctan
(x)¶ Inverse of
tan
. When \(x\) is noncomplex,arctan(x)
returns a value in \([\frac{\pi}{2}, \frac{\pi}{2}]\).

sinh
(x)¶ Hyperbolic sine: \(\sinh(x) = \frac{1}{2} \left( \mathrm{e}^x  \mathrm{e}^{x} \right)\)

cosh
(x)¶ Hyperbolic cosine: \(\cosh(x) = \frac{1}{2} \left( \mathrm{e}^x + \mathrm{e}^{x} \right)\)

tanh
(x)¶ Hyperbolic tangent: \(tanh(x) = \frac{\sinh(x)}{\cosh(x)}\)

cosech
(x)¶ Hyperbolic cosecant: \(\operatorname{cosech}(x) = \frac{1}{\sinh(x)}\)

sech
(x)¶ Hyperbolic secant: \(\operatorname{sech}(x) = \frac{1}{\cosh(x)}\)

coth
(x)¶ Hyperbolic cotangent: \(\coth(x) = \frac{1}{\tanh(x)}\)
Number theory¶

x!
Factorial. When
x
is not an integer, \(\Gamma(x+1)\) is used instead. Examples:
fact(3)
→6
3!
→6
fact(5.5)
→287.885277815

factorise
(n)¶ Factorise
n
. Returns the exponents of the prime factorisation ofn
as a list. Examples
factorise(18)
→[1,2]
factorise(70)
→[1,0,1,1]

gamma
(x)¶ Gamma function.
 Examples:
gamma(3)
→2
gamma(1+i)
→0.4980156681  0.1549498283i

ceil
(x)¶ Round up to the nearest integer. When
x
is complex, each component is rounded separately. Examples:
ceil(3.2)
→4
ceil(1.3+5.4i)
→1+6i

floor
(x)¶ Round down to the nearest integer. When
x
is complex, each component is rounded separately.Example:
floor(3.5)
→3

trunc
(x)¶ If
x
is positive, round down to the nearest integer; if it is negative, round up to the nearest integer. Example:
trunc(3.3)
→3
trunc(3.3)
→3

fract
(x)¶ Fractional part of a number. Equivalent to
xtrunc(x)
.Example:
fract(4.3)
→0.3

mod
(a, b)¶ Modulo; remainder after integral division, i.e. \(a \bmod b\).
Example:
mod(5,3)
→2

perm
(n, k)¶ Count permutations, i.e. \(^n \kern2pt P_k = \frac{n!}{(nk)!}\).
Example:
perm(5,2)
→20

comb
(n, k)¶ Count combinations, i.e. \(^n \kern2pt C_k = \frac{n!}{k!(nk)!}\).
Example:
comb(5,2)
→10
.

gcd
(a, b)¶ 
gcf
(a, b)¶ Greatest common divisor of integers
a
andb
. Can also writegcf(a,b)
.Example:
gcd(12,16)
→4

lcm
(a, b)¶ Lowest common multiple of integers
a
andb
. Can be used with any number of arguments; it returns the lowest common multiple of all the arguments. Examples
lcm(8,12)
→24
lcm(8,12,5)
→120

xy
x
dividesy
.Example:
48
→true
Vector arithmetic¶

vector
(a1, a2, ..., aN) Create a vector with given components. Alternately, you can create a vector from a single list of numbers.
 Examples:
vector(1,2,3)
vector([1,2,3])

matrix
(row1, row2, ..., rowN) Create a matrix with given rows, which should be lists of numbers. Or, you can pass in a single list of lists of numbers.
 Examples:
matrix([1,2],[3,4])
matrix([[1,2],[3,4]])

rowvector
(a1, a2, ..., aN)¶ Create a row vector (\(1 \times n\) matrix) with the given components. Alternately, you can create a row vector from a single list of numbers.
 Examples:
rowvector(1,2)
→matrix([1,2])
rowvector([1,2])
→matrix([1,2])

dot
(x, y)¶ Dot (scalar) product. Inputs can be vectors or column matrices.
Examples:
dot(vector(1,2,3),vector(4,5,6))
,dot(matrix([1],[2]), matrix([3],[4])
.

cross
(x, y)¶ Cross product. Inputs can be vectors or column matrices.
Examples:
cross(vector(1,2,3),vector(4,5,6))
,cross(matrix([1],[2]), matrix([3],[4])
.

angle
(a, b)¶ Angle between vectors
a
andb
, in radians. Returns0
if eithera
orb
has length 0.Example:
angle(vector(1,0),vector(0,1))

det
(x)¶ Determinant of a matrix. Only defined for up to 3x3 matrices.
Examples:
det(matrix([1,2],[3,4]))
,det(matrix([1,2,3],[4,5,6],[7,8,9]))
.

transpose
(x)¶ Matrix transpose. Can also take a vector, in which case it returns a singlerow matrix.
Examples:
transpose(matrix([1,2],[3,4]))
,transpose(vector(1,2,3))
.

id
(n)¶ Identity matrix with \(n\) rows and columns.
Example:
id(3)
.
Strings¶

latex
(x)¶ Mark string
x
as containing raw LaTeX, so when it’s included in a mathmode environment it doesn’t get wrapped in a\textrm
environment.Example:
latex('\frac{1}{2}')
.

safe
(x)¶ Mark string
x
as safe: don’t substitute variable values into it when this expression is evaluated.Use this function to preserve curly braces in string literals.
Example:
safe('From { to }')

capitalise
(x)¶ Capitalise the first letter of a string.
Example:
capitalise('hello there')
.

pluralise
(n, singular, plural)¶ Return
singular
ifn
is 1, otherwise returnplural
.Example:
pluralise(num_things,"thing","things")

upper
(x)¶ Convert string to uppercase.
Example:
upper('Hello there')
.

lower
(x)¶ Convert string to lowercase.
Example:
lower('CLAUS, Santa')
.

join
(strings, delimiter)¶ Join a list of strings with the given delimiter.
Example:
join(['a','b','c'],',')
→'a,b,c'

split
(string, delimiter)¶ Split a string at every occurrence of
delimiter
, returning a list of the the remaining pieces.Example:
split("a,b,c,d",",")
→["a","b","c","d"]

currency
(n, prefix, suffix)¶ Write a currency amount, with the given prefix or suffix characters.
Example:
currency(123.321,"£","")
→'£123.32'

separateThousands
(n, separator)¶ Write a number, with the given separator character between every 3 digits
To write a number using notation appropriate to a particular culture or context, see
formatnumber
.Example:
separateThousands(1234567.1234,",")
→'1,234,567.1234'
Logic¶

x<y
Returns
true
ifx
is less thany
. Defined only for numbers.Examples:
4<5
.

x>y
Returns
true
ifx
is greater thany
. Defined only for numbers.Examples:
5>4
.

x<=y
Returns
true
ifx
is less than or equal toy
. Defined only for numbers.Examples:
4<=4
.

x>=y
Returns
true
ifx
is greater than or equal toy
. Defined only for numbers.Examples:
4>=4
.

x<>y
Returns
true
ifx
is not equal toy
. Defined for any data type. Returnstrue
ifx
andy
are not of the same data type.Examples:
'this string' <> 'that string'
,1<>2
,'1' <> 1
.

x=y
Returns
true
ifx
is equal toy
. Defined for any data type. Returnsfalse
ifx
andy
are not of the same data type.Examples:
vector(1,2)=vector(1,2,0)
,4.0=4
.

x and y
Logical AND.
Examples:
true and true
,true && true
,true & true
.

not x
Logical NOT.
Examples:
not true
,!true
.

x or y
Logical OR.
Examples:
true or false
,true  false
.

x xor y
Logical XOR.
Examples:
true XOR false
.
Ranges¶

a..
b
()¶ Define a range. Includes all integers between and including
a
andb
.Examples:
1..5
,6..6
.

a..b#s
Set the step size for a range. Default is 1. When
s
is 0, the range includes all real numbers between the limits.Examples:
0..1 # 0.1
,2..10 # 2
,0..1#0
.

a except b
Exclude a number, range, or list of items from a list or range.
Examples:
9..9 except 0
,9..9 except [1,1]
.3..8 except 4..6
,[1,2,3,4,5] except [2,3]
.

list
(range) Convert a range to a list of its elements.
Example:
list(2..2)
→[2,1,0,1,2]
Lists¶

x[n]
Get the
n
^{th} element of list, vector or matrixx
. For matrices, then
^{th} row is returned. Example:
[0,1,2,3][1]
→1
vector(0,1,2)[2]
→2
matrix([0,1,2],[3,4,5],[6,7,8])[0]
→matrix([0,1,2])

x[a..b]
Slice list
x
 return elements with indices in the given range. Note that list indices start at 0, and the final index is not included.Example:
[0,1,2,3,4,5][1..3]
→[1,2]

x in collection
Is element
x
in the list, set or rangecollection
?If
collection
is a dictionary, returnstrue
if the dictionary has a keyx
. Examples:
3 in [1,2,3,4]
→true
3 in (set(1,2,3,4) and set(2,4,6,8))
→false
"a" in ["a": 1]
→true
1 in ["a": 1]
throws an error because dictionary keys must be strings.

repeat
(expression, n)¶ Evaluate
expression
n
times, and return the results in a list.Example:
repeat(random(1..4),5)
→[2, 4, 1, 3, 4]

map
(expression,name[s],d)¶ Evaluate
expression
for each item in list, range, vector or matrixd
, replacing variablename
with the element fromd
each time.You can also give a list of names if each element of
d
is a list of values. The Nth element of the list will be mapped to the Nth name.Note
Do not use
i
ore
as the variable name to map over  they’re already defined as mathematical constants! Examples:
map(x+1,x,1..3)
→[2,3,4]
map(capitalise(s),s,["jim","bob"])
→["Jim","Bob"]
map(sqrt(x^2+y^2),[x,y],[ [3,4], [5,12] ])
→[5,13]
map(x+1,x,id(2))
→matrix([[2,1],[1,2]])
map(sqrt(x),x,vector(1,4,9))
→vector(1,2,3)

filter
(expression, name, d)¶ Filter each item in list or range
d
, replacing variablename
with the element fromd
each time, returning only the elements for whichexpression
evaluates totrue
.Note
Do not use
i
ore
as the variable name to map over  they’re already defined as mathematical constants!Example:
filter(x>5,x,[1,3,5,7,9])
→[7,9]

let
(name, definition, ..., expression)¶ 
let
(definitions, expression) Evaluate
expression
, temporarily defining variables with the given names. Use this to cut down on repetition. You can define any number of variables  in the first calling pattern, follow a variable name with its definition. Or you can give a dictionary mapping variable names to their values. The last argument is the expression to be evaluated. Examples:
let(d,sqrt(b^24*a*ac), [(b+d)/2, (bd)/2])
→[2,3]
(when[a,b,c]
=[1,5,6]
)let(x,1, y,2, x+y)
→3
let(["x": 1, "y": 2], x+y)
→3

sort
(x)¶ Sort list
x
.Example:
sort([4,2,1,3])
→[1,2,3,4]

reverse
(x)¶ Reverse list
x
.Example:
reverse([1,2,3])
→[3,2,1]

indices
(list, value)¶ Find the indices at which
value
occurs inlist
. Examples:
indices([1,0,1,0],1)
→[0,2]
indices([2,4,6],4)
→[1]
indices([1,2,3],5)
→[]

distinct
(x)¶ Return a copy of the list
x
with duplicates removed.Example:
distinct([1,2,3,1,4,3])
→[1,2,3,4]

list
(x) Convert set, vector or matrix
x
to a list of components (or rows, for a matrix). Examples:
list(set(1,2,3))
→[1,2,3]
(note that you can’t depend on the elements of sets being in any order)list(vector(1,2))
→[1,2]
list(matrix([1,2],[3,4]))
→[[1,2], [3,4]]

satisfy
(names, definitions, conditions, maxRuns)¶ Each variable name in
names
should have a corresponding definition expression indefinitions
.conditions
is a list of expressions which you want to evaluate totrue
. The definitions will be evaluated repeatedly until all the conditions are satisfied, or the number of attempts is greater thanmaxRuns
. IfmaxRuns
isn’t given, it defaults to 100 attempts.Example:
satisfy([a,b,c],[random(1..10),random(1..10),random(1..10)],[b^24*a*c>0])

sum
(numbers)¶ Add up a list of numbers
Example:
sum([1,2,3])
→6

product
(list1, list2, ..., listN)¶ Cartesian product of lists. In other words, every possible combination of choices of one value from each given list.
Example:
product([1,2],[a,b])
→[ [1,a], [1,b], [2,a], [2,b] ]

zip
(list1, list2, ..., listN)¶ Combine two (or more) lists into one  the Nth element of the output is a list containing the Nth elements of each of the input lists.
Example:
zip([1,2,3],[4,5,6])
→[ [1,4], [2,5], [3,6] ]

combinations
(collection, r)¶ All ordered choices of
r
elements fromcollection
, without replacement.Example:
combinations([1,2,3],2)
→[ [1,2], [1,3], [2,3] ]

combinations_with_replacement
(collection, r)¶ All ordered choices of
r
elements fromcollection
, with replacement.Example:
combinations([1,2,3],2)
→[ [1,1], [1,2], [1,3], [2,2], [2,3], [3,3] ]

permutations
(collection, r)¶ All choices of
r
elements fromcollection
, in any order, without replacement.Example:
permutations([1,2,3],2)
→[ [1,2], [1,3], [2,1], [2,3], [3,1], [3,2] ]
Dictionaries¶

dict[key]
Get the value corresponding to the given key string in the dictionary
d
.If the key is not present in the dictionary, an error will be thrown.
Example:
["a": 1, "b": 2]["a"]
→1

get
(dict, key, default)¶ Get the value corresponding to the given key string in the dictionary.
If the key is not present in the dictionary, the
default
value will be returned. Examples:
get(["a":1], "a", 0)
→1
get(["a":1], "b", 0)
→0

dict
(keys) Create a dictionary with the given keyvalue pairs. Equivalent to
[ .. ]
, except when no keyvalue pairs are given:[]
creates an empty list instead. Examples:
dict()
dict("a": 1, "b": 2)

keys
(dict)¶ A list of all of the given dictionary’s keys.
Example:
keys(["a": 1, "b": 2, "c": 1])
→["a","b","c"]

values
(dict)¶ 
values
(dict, keys) A list of the values corresponding to each of the given dictionary’s keys.
If a list of keys is given, the values corresponding to those keys are returned, in the same order.
 Examples:
values(["a": 1, "b": 2, "c": 1])
→[1,2,1]
values(["a": 1, "b": 2, "c": 3], ["b","a"])
→[2,1]

items
(dict)¶ A list of all of the
[key,value]
pairs in the given dictionary.Example:
values(["a": 1, "b": 2, "c": 1])
→[ ["a",1], ["b",2], ["c",1] ]
Sets¶

set
(a,b,c,...) or set([elements]) Create a set with the given elements. Either pass the elements as individual arguments, or as a list.
Examples:
set(1,2,3)
,set([1,2,3])

union
(a, b)¶ Union of sets
a
andb
 Examples:
union(set(1,2,3),set(2,4,6))
→set(1,2,3,4,6)
set(1,2,3) or set(2,4,6)
→set(1,2,3,4,6)

intersection
(a, b)¶ Intersection of sets
a
andb
, i.e. elements which are in both sets Examples:
intersection(set(1,2,3),set(2,4,6))
→set(2)
set(1,2,3) and set(2,4,6)
→set(2)

ab
Set minus  elements which are in a but not b
Example:
set(1,2,3,4)  set(2,4,6)
→set(1,3)
Randomisation¶

random
(x)¶ Pick uniformly at random from a range, list, or from the given arguments.
 Examples:
random(1..5)
random([1,2,4])
random(1,2,3)

deal
(n)¶ Get a random shuffling of the integers \([0 \dots n1]\)
Example:
deal(3)
→[2,0,1]

shuffle
(x) or shuffle(a..b)¶ Random shuffling of list or range.
 Examples:
shuffle(["a","b","c"])
→["c","b","a"]
shuffle(0..4)
→[2,3,0,4,1]
Control flow¶

award
(a, b)¶ Return
a
ifb
istrue
, else return0
.Example:
award(5,true)
→5

if
(p, a, b)¶ If
p
istrue
, returna
, else returnb
. Only the returned value is evaluated.Example:
if(false,1,0)
→0

switch
(p1, a1, p2, a2, ..., pn, an, d)¶ Select cases. Alternating boolean expressions with values to return, with the final argument representing the default case. Only the returned value is evaluated.
 Examples:
switch(true,1,false,0,3)
→1
switch(false,1,true,0,3)
→0
switch(false,1,false,0,3)
→3
HTML¶

html
(x) Parse string
x
as HTML.Examples:
html('<div>Text!</div>')
.

table
(data), table(data, headers)¶ Create an HTML with cell contents defined by
data
, which should be a list of lists of data, and column headers defined by the list of stringsheaders
. Examples:
table([[0,1],[1,0]], ["Column A","Column B"])
table([[0,1],[1,0]])

image
(url)¶ Create an HTML img element loading the image from the given URL. Images uploaded through the resources tab are stored in the relative URL resources/images/<filename>.png, where <filename> is the name of the original file.
 Examples:
image('resources/images/picture.png')
image(chosenimage)
 Question using randomly chosen images.
JSON¶
JSON is a lightweight datainterchange format. Many public data sets come in JSON format; it’s a good way of encoding data in a way that is easy for both humans and computers to read and write.
For an example of how you can use JSON data in a Numbas question, see the exam Working with JSON data.

json_decode
(json)¶ Decode a JSON string into JME data types.
JSON is decoded into numbers, strings, booleans, lists, or dictionaries. To produce other data types, such as matrices or vectors, you will have to postprocess the resulting data.
Warning
The JSON value
null
is silently converted to an empty string, because JME has no “null” data type. This may change in the future.Example:
json_decode(' {"a": 1, "b": [2,true,"thing"]} ')
→["a": 1, "b": [2,true,"thing"]]

json_encode
(data)¶ Convert the given object to a JSON string.
Numbers, strings, booleans, lists, and dictionaries are converted in a straightforward manner. Other data types may behave unexpectedly.
Example:
json_encode([1,"a",true])
→'[1,"a",true]'
Number notation¶
There are many different ways of writing a number, depending on culture and context.
Numbas can interpret and display numbers in several styles.
Styles of notation¶
Numbas supports the following styles of notation. The entry in the “Code” column is the string you should use to identify the style in JME or JavaScript code.
Style  Code  Description  Example 

English (plain)  plainen 
Powers of 1000 not separated, and a dot is used for the decimal mark.  1234567.890123 
English  en 
Positive powers of 1000 are separated with commas, and a dot is used for the decimal mark.  1,234,567.890123 
SI (English)  sien 
Powers of 1000 are separated with spaces, and a dot is used for the decimal mark.  1 234 567.890 123 
SI (French)  sifr 
Powers of 1000 are separated with spaces, and a comma is used for the decimal mark.  1 234 567,890 123 
Continental  eu 
Positive powers of 1000 are separated with dots, and a comma is used for the decimal mark.  1.234.567,890123 
Continental (plain)  plaineu 
Powers of 1000 are not separated, and a comma is used for the decimal mark.  1234567,890123 
Swiss  ch 
Positive powers of 1000 are separated with apostrophes, and a dot is used for the decimal mark.  1‘234‘567.890123 
Indian  in 
Groups of digits in the integer part are separated with commas. The rightmost group is three digits, and other digits are grouped in pairs. A dot is used for the decimal mark.  12,34,567.890123 
Warning
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.
In the JavaScript runtime, these styles are defined in Numbas.util.numberNotationStyles
.
Numbers in JME¶
In JME code, and Mathematical expression parts, numbers are written in the “English (plain)” form only.
You can parse a string representing a number written in a different style using the parsenumber
function, and display it using a particular style using the formatnumber
function, or by giving a style code to dpformat
or sigformat
.
Substituting variables into displayed maths¶
In Numbas, maths is displayed using LaTeX. For help with LaTeX, see :ref:LaTeX notation
.
LaTeX is purely a typesetting language and is illsuited for representing meaning in addition to layout. For this reason, dynamic or randomised maths expressions must be written in JME syntax and converted to LaTeX. Numbas provides two new LaTeX commands to do this for you.
To substitute the result of an expression into a LaTeX expression, use the \var
command. Its parameter is a JME expression, which is evaluated and then converted to LaTeX.
For example:
\[ \var{2^3} \]
produces:
\[ 8 \]
and if a variable called x has been defined to have the value 3:
\[ 2^{\var{x}} \]
produces:
\[ 2^{3} \]
This simple substitution doesn’t always produce attractive results, for example when substituted variables might have negative values. If \(y=4\):
\[ \var{x} + \var{y} \]
produces:
\[ 3 + 4 \]
To deal with this, and other more complicated substitutions, there is the \simplify
command.
The main parameter of the \simplify
command is a JME expression. It is not evaluated  it is converted into LaTeX as it stands. For example:
\[ \simplify{ x + (1/y) } \]
produces:
\[ x  \frac{1}{y} \]
Variables can be substituted in by enclosing them in curly braces. For example:
\[ \simplify{ {x} / {y} } \]
produces, when \(x=2,y=3\):
\[ \frac{ 2 }{ 3 } \]
The \simplify
command automatically rearranges expressions, according to a set of simplification rules, to make them look more natural. Sometimes you might not want this to happen, for example while writing out the steps in a worked solution.
The set of rules to be used is defined in a list enclosed in square brackets before the main argument of the \simplify
command. You can control the \simplify
command’s behaviour by switching rules on or off.
For example, in:
\[ \simplify{ 1*x } \]
I have not given a list of rules to use, so they are all switched on. The unitFactor
rule cancels the redundant factor of 1 to produce:
\[ x \]
while in:
\[ \simplify[!unitFactor]{ 1*x } \]
I have turned off the unitFactor rule, leaving the expression as it was:
\[ 1 x \]
When a list of rules is given, the list is processed from left to right. Initially, no rules are switched on. When a rule’s name is read, that rule is switched on, or if it has an exclamation mark in front of it, that rule is switched off.
Sets of rules can be given names in the question’s Rulesets section, so they can be turned on or off in one go.
Display options¶
The \simplify
and \var
commands take an optional list of settings, separated by commas.
These affect how certain elements, such as numbers or vectors, are displayed.
The following display options are available:
 fractionNumbers
This rule doesn’t rewrite expressions, but tells the maths renderer that you’d like noninteger numbers to be displayed as fractions instead of decimals.
Example:
\var[fractionNumbers]{0.5}
produces \(\frac{1}{2}\). rowVector
 This rule doesn’t rewrite expressions, but tells the maths renderer that you’d like vectors to be rendered as rows instead of columns.
Simplification rules¶
As well as the display options, the \simplify
command takes an optional list of names of simplification rules to use, separated by commas.
These rules affect how the command rearranges the expression you give it.
Lists of simplification rule names are read from left to right, and rules are added or removed from the set in use as their names are read.
To include a rule, use its name, e.g. unitfactor
.
To exclude a rule, put an exclamation mark in front of its name, e.g. !unitfactor
.
Rule names are not casesensitive: any mix of lowercase or uppercase works.
To turn all builtin rules on, use the name all
. To turn all builtin rules off, use !all
.
If you don’t give a list of options, e.g. \simplify{ ... }
, all the builtin rules are used.
If you give an empty list of options, e.g. \simplify[]{ ... }
, no rules are used.
For example, the following code:
\simplify[all,!collectNumbers,fractionNumbers]{ 0.5*x + 1*x^2  2  3 }
turns on every rule, but then turns off the collectNumbers
rule, so every rule except collectNumbers
can be applied.
Additionally, the display option fractionNumbers
is turned on, so the 0.5
is displayed as \(\frac{1}{2}\).
Altogether, this produces the following rendering: \(\frac{1}{2} x + x^2  2  3\)
The following simplification rules are available:
 basic
These rules are always turned on, even if you give an empty list of rules. They must be actively turned off, by including
!basic
in the list of rules.+x
→x
(get rid of unary plus)x+(y)
→xy
(plus minus = minus)x(y)
→x+y
(minus minus = plus)(x)
→x
(unary minus minus = plus)x
→eval(x)
(if unary minus on a complex number with negative real part, rewrite as a complex number with positive real part)x+y
→eval(x+y)
(always collect imaginary parts together into one number)x+y
→eval(xy)
(similarly, for negative numbers)(x)/y
→(x/y)
(take negation to left of fraction)x/(y)
→(x/y)
(x)*y
→(x*y)
(take negation to left of multiplication)x*(y)
→(x*y)
x+(y+z)
→(x+y)+z
(make sure sums calculated lefttoright)x(y+z)
→(xy)z
x+(yz) ``(x+y)z'
x(yz)
>(xy)+z
(x*y)*z
→x*(y*z)
(make sure multiplications go righttoleft)n*i
→eval(n*i)
(always collect multiplication by \(i\))i*n
→eval(n*i)
 unitFactor
Cancel products of 1
1*x
→x
x*1
→x
 unitPower
Cancel exponents of 1
x^1
→x
 unitDenominator
Cancel fractions with denominator 1
x/1
→x
 zeroFactor
Cancel products of zero to zero
x*0
→0
0*x
→0
0/x
→0
 zeroTerm
Omit zero terms
0+x
→x
x+0
→x
x0
→x
0x
→x
 zeroPower
Cancel exponents of 0
x^0
→1
 noLeadingMinus
Rearrange expressions so they don’t start with a unary minus
x+y
→yx
0
→0
 collectNumbers
Collect together numerical (as opposed to variable) products and sums. The rules below are only applied if
n
andm
are numbers.xy
→(x+y)
(collect minuses)n+m
→eval(n+m)
(add numbers)nm
→eval(nm)
(subtract numbers)n+x
→x+n
(numbers go to the end of expressions)(x+n)+m
→x+eval(n+m)
(collect number sums)(xn)+m
→x+eval(mn)
(x+n)m
→x+eval(nm)
(xn)m)
→xeval(n+m)
(x+n)+y
→(x+y)+n
(numbers go to the end of expressions)(x+n)y
→(xy)+n
(xn)+y
→(x+y)n
(xn)y
→(xy)n)
n*m
→eval(n*m)
(multiply numbers)x*n
→n*x
(numbers go to left hand side of multiplication, unless \(n=i\))m*(n*x)
→eval(n*m)*x
 simplifyFractions
Cancel fractions to lowest form. The rules below are only applied if
n
andm
are numbers and \(gcd(n,m) > 1\).n/m
→eval(n/gcd(n,m))/eval(m/gcd(n,m))
(cancel simple fractions)(n*x)/m
→(eval(n/gcd(n,m))*x)/eval(m/gcd(n,m))
(cancel algebraic fractions)n/(m*x)
→eval(n/gcd(n,m))/(eval(m/gcd(n,m))*x)
(n*x)/(m*y)
→(eval(n/gcd(n,m))*x)/(eval(m/gcd(n,m))*y)
 zeroBase
Cancel any power of zero
0^x
→0
 constantsFirst
Numbers go to the left of multiplications
x*n
→n*x
x*(n*y)
→n*(x*y)
 sqrtProduct
Collect products of square roots
sqrt(x)*sqrt(y)
→sqrt(x*y)
 sqrtDivision
Collect fractions of square roots
sqrt(x)/sqrt(y)
→sqrt(x/y)
 sqrtSquare
Cancel square roots of squares, and squares of square roots
sqrt(x^2)
→x
sqrt(x)^2
→x
sqrt(n)
→eval(sqrt(n))
(ifn
is a square number)
 trig
Simplify some trigonometric identities
sin(n)
→eval(sin(n))
(ifn
is a multiple of \(\frac{\pi}{2}\))cos(n)
→eval(cos(n))
(ifn
is a multiple of \(\frac{\pi}{2}\))tan(n)
→0
(ifn
is a multiple of \(\pi\))cosh(0)
→1
sinh(0)
→0
tanh(0)
→0
 otherNumbers
Evaluate powers of numbers. This rule is only applied if
n
andm
are numbers.n^m
→eval(n^m)
Displayonly JME functions¶
There are a few “virtual” JME functions which can not be evaluated, but allow you to express certain constructs for the purposes of display, while interacting properly with the simplification rules.

int
(expression, variable)¶ An indefinite integration, with respect to the given variable.
int(x^2+2,x)
→ \(\displaystyle{\int \! x^2+2 \, \mathrm{d}x}\)int(cos(u),u)
→ \(\displaystyle{\int \! \cos(u) \, \mathrm{d}u}\)

defint
(expression, variable, lower bound, upper bound)¶ A definite integration between the two given bounds.
defint(x^2+2,x,0,1)
→ \(\displaystyle{\int_{0}^{1} \! x^2+2 \, \mathrm{d}x}\)defint(cos(u),u,x,x+1)
→ \(\displaystyle{\int_{x}^{x+1} \! \cos(u) \, \mathrm{d}u}\)

diff
(expression, variable, n)¶ \(n\)th derivative of expression with respect to the given variable
diff(y,x,1)
→ \(\frac{\mathrm{d}y}{\mathrm{d}x}\)diff(x^2+2,x,1)
→ \(\frac{\mathrm{d}}{\mathrm{d}x} \left (x^2+2 \right )\)diff(y,x,2)
→ \(\frac{\mathrm{d}^{2}y}{\mathrm{d}x^{2}}\)

partialdiff
(expression, variable, n)¶ \(n\)th partial derivative of expression with respect to the given variable
partialdiff(y,x,1)
→ \(\frac{\partial y}{\partial x}\)partialdiff(x^2+2,x,1)
→ \(\frac{\partial }{\partial x} \left (x^2+2 \right )\)partialdiff(y,x,2)
→ \(\frac{\partial ^{2}y}{\partial x^{2}}\)

sub
(expression, index)¶ Add a subscript to a variable name. Note that variable names with constant subscripts are already rendered properly – see Variable names – but this function allows you to use an arbitray index, or a more complicated expression.
sub(x,1)
→ \(x_{1}\)sub(x,n+2)
→ \(x_{n+2}\)
The reason this function exists is to allow you to randomise the subscript. For example, if the index to be used in the subscript is held in the variable
n
, then this:\simplify{ sub(x,{n}) }
will be rendered as
\(x_{1}\)when
n = 1
.

sup
(expression, index)¶ Add a superscript to a variable name. Note that the simplification rules to do with powers won’t be applied to this function, since it represents a generic superscript notation, rather than the operation of raising to a power.
sup(x,1)
→ \(x^{1}\)sup(x,n+2)
→ \(x^{n+2}\)
Patternmatching mathematical expressions¶
Warning
The patternmatching algorithm is new and experimental. It opens up many new possibilities for providing adaptive feedback and manipulating mathematical expressions in general, but the interface is currently quite cumbersome. This documentation will be expanded as the system is used more.
Numbas includes a sophisticated patternmatching algorithm for mathematical expressions. It’s mainly used by the \simplify
command, but can also be used in, for example, custom marking scripts to answer more nuanced questions about the form of the student’s answer.
The patternmatcher should be considered to work similarly to how a regular expression algorithm, except it operates on algebraic syntax trees instead of text strings. The algorithm will either return false
, when the expression doesn’t match the pattern, or true
, and a dictionary of named matching groups, which are subtrees of the input expression.
Using the pattern matcher¶
The function Numbas.jme.display.matchExpression(pattern,expression) matches a JME expression against a pattern. The pattern is also written in JME syntax, but there are extra operators available to allow extra control what does or doesn’t match.
The parameters of a commutative operation in the pattern (i.e. addition, multiplication, or equality) can match in any order. The algorithm matches greedily, reading from left to right in both the pattern to match and the input expression.
Patternmatching should only be used for assigning marks when the form of the student’s answer is what’s being assessed, for example when the student is asked to factorise a quadratic or reduce a fraction to lowest terms. For answers which are the result of a calculation, you should use the normal numerical marking algorithms because patternmatching can be too restrictive (or, if you’re not careful, too accepting!) In such cases, you could use patternmatching to provide feedback about possible errors the student made, when their answer is marked wrong by the numerical algorithm.
Patternmatching syntax¶

?
Match anything.

??
Match anything or nothing.

expr;g
Capture
expr
in the group namedg
.

m_any(expr1,expr2,...)
Match any of the expressions
exprN
.

m_all(expr)
Capture all terms (in an addition, multiplication, or other commutative operation) matching
expr
.

m_pm(expr)
Capture
expr
or(expr)
, i.e. plus or minus the given expression.

m_not(expr)
Match anything except
expr
.

m_uses(name1,name2,...)
Match any expression which uses the given variable names.

m_commute(expr)
Match the terms in
expr
in any order, following the laws of commutativity. (This is only required if you are usingmatchExpression
with thedoCommute
flag set tofalse
, and you only want to use commutativity in certain places)

m_nothing
Match nothing. Useful as an empty term to act as the righthand side of an addition, where you want to capture all terms in the lefthand side.

m_number
Match a single number.

m_type(type)
Match a single token of the given type. For example,
m_type(vector)
matches a vector, whilem_type(op)
matches any operator. See Data types for a list of data types.
To help with learning the new syntax, there is an online tool to test expressions against patterns at http://www.staff.ncl.ac.uk/christian.perfect/patternmatching/matching.html
Examples¶
Get all \(x\) terms in a polynomial:
m_all(m_pm(m_all(??)*m_any(x,x^?)));xs+m_all(??);rest
Get the coefficient and degree of an \(x\) term:
m_pm(m_all(??);coefficient*m_any(x,x^?;degree))
Get both sides of an equation:
?;left=?;right
Check \(x\) terms are collected on one side of an equation:
m_uses(x);xside = m_not(m_uses(x));otherside
Check that a quadratic is factorised:
(m_pm(??*x);a+?;b)*(m_pm(??*x);c+?;d)
Capture multiple powers of \(x\) and \(y\):
m_all( m_any( ??x, ??y, ??x^??, ??y^??, m_any(x,x^??)*m_any(y,y^??)*?? ) );terms + m_all(??;rest)
Javascript APIs¶
Numbas provides a JavaScript API through the Numbas
object. It’s documented online at numbas.github.io/Numbas
Extensions¶
An extension is a folder containing one or more files that should be included in an exam. They can be javascript files, CSS stylesheets, or any other kind of resource.
Each extension must have a unique short name, which is used both in the Numbas editor and by the scriptloader in compiled exams.
The minimum an extension must contain is a file named <extensionname>.js
, containing the following:
Numbas.addExtension('<extensionname>',['base'],function(extension) {
});
(See the API documentation for Numbas.addExtension for details on how this function works)
This function call tells Numbas that the extension has loaded. Because Numbas can’t guarantee the order script files will be loaded in, code which uses the Numbas object must be placed inside the callback function given to Numbas.addExtension
.
Using an extension with the editor¶
Package your extension’s files into a .zip file. Next, go to the Numbas editor click on the Your profile link, then Your extensions. The Upload a new extension link takes you to a form where you can upload the .zip file you created.
 Name:
 A humanreadable name for the extension. This should concisely describe what it does, or what feature it provides.
 Short name:
A unique identifier for the extension.
Warning
An extension’s short name must be unique, and match the short name used when uploading it to the editor. This means that if you reuse an extension and use a different name when uploading it to the editor, you must rename its JavaScript file and change the name given to
Numbas.addExtension
. Documentation URL:
 The URL of a page describing how to use the extension.
Adding JME functions¶
An extension can add JME functions (or rulesets, or anything else that goes in a Scope object by manipulating the extension.scope
object. Here’s an example which adds a single JME function:
Numbas.addExtension('difference',['jme'],function(extension) {
var funcObj = Numbas.jme.funcObj;
var TNum = Numbas.jme.types.TNum;
extension.scope.addFunction(new funcObj('difference',[TNum,TNum],TNum,function(a,b){ return Math.abs(ab); }, {unwrapValues:true}));
})
(Download this extension: difference.zip
)
Adding a new JME data type¶
JME data types are JavaScript objects, distinguished by their type
property. The object should have a value property which contains the data it represents. The JME system can happily use new data types, but you’ll need to tell it how to render them as LaTeX or JME code. This is done by adding methods to Numbas.jme.display.typeToTeX
and Numbas.jme.display.typeToJME
. Once you’ve defined how to create and display the new data type, you can add functions dealing with it in the same way as for the builtin data types.
Here’s an example extension which defines a toy “chemical” data type (excuse the bad chemistry):
Numbas.addExtension('chemicals',['jme','jmedisplay'],function(chemicals) {
var chemicalsScope = chemicals.scope;
// Define the constructor for a new data type representing a chemical formula
// `formula` is a dictionary mapping element symbols to the number of atoms present
function TChemical(formula) {
this.value = formula;
}
TChemical.prototype.type = 'chemical';
// define a couple of example formulas
chemicalsScope.variables.oxygen = new TChemical({O:2});
chemicalsScope.variables.water = new TChemical({H:2, O:1});
// Code to render a chemical formula as LaTeX
Numbas.jme.display.typeToTeX.chemical = function(thing,tok,texArgs,settings) {
var out = '';
for(var element in tok.value){
out += element;
var num = tok.value[element];
if(num>1) {
out += '_{'+num+'}';
}
}
return '\\mathrm{'+out+'}';
}
// Code to render a chemical formula as a JME expression
Numbas.jme.display.typeToJME.chemical = function(tree,tok,bits,settings) {
var out = '';
for(var element in tok.value) {
if(out.length) {
out += '+';
}
out += 'molecule("'+element+'",'+tok.value[element]+')'
}
return out;
}
var funcObj = Numbas.jme.funcObj;
var TString = Numbas.jme.types.TString;
var TNum = Numbas.jme.types.TNum;
// define addition on chemicals: add up the elements in each formula
chemicalsScope.addFunction(new funcObj('+',[TChemical,TChemical],TChemical,function(c1,c2) {
var nformula = {};
var element;
for(element in c1) {
nformula[element] = c1[element];
}
for(element in c2) {
if(element in nformula) {
nformula[element] += c2[element];
} else {
nformula[element] = c2[element];
}
}
return nformula;
}));
// define a function to create a molecule with given number of atoms of given element
chemicalsScope.addFunction(new funcObj('molecule',[TString,TNum],TChemical,function(element,numatoms) {
var formula = {};
formula[element] = numatoms;
return formula;
}));
// define a JME functions which tells you how many of the given element are in a formula
chemicalsScope.addFunction(new funcObj('numatoms',[TChemical,Numbas.jme.types.TString],Numbas.jme.types.TNum,function(chemical,element) {
if(element in chemical) {
return chemical[element];
} else {
return 0;
}
}));
});
(Download this extension: chemicals.zip
)
Firstparty extensions¶
JSXGraph¶
The JSXGraph extension provides a function Numbas.extensions.jsxgraph.makeBoard
which creates a JSXGraph board and wraps it inside an HTML div element to embed in the page.
The simplest use is to define a custom function in Javascript which returns an HTML value, like so:
// First, make the JSXGraph board.
// The function provided by the JSXGraph extension wraps the board up in
// a div tag so that it's easier to embed in the page.
var div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',
{boundingBox: [13,16,13,16],
axis: false,
showNavigation: false,
grid: true
});
// div.board is the object created by JSXGraph, which you use to
// manipulate elements
var board = div.board;
// Then do whatever you want with the board....
// and return the container div
return div;
The question Using student input in a JSXGraph diagram is a more complete example of creating a JSXGraph diagram based on question variables and student input.
For help on using JSXGraph, see the official documentation.
GeoGebra¶
The GeoGebra extension provides a couple of functions to load a GeoGebra material from geogebra.org and embed it in a question.
For more information on how to use the extension, see its documentation.
The screencast below shows how to use GeoGebra in a question.
Statistical functions¶
The statistical functions extension provides many new functions for generating samples from random distributions, and calculating statistics.
It is built on the jStat library and follows its API quite closely.
Here’s a list of the supported functions, as of January 2013. For information on usage, please see the jStat documentation.
sum
sumsqrd
sumsqerr
product
min
max
mean
meansqerr
geomean
median
cumsum
diff
mode
range
variance
stdev
meandev
meddev
coeffvar
quartiles
covariance
corrcoeff
betapdf
betacdf
betainv
betamean
betamedian
betamode
betasample
betavariance
centralfpdf
centralfcdf
centralfinv
centralfmean
centralfmode
centralfsample
centralfvariance
cauchypdf
cauchycdf
cauchyinv
cauchymedian
cauchymode
cauchysample
chisquarepdf
chisquarecdf
chisquareinv
chisquaremean
chisquaremedian
chisquaremode
chisquaresample
chisquarevariance
exponentialpdf
exponentialcdf
exponentialinv
exponentialmean
exponentialmedian
exponentialmode
exponentialsample
exponentialvariance
gammapdf
gammacdf
gammainv
gammamean
gammamode
gammasample
gammavariance
invgammapdf
invgammacdf
invgammainv
invgammamean
invgammamode
invgammasample
invgammavariance
kumaraswamypdf
kumaraswamycdf
kumaraswamymean
kumaraswamymedian
kumaraswamymode
kumaraswamyvariance
lognormalpdf
lognormalcdf
lognormalinv
lognormalmean
lognormalmedian
lognormalmode
lognormalsample
lognormalvariance
normalpdf
normalcdf
normalinv
normalmean
normalmedian
normalmode
normalsample
normalvariance
paretopdf
paretocdf
paretomean
paretomedian
paretomode
paretovariance
studenttpdf
studenttcdf
studenttinv
studenttmean
studenttmedian
studenttmode
studenttsample
studenttvariance
weibullpdf
weibullcdf
weibullinv
weibullmean
weibullmedian
weibullmode
weibullsample
weibullvariance
uniformpdf
uniformcdf
uniformmean
uniformmedian
uniformmode
uniformsample
uniformvariance
binomialpdf
binomialcdf
geometricpdf
geometriccdf
geometricmean
geometricmedian
geometricmode
geometricsample
geometricvariance
negbinpdf
negbincdf
hypgeompdf
hypgeomcdf
poissonpdf
poissoncdf
poissonmean
poissonsample
poissonvariance
triangularpdf
triangularcdf
triangularmean
triangularmedian
triangularmode
triangularsample
triangularvariance
zscore
ztest
tscore
ttest
anovafscore
anovaftest
ftest
normalci
tci
betafn
betaln
betacf
ibetainv
ibeta
gammaln
gammafn
gammap
factorialln
factorial
combination
permutation
gammapinv
erf
erfc
erfcinv
randn
randg
Themes¶
A Numbas theme is a package of files containing everything needed to display an exam in the browser. This includes an HTML file, CSS stylesheets, and JavaScript to manage coordination between the page and the exam runtime.
Contents of a theme¶
A theme is a folder containing the following three things:
 An optional file called
inherit.txt
containing the name of a theme to extend.  A folder called
files
containing static files to be included in the compiled exam. For a theme which does not extend another, this contains at the minimum a JavaScript filescripts/display.js
.  A folder called
templates
containing, at the least, two files calledindex.html
andquestion.xslt
. These files are jinja2 templates which will produce the HTML for the exam and the XSLT stylesheet for questions, respectively.
Oldstyle themes¶
Before Numbas 2.1, the files index.html
and question.xslt
were static, with index.html
residing in the files
folder, and question.xslt
residing in a folder called xslt
.
For backwards compatibility, if either of these files are found in those paths, they’re used instead of any template files.
This way, if an oldstyle theme extends the default
theme and overrides index.html
, it will still work.
JavaScript and CSS files¶
All JavaScript and CSS files used by a Numbas exam are collected into two files, scripts.js
and styles.css
.
These are the only files you need to load from your theme’s index.html
 all script and stylesheet files, including those provided by your theme, are collected into these.
HTML and XSLT templates¶
The files index.html
and question.xslt
are produced using jinja2.
The main reason for this is to allow authors to override sections of the layout, while inheriting the rest from the base theme.
While jinja2 is a very powerful templating language, it’s used in the default theme solely as a way of including subtemplates with the {% include "filename.html" %}
tag.
However, if you wish to do something more sophisticated, the variables exam
and options
are available in the template context.
See the Numbas compiler source code to find out what properties these objects have.
Building off an existing theme¶
At the top of your theme folder, place a file called inherit.txt
containing the name of the theme to extend, e.g. default
.
When an exam is compiled using your theme, all of the parent theme’s files will be included, and then all of the files belonging to your theme, overriding any files of the same name from the parent theme.
For example, to change the logo displayed in the navigation bar, you could create a theme containing only inherit.txt
and templates/logo.html
.
The default theme is packaged with the Numbas compiler; if you want to modify it you should first download the Numbas repository from https://github.com/numbas/Numbas and copy the folder themes/default
.
It’s a good idea to remove from your theme package any files that you don’t change from the default, so that bugfixes in the base theme will be carried through to your version.
Uploading a theme to the editor¶
Package your theme’s files into a .zip file. Next, go to the Numbas editor and click on the Your profile link, then Your themes. The Upload a new theme takes you to a form where you can upload the .zip file you created, and give it a humanreadable name. You will be able to select any of your themes in the exam edit page.
If you make changes to your theme, go back to the Your themes page and click on the Edit link, then upload a revised .zip file.
Examples¶
 Replace the Numbas logo:
changelogotheme.zip
 Add custom CSS rules:
extracsstheme.zip
Installing an editor server¶
You can find instructions on setting up your own instance of the Numbas at the Numbas editor GitHub page.