STACK questions with AI Feedback

Interactive practice on Quarto teaching pages

Bring selected Moodle STACK questions to a teaching website. Learners practise in their browser, see how their answers are interpreted, and can request guided AI Feedback alongside the question’s mathematical grading. The exported XML, scoring rules and author tests remain available for inspection.

Quarto turns plain-text teaching material into web pages. CTM STACK adds interactive question cards to those pages for publication as a static site.

For teachers

Try a question

Expand and collect the polynomial below. An equivalent factored answer earns partial credit. Press Validate answers to inspect your expression, then Check answer to grade it. Change the variant to try fresh coefficients. The AI Feedback panel offers guided hints and explanations; it does not replace the question’s scoring. Review controls let authors replay the question’s own tests.

Expand and collect like terms: \((x+{3})(x+{4})\).

Give your answer as a polynomial in \(x\).

Show source
```{.stack-question}
#| label: index-expand-a-product-form-sensitive
#| file: questions/polynomial-expansion.xml
#| question: Expand a product (form-sensitive)
#| variants: 3
#| review: true
#| feedback: true
```
Show STACK source
<?xml version="1.0" encoding="UTF-8"?>
<!-- Example question authored by the CTM team. Licensed under CC BY-SA 4.0. -->
<quiz>
  <question type="stack">
    <name>
      <text>Expand a product (form-sensitive)</text>
    </name>
    <questiontext format="html">
      <text>&lt;p&gt;Expand and collect like terms: \((x+{@a@})(x+{@b@})\).&lt;/p&gt;&lt;p&gt;Give your answer as a polynomial in \(x\). [[input:ans]] [[validation:ans]] [[feedback:prt1]]&lt;/p&gt;</text>
    </questiontext>
    <generalfeedback format="html">
      <text>&lt;p&gt;Multiply each term and collect: \(x^2+({@a@}+{@b@})x+{@a@}\cdot{@b@}={@ta@}\).&lt;/p&gt;&lt;p&gt;A factored expression has the same value, but this task asks for expanded form.&lt;/p&gt;</text>
    </generalfeedback>
    <defaultgrade>1</defaultgrade>
    <penalty>0.1</penalty>
    <hidden>0</hidden>
    <idnumber/>
    <stackversion>
      <text>2021072200</text>
    </stackversion>
    <questionvariables>
      <text>a:rand(4)+2;
