Development log – November 2014: version tracking!

Here’s another round-up of recent development work on Numbas.

Version tracking

The big new feature is version tracking – every change made to a Numbas question or exam is saved in the database, and you can revert to old versions in the new “Editing history” tab. Each version is stamped with the time of its creation and the name of the person who made the change. You can also add your own comment to a version to describe what you’ve changed.

editing history

The editor now also has undo/redo buttons for changes made since you opened the page, so you can quickly rewind if you do something silly like delete a part or variable.

This should make maintaining questions and collaborating on question development a lot easier!

Other changes

  • The order in which custom scripts run has been cleared up. The “when part is created” script runs directly after the built-in constructors. The marking and validation scripts are attached to the object just before the display is initialised, but before the part-type-specific code is run. If the exam is being resumed from a saved session, the part is submitted after the built-in and custom constructors have been run, so you can depend on all your custom code being present whenever the marking script is run.
  • Fixed a bug which caused a crash when a custom script ends with a comment (code)
  • Numbas.math.rationalApproximation halts its algorithm when it gets within the desired range of a whole number. If the number you feed in is already within that range but not exactly an integer, it had no steps to reconstruct and returned [1,0]. Now it correctly returns [n,1]. (code)
  • Updated the Spanish, Norwegian and Dutch translations.
  • Numbas.math.niceNumber rounds numbers smaller than 1E-15 to 0. (code)
  • Made sure that the “try another question” button accounts for the shuffling of the exam’s questions. (code)
  • Fixed the JME type-checking algorithm when a function call doesn’t have as many parameters as the definition it’s being compared against. (code)
  • Numbas.math.precround only rounds the fractional part of the number it’s given, instead of working on the whole number. This reduces the size of floating point errors introduced during the process. (code)
  • Numbas.jme.subvars renders numbers in scientific notation in JME syntax, not javascript’s. (code)
  • The JME function distinct uses Numbas.util.eq to test for duplicates instead of JavaScript’s equality operator. This means it works on all JME data types, not just ones which have analogues in JavaScript. (code)
  • You’re no longer warned that unsaved changes will be lost when leaving an exam which is already in review mode. (code)
  • Numbas now catches the error thrown if the SCORM API is already initialised before it starts (a particularly annoying bug in Moodle can cause this to happen) (code)
  • There are two new JME functions: join and sum.
  • Fixed a bug which meant multiple response parts were marked as having unsubmitted changes even if nothing had changed. (code)
  • You can now get the student’s ID from This was added to enable a custom theme which uses the student’s ID as the seed for the random number generator. (code, API doc)
  • Added a few simplification rules to work with multiples of pi, i and e. (code)
  • Added commands m_number and m_type(name) to the pattern-matching syntax. (documentation)
  • There’s now a “replace with gap-fill” button on each part. This is handy if you start writing a part, and then decide you want to change its layout or add more inputs by making it a gap-fill.
  • As well as shuffling the order of an exam’s questions, you can now choose to use only a subset of the questions attached to the exam. A few people asked for this to provide a random element to exams whose questions aren’t randomised. (documentation)
  • If your Numbas extension is just a single .js file, you can upload that instead of having to put it inside a .zip file.
  • You can choose whether to give the student a warning or prevent submission entirely if they choose the wrong number of options in a multiple-response part.