Maths with QTI – QTI XML Structure and Building Blocks Resource

We have recently started using QTI, specifically Uniqurate and QTIWorks, to write maths questions for delivery to students. Uniqurate can be used to write basic questions, including maths questions with numerical answers and simple randomisation of values. However, to incorporate more complex randomisation, e.g. randomising variable letters, to allow mathematical expressions to be given as answers and to do various other more complex things with maths questions, it is necessary to write (or, preferably, modify someone else’s!) QTI XML. This can get quite complicated and I have found some aspects of it difficult to get stuck into. I find that I know that something is possible, but it can take some time to pin down exactly how to do it, and I usually copy code from other questions. (Many thanks to Dr Sue Milne from ELandWeb for providing extensive help, both by giving access to her questions and answering many QTI-related queries)

One thing that I keep wishing for is a resource containing reusable blocks of QTI code that could be used to build a question. I believe that such a resource does not currently exist, so I have decided to start to write one, the links to which can be found below.

At this point I should make the disclaimer that I am still early on in my QTI journey, so I am no expert, and can by no means guarantee that this resource will be correct, but I will try to improve and extend it as I get to know the QTI specification better. The posts based on the XML snippets that I have been using, and therefore they are far from being a complete resourse. However, I hope they are useful to anyone getting started with QTI. Please feel free to suggest additions and corrections.

  1. QTI XML Basic Structure
  2. Variable Declarations
  3. Template Processing
  4. Item Body
  5. Response Processing
  6. Solution and Hint
  7. Modifying assessment.xml (for Assessments created in Uniqurate)

Maths with QTI – QTI XML Basic Structure

Please note that this is a work in progress!

This is the first of my QTI XML Building Blocks posts, where I will give the basic structure of an assessment item in a QTI XML file, that can be used as a framework that can be filled in with the building blocks that I will cover in future posts. This is very much a work in progress and I can’t promise everything is correct. At this stage I am just trying to create something that is useful to me, and putting it out there in case it is useful to anyone else!

So, here is the basic structure of a QTI XML document (or the basic structure I’ve been using/copying for writing questions):

<?xml version="1.0" encoding="UTF-8"?>

<!-- Define question properties -->
<!-- Some of these are obvious, others are XML namespace definitions - not all of these are generally needed 
   adaptive - if set to false, only one attempt is allowed, so this is best for summative items. If set to true, multiple attempts are allowed and the feedback/outcomes can be changed, and this is better for formative items, where a user can have multiple goes. This should not be confused with an adaptive test, where the questions presented change depending on a user's answers to previous questions, although a similar thing can be achieved within an adaptive item.
-->
<assessmentItem xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1"
   xmlns:m="http://www.w3.org/1998/Math/MathML"
   xmlns:xi="http://www.w3.org/2001/XInclude"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ma="http://mathassess.qtitools.org/xsd/mathassess"
   xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 imsqti_v2p1.xsd http://mathassess.qtitools.org/xsd/mathassess mathassess.xsd">
   xml:lang="en"
   adaptive="true"
   timeDependent="false"
   identifier="questionidentifier"
   title="Question Title">

   <!-- VARIABLE DECLARATIONS -->
   <!-- Here we define all of the variables that are going to be used in the question -->

   <!-- Response Declarations -->
   <!-- These are the variables used in response processing, including those for storing the response(s) given by the user -->
   <responseDeclaration identifier="RESPONSE" cardinality="single" baseType="integer"/>

   <!-- Outcome Declarations -->
   <!-- These are the variables used for returning an outcome to the user, e.g. score, feedback -->
   <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="integer"/>

   <!-- Template Declarations -->
   <!-- These are the variables used for creating the question, e.g. the variables used for randomising values within a question -->
   <templateDeclaration identifier="iA" cardinality="single" baseType="integer" mathVariable="true"/>

   <!-- TEMPLATE PROCESSING -->
   <templateProcessing>
      <!-- Here template variables are assigned values, constraints are defined etc -->
   </templateProcessing>

   <!-- ITEM BODY -->
   <itemBody>
      <!-- The itemBody contains the content of the item, including the question, interactions, feedback sections (which are initially hidden) etc  -->
   </itemBody>

   <!-- RESPONSE PROCESSING -->
   <responseProcessing>
      <!-- Here the user's response is assessed, compared the correct answer etc, and outcome variable, e.g. score and which feedback to show, are set -->
   </responseProcessing>
</assessmentItem>

Maths with QTI – Help Guide for Maths Entry Questions

This is intended as a simple guide to entering mathematical expressions as answers to questions delivered using QTIWorks. Any comments about its usefulness/helpfulness would be most welcome.

Note that you can also view an input hints box by clicking on the blue question mark symbol help_questionmark next to the maths input box. You can also watch a brief video showing you how to enter mathematical answers.

This guide contains the following sections:

The Maths Input box ^ Top

When a mathematical expression is required as an answer to a question, a text box within a larger grey box is shown. When text is typed into the text box, it is interpreted mathematically, and the resulting mathematical expression is shown:

mathsinputbox_mod

If you click on the blue question mark symbol help_questionmark, an input hints box will pop up.

Basic Operators (+ – * / =) ^ Top

The basic mathematical operators can be represented by words or symbols, as shown in the table below.

Operation Symbol Word
Addition +
Subtraction
Multiplication * times
Division / divide
Equals =

note that multiplication is implied between a coefficient and a variable, e.g. 2x = 2*x, and between consecutive variables, i.e. letters, unless the letters make up a special character, e.g. pa = p*a, but pi = π, not p*i.

Other Operators (± > ≥ < ≤ ≠) ^ Top

Other operatores, e.g. comparison operators, can be represented as shown in the table below.

Operation Input Interpretation
Plus or minus +- ±
Greater than > >
Greater than or equal to >=
Less than < <
Less than or equal to <=
Not equal !=

Precedence (order of operations) ^ Top

The order of precedence, i.e. the order in which operations are performed/interpreted, follows the usual rules:

  1. brackets
  2. roots and exponentials
  3. multiplication and division
  4. addition and subtraction
Input Interpretation Notes
2+3*4 precedence_nobrackets equals 14
2+(3*4) precedence_unnecessarybrackets equals 14, brackets are unnecessary
(2+3)*4 precedence_brackets equals 20, brackets are required

Special Symbols and Functions ^ Top

Generally, letters just represent variables, and multiplication between consecutive letters is implied (see Basic Operations above). However, there are certain letters or words that have special meaning, as follows:

Letter/Word Meaning
e e, the natural exponential, 2.71828…
i the imaginary number, √-1
alpha…lambda…pi…etc Greek letters, α, λ, π etc
log logarithm function
ln natural logarithm function
sin, cos, tan trigonometric functions
cap, cup, in, not, notin, subset, subseteq, to,
vee, wedge…and probably others
Logic and Set Theory operators

Fractions (a/b) ^ Top

Use the divide symbol,  ‘/’, between the numerator (top) denominator (bottom) of a fraction. Brackets may be needed to give the correct numerator and denominator.

Input Interpretation
1/2 half
2x+1/3x+2 fraction_no_brackets
(2x+1)/(3x+2) fraction_brackets

Brackets (a(b+c)) ^ Top

Brackets can be used as they normally would when writing an expression.

Input Interpretation Notes
sin(2x+30)  brackets_sin  brackets not needed for sin of single value, e.g. sinx gives sinx
5(x+1)(2x-3)  brackets_2
3(2x-(2-y))  brackets_nested equivalent to 3(2x-2+y)

Powers (x^a) ^ Top

Use ^ (hat/caret symbol) to represent powers:

Input Interpretation Notes
x^2 powers_xsquared    
x^(1/3) powers_xtothird fractional powers need brackets
x^-1 powers_xtominus1 negative powers do not need brackets
e^(x(2x+1)) powers_expbrackets
e^x(2x+1) powers_expnobrackets

Roots (sqrt(x) or x^(a/b)) ^ Top

Only a square root can be represented with the root symbol. All other roots must be represented as fractional powers:

Root Input Interpretation
Square root (√x) sqrtx or sqrt(x) roots_sqrtx
Cube root (∛x) x^(1/3) roots_cubertx

Subscripts (x_a) ^ Top

Use _ (underscore) to give a subscript (similar to using ^ for powers/superscripts)

Input Interpretation
x_1 subscript_x_1
y_a subscript_y_a

“Sorry, I could not make sense of your input” ^ Top

You will see this message in a number of situations (including, but not limited to):

  • When you have an operator (e.g. + – * / ^ _ =), that does not have a value/variable before and/or after it, e.g. ‘1+’, ‘*3’, ‘x/’, ‘y^’
  • When you have two consecutive operators, e.g. ‘+*’
  • When you have opened a bracket and not (yet) closed it, e.g. ‘2(x+3’

If you see this message when you believe you have entered a complete expression, make sure you check your expression carefully, in particular that you have closed all brackets.

Getting excited by maths handling in MathAssessEngine

Just been trying out some sample QTIv2.1 questions sent to me by Dr Sue Milne from ELandWeb Ltd which address some issues with maths in online assessment that we have been struggling with for some time:

  • How do we allow students to choose the units in which they answer a numeric question?
  • How do we allow students to answer an algebraic question with an algebraic answer?
  • How can we randomise the values presented whilst testing the same mathematical concept from student to student and from attempt to attempt (to allow students to retest themselves)?
The answer appears to be that what we need is MathAssessEngine from the University of Edinburgh and QTIv2.1 .
Answering questions with algebra
Answering a question with algebra in MathAssessEngine
We haven’t yet had time to look at this is any great detail but these two examples demonstrate that there is a whole new world of assessments out there waiting to be explored.
qtiv21_examples contains two examples:
Example 1  (SineRule-002-mathOpWithSol.xml): Demonstrates a question that ‘understands’ units and the impact they will have on the expected answer
Example 2 (mela012252.xml): Demonstrates answering a question with algebra – in this case ‘sqrt’.  As the participant types, the answer the computer will mark is displayed in MathML.
Both questions randomise the variables shown each time you retake the question. To give them a go yourself, unzip the file then visit MathAssessEngine. ‘Choose file’ under ‘Upload Assessment Items and Tests’ and click ‘Go’.

 

The Curious Case of the Disappearing Image

During our first live test of Rogo, we were somewhat alarmed when the students pointed out that one of the questions was missing an image. Although far from ideal, it was thankfully not disastrous, as it was noticed fairly early on and we were able to print out a copy of the image for all the students.

The question is, what happened to this image? The paper was checked thoroughly against the QuestionMark Perception version of the paper immediately after it was imported, so it would have been spotted at that point had it not come through in the import. However, I clearly did not check the paper thoroughly enough immediately before the exam, as the image was not there.

So the image was lost from the question between it being imported into Rogo and the paper being taken. To find out when and why, I reimported just this question. The image is there in the QTI XML export from Perception, and was there in the question immediately after import. However, after saving the question from the edit screen, without having made any changes to the question, the image had disappeared. The table cell that should contain the image was left just containing an &nbsp;.

We presumed there was something in the imported HTML that was causing this to occur. Initially we thought it might be that there was no closing tag for the <IMG …> (nor a closing slash at the end of the tag), but adding this made no difference, and there were other questions that have the same lack of closing tag and there were no problems with these. On closer inspection of the html for the questions, we noticed that there was a span in the question intro in the faulty question that was not there in any others. This span contained some attributes that came from MS Word:

<SPAN style=”mso-bidi-font-family: Arial; mso-hansi-font-family: Arial” lang=EN-GB><STRONG>diaphragm <BR></STRONG></SPAN>

Removing the span altogether fixed the problem, so we drilled down in order to identify what aspect of the tags was causing it. We looked into the following:

  • The <br> inside span the span? Moving it outside made no difference
  • No quotation marks around EN-GB? Adding them made no difference
  • The lang attribute? Removing it made no difference
  • Non-standard CSS properties in style attribute? Removing the styles fixed the problem

Although it is nice to have found the specific cause, there is no reason for this span to exist at all, so we have removed it completely from the imported version. Hopefully questions containing spans such as this will be few and far between, but since many questions are copied in from Word, care needs to be taken, as it seems that the Rogo text editor, not unusually, does not like them.

For future imports, a quick find/replace through the QTI XML exports when we transfer questions en masse from Perception to Rogo should enable us to remove problematic spans. We will have to do some modification of the XML anyway (e.g. changing the path to images), so it will not be much more work to sort this out as well. I have also blogged about other issues relating to importing questions.

Importing Questions into Rogo

In preparation for our first running our first live test of Rogo, we needed to get an exam paper that had been created in Questionmark Perception into Rogo. This seemed simple enough, simply by exporting the QTI XML from Perception and importing it into Rogo. This generally worked reasonably well, but there were a few issues that had to be dealt with:

  • Not unsurprisingly, images needed special attention. The links to the images in Perception (e.g. “%SERVER.GRAPHICS%topicresources/1065007843”, where the number at the end is the topic id) were replaced (using a blanket find/replace) with “/media(/subdirectorypath)”, and the images copied into the appropriate subdirectory.
  • There were some issues with tables where an image was shown side by side with the answer options, which required a hack in Perception. For some questions there were problems in the HTML in Perception (left over from the dark ages), so fixing the HTML in Perception fixed the import problems relating to this.
  • EMQ feedback – the general question feedback from Perception is given as the feedback for all stems in Rogo, which does not have general feedback for EMQs. This can be fixed by removing the feedback from all except the last question, so that it just appears at the end of the responses. Alternatively, the feedback can be split up to give each stem its own feedback. Either of these options would be laborious for large numbers of questions, so the best long-term alternative may be to alter the import code to deal with this.
  • MCQ feedback – when importing MCQs (including those created in Rogo, exported and imported back in without any modification), in which only general feedback is provided, the general feedback is put in the answer feedback for each answer and general feedback is left empty. This has been added to the Rogo Trac system (#683,  https://suivarro.nottingham.ac.uk/trac/rogo/ticket/683)
  • Correct answers for EMQs – after importing all the correct answers are set to A. This is also the case if a question is created in Rogo, exported from Rogo and imported back in. This issue was added to Trac (#682, https://suivarro.nottingham.ac.uk/trac/rogo/ticket/682) and has now been fixed by the Rogo team, presumably for a future release. For this assessment, fixing this was simply, but annoyingly, a case of going through all the questions and changing the correct answers.
  • Rogo does not have a multiple MCQ question type, i.e. several MCQs that share the same stimulus and so are combined into a single question, so that it looks like an EMQ, but there are different answer options for each stem. Such questions are recognised as Matrix questions by Rogo when they are imported, but this format is not appropriate. There is no way of modifying an EMQ in Rogo so that subsets of the answer options are only available for certain stems. We have a large number of questions of this format, and currently the only option is to separate them out into MCQs, which is not a sustainable solution. Therefore, we may need to create a multiple MCQ question type, which hopefully would not be too difficult using the EMQ question type as the basis.

Having fixed all these problems, it seemed as though we had an exact copy of the assessment, with everything working as it should. The only difference between the questions as far as the students were concerned was that the multiple MCQ question (there was only one of this type in this paper) was split into 5 separate MCQs.

However, while running the assessment, we were to come across the Curious Case of the Disappearing Image, which, it turned out, was caused by a problem related to importing.