b:rand(3)+2;
ta:x^2+(a+b)*x+a*b;</text>
    </questionvariables>
    <specificfeedback format="html">
      <text>&lt;p&gt;[[feedback:prt1]]&lt;/p&gt;</text>
    </specificfeedback>
    <questionnote format="moodle_auto_format">
      <text>Expansion: (x+a)(x+b) = ta</text>
    </questionnote>
    <questiondescription format="moodle_auto_format">
      <text/>
    </questiondescription>
    <questionsimplify>1</questionsimplify>
    <assumepositive>0</assumepositive>
    <assumereal>0</assumereal>
    <scientificnotation>*10</scientificnotation>
    <multiplicationsign>none</multiplicationsign>
    <sqrtsign>1</sqrtsign>
    <complexno>i</complexno>
    <inversetrig>cos-1</inversetrig>
    <logicsymbol>lang</logicsymbol>
    <matrixparens>[</matrixparens>
    <isbroken>0</isbroken>
    <variantsselectionseed/>
    <input>
      <name>ans</name>
      <type>algebraic</type>
      <tans>ta</tans>
      <boxsize>18</boxsize>
      <strictsyntax>1</strictsyntax>
      <insertstars>1</insertstars>
      <syntaxhint/>
      <syntaxattribute>0</syntaxattribute>
      <forbidwords/>
      <allowwords/>
      <forbidfloat>1</forbidfloat>
      <requirelowestterms>0</requirelowestterms>
      <checkanswertype>1</checkanswertype>
      <mustverify>1</mustverify>
      <showvalidation>1</showvalidation>
      <options/>
    </input>
    <prt>
      <name>prt1</name>
      <value>1.0000000</value>
      <autosimplify>0</autosimplify>
      <feedbackstyle>1</feedbackstyle>
      <feedbackvariables>
        <text/>
      </feedbackvariables>
      <node>
        <name>0</name>
        <description/>
        <answertest>EqualComAss</answertest>
        <sans>ans</sans>
        <tans>ta</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>=</truescoremode>
        <truescore>1.0000000</truescore>
        <truepenalty/>
        <truenextnode>-1</truenextnode>
        <trueanswernote>prt1-0-T</trueanswernote>
        <truefeedback format="html">
          <text>&lt;p&gt;Correct: the expression is expanded and collected.&lt;/p&gt;</text>
        </truefeedback>
        <falsescoremode>=</falsescoremode>
        <falsescore>0.0000000</falsescore>
        <falsepenalty/>
        <falsenextnode>1</falsenextnode>
        <falseanswernote>prt1-0-F</falseanswernote>
        <falsefeedback format="html">
          <text/>
        </falsefeedback>
      </node>
      <node>
        <name>1</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>ans</sans>
        <tans>ta</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>=</truescoremode>
        <truescore>0.5000000</truescore>
        <truepenalty/>
        <truenextnode>-1</truenextnode>
        <trueanswernote>prt1-1-T</trueanswernote>
        <truefeedback format="html">
          <text>&lt;p&gt;This is equivalent, but expand the product and collect like terms for full credit.&lt;/p&gt;</text>
        </truefeedback>
        <falsescoremode>=</falsescoremode>
        <falsescore>0.0000000</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt1-1-F</falseanswernote>
        <falsefeedback format="html">
          <text>&lt;p&gt;Check the middle term and constant term when you multiply the binomials.&lt;/p&gt;</text>
        </falsefeedback>
      </node>
    </prt>
    <deployedseed>17</deployedseed>
    <deployedseed>29</deployedseed>
    <deployedseed>47</deployedseed>
    <qtest>
      <testcase>1</testcase>
      <description>Expanded polynomial</description>
      <testinput>
        <name>ans</name>
        <value>ta</value>
      </testinput>
      <expected>
        <name>prt1</name>
        <expectedscore>1.0000000</expectedscore>
        <expectedpenalty>0.0000000</expectedpenalty>
        <expectedanswernote>prt1-0-T</expectedanswernote>
      </expected>
    </qtest>
    <qtest>
      <testcase>2</testcase>
      <description>Equivalent but still factored</description>
      <testinput>
        <name>ans</name>
        <value>(x+a)*(x+b)</value>
      </testinput>
      <expected>
        <name>prt1</name>
        <expectedscore>0.5000000</expectedscore>
        <expectedpenalty>0.1000000</expectedpenalty>
        <expectedanswernote>prt1-0-F | prt1-1-T</expectedanswernote>
      </expected>
    </qtest>
    <qtest>
      <testcase>3</testcase>
      <description>Incorrect middle coefficient</description>
      <testinput>
        <name>ans</name>
        <value>x^2+(a+b+1)*x+a*b</value>
      </testinput>
      <expected>
        <name>prt1</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty>0.1000000</expectedpenalty>
        <expectedanswernote>prt1-0-F | prt1-1-F</expectedanswernote>
      </expected>
    </qtest>
  </question>
</quiz>

Download this STACK XML · Try more questions

What is supported?

Teaching task What to try next
Equivalent algebra or a required written form Rational and form-sensitive questions
A measured number with tolerance or reported decimal places Numerical questions
Polynomial equations or Boolean propositions Equations and logic
Ordered lists, sets and nested finite collections Collection questions
A particular matrix, any basis, or a matrix meeting conditions Matrix examples and choosing an answer test
Another authored condition, such as positive definiteness Live positive-definiteness question and its authoring walkthrough

These activities cover a defined part of STACK. The authoring guide maps teaching tasks to supported tests; its developer reference records precise input, expression and grading limits. The question corpus shows which unchanged imports currently run and which need author attention.

Use your own question

  1. Export a supported question from Moodle as STACK XML.
  2. Add CTM STACK to a Quarto project and embed the named question in a page.
  3. Run its author tests, render the site and inspect an alternate correct and an incorrect answer before publishing.

The authoring guide gives the installation steps, embedding example and AI Feedback setup. For a question asking for any basis or any matrix with a chosen property, start with Python answer tests. A native Moodle STACK version of a Python-only question needs equivalent Maxima checks.

For developers

Explore the port

The existing STACK answer-test families implemented here are AlgEquiv, Sets, SameType, EqualComAss, FacForm, SingleFrac, LowestTerms, NumAbsolute, NumRelative and NumDecPlaces. The Python-only PythonChecker test uses shared matrix predicates or an author-written function for tasks such as alternate bases and matrix conditions. Ordinary response trees still control scores and feedback.