From bcca1d12e76910dab0dd0ff470b7cba0087e4979 Mon Sep 17 00:00:00 2001 From: Christian Lawson-Perfect Date: Fri, 27 Sep 2024 16:24:07 +0100 Subject: [PATCH] use `numbas.review_allowed` from SCORM to decide whether to enter review mode on resuming a finished attempt --- runtime/scripts/exam.js | 4 +- runtime/scripts/scorm-storage.js | 9 ++ runtime/scripts/storage.js | 5 + tests/locales.js | 19 +-- tests/numbas-runtime.js | 234 ++++++++++++++++++------------- tests/parts/part-tests.mjs | 95 ++++++++++--- tests/parts/part_unit_tests.mjs | 2 +- tests/parts/scorm_api.mjs | 4 + 8 files changed, 247 insertions(+), 125 deletions(-) diff --git a/runtime/scripts/exam.js b/runtime/scripts/exam.js index 923365a13..5f1e53e90 100644 --- a/runtime/scripts/exam.js +++ b/runtime/scripts/exam.js @@ -291,7 +291,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { 'allowrevealanswer', 'advicethreshold', ], - exam, + settings, [ 'showActualMark', 'showTotalMark', @@ -1346,7 +1346,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { //display the results - var revealAnswers = this.settings.enterReviewModeImmediately || this.entry == 'review' || Numbas.is_instructor; + var revealAnswers = this.settings.enterReviewModeImmediately || (this.entry == 'review' && this.store.reviewModeAllowed()) || Numbas.is_instructor; for(var i=0;iOne or more subsequent parts depend on your answer to this part. Submitting this part again will invalidate those parts, and remove them from the question. This cannot be undone.

\n

Would you like to submit this part again?

", "control.proceed anyway": "Proceed anyway?", "control.regen": "Try another question like this one", - "control.submit answer": "Submit answer", - "control.submit all parts": "Submit all parts", - "control.submit again": "Submit again", - "control.submit": "Submit", + "control.submit answer": "Save answer", + "control.submit all parts": "Save all answers", "control.previous": "Previous", "control.next": "Next", "control.advice": "Advice", @@ -1718,7 +1716,7 @@ Numbas.locale = { "part.marking.maximum scaled down": "The maximum you can score for this part is {{count,niceNumber}} $t(mark). Your scores will be scaled down accordingly.", "part.marking.used variable replacements": "This part was marked using your answers to previous parts.", "part.marking.variable replacement part not answered": "You must answer {{part}} first.", - "part.marking.resubmit because of variable replacement": "This part's marking depends on your answers to other parts, which you have changed. Submit this part again to update your score.", + "part.marking.resubmit because of variable replacement": "This part's marking depends on your answers to other parts, which you have changed. Save your answer to this part again to update your score.", "part.marking.not submitted": "No answer submitted.", "part.marking.did not answer": "You did not answer this question.", "part.marking.total score": "You scored {{count,niceNumber}} $t(mark) for this part.", @@ -1750,8 +1748,11 @@ Numbas.locale = { "part.missing type attribute": "{{part}}: Missing part type attribute", "part.unknown type": "{{part}}: Unrecognised part type {{type}}", "part.setting not present": "Property '{{property}}' not set", - "part.feedback out of date": "This feedback is based on your last submitted answer. Submit your changed answer to get updated feedback.", + "part.feedback out of date": "This feedback is based on your last submitted answer. Save your changed answer to get updated feedback.", "part.input title": "Answer for part {{name}}", + "part.show feedback": "Show feedback", + "part.hide feedback": "Hide feedback", + "part.feedback title": "Feedback for {{name}}.", "part.correct answer title": "Expected answer for part {{name}}", "part.waiting for pre submit": "Your answer is being marked. Please wait.", "part.jme.answer missing": "Correct answer is missing", @@ -1778,6 +1779,7 @@ Numbas.locale = { "part.numberentry.answer invalid": "You did not enter a valid number.", "part.numberentry.answer not reduced": "Your answer is not reduced to lowest terms.", "part.numberentry.give your answer as a reduced fraction": "Reduce your answer to lowest terms.", + "part.numberentry.write your answer as a fraction": "Write your answer as a fraction.", "part.numberentry.answer not integer": "Your answer is invalid. You must enter a whole number, not a decimal.", "part.numberentry.answer not integer or decimal": "Your answer is invalid. You must enter an integer or a decimal.", "part.numberentry.answer not integer or decimal or fraction": "Your answer is invalid. You must enter an integer, a decimal or a fraction.", @@ -1837,6 +1839,7 @@ Numbas.locale = { "question.header": "Question {{number}}", "question.submit part": "Save answer", "question.answer saved": "Answer saved", + "question.all answers saved": "All answers saved", "question.show steps": "Show steps", "question.show steps penalty": "You will lose {{count,niceNumber}} $t(mark).", "question.show steps no penalty": "Your score will not be affected.", @@ -1849,8 +1852,8 @@ Numbas.locale = { "question.no such part": "Can't find part {{path}}.", "question.can not submit": "Can not submit answer - check for errors.", "question.answer submitted": "Answer submitted", - "question.unsubmitted changes": "You have made a change to your answer but not submitted it. Please check your answer and then press the Submit answer button.", - "question.unsubmitted changes_plural": "You have made changes to your answers but not submitted them. Please check your answers to each part and then press the Submit all parts button.", + "question.unsubmitted changes": "You have made a change to your answer but not submitted it. Please check your answer and then press the Save answer button.", + "question.unsubmitted changes_plural": "You have made changes to your answers but not submitted them. Please check your answers to each part and then press the Save all answers button.", "question.score feedback.show": "Show feedback", "question.score feedback.hide": "Hide feedback", "question.score feedback.not marked": "Not marked", diff --git a/tests/numbas-runtime.js b/tests/numbas-runtime.js index 81a8d5c86..f53f79b6d 100644 --- a/tests/numbas-runtime.js +++ b/tests/numbas-runtime.js @@ -21526,13 +21526,7 @@ if(res) { \ }; this.question && this.question.updateScore(); - if(this.answered) - { - if(!(this.parentPart && this.parentPart.type=='gapfill') && this.settings.showFeedbackIcon && this.marks!=0) { - this.markingComment( - R('part.marking.total score',{count:this.score}) - ); - } + if(this.answered) { if(this.display) { this.display.showScore(this.answered); } @@ -21990,18 +21984,15 @@ if(res) { \ action.message = ''; } if(change!=0) { - if(util.isNonemptyHTML(action.message)) { - action.message += '\n\n'; - } var marks = Math.abs(change); if(change>0) { - action.message += R('feedback.you were awarded',{count:marks}); + action.credit_message = R('feedback.you were awarded',{count:marks}); } else if(change<0) { - action.message += R('feedback.taken away',{count:marks}); + action.credit_message = R('feedback.taken away',{count:marks}); } } } - change_desc = credit_change>0 ? 'positive' : credit_change<0 ? 'negative' : 'neutral'; + change_desc = credit_change > 0 ? 'positive' : credit_change < 0 ? 'negative' : 'neutral'; switch(action.reason) { case 'correct': change_desc = 'positive'; @@ -22629,7 +22620,6 @@ var Question = Numbas.Question = function( number, exam, group, gscope, store) q.exam = exam; q.tags = []; q.group = group; - q.adviceThreshold = q.exam ? q.exam.adviceGlobalThreshold : 0; q.number = number; q.path = `q${this.number}`; gscope = gscope || (exam && exam.scope) || Numbas.jme.builtinScope; @@ -23683,8 +23673,7 @@ Question.prototype = /** @lends Numbas.Question.prototype */ * @param {Numbas.parts.partpath} path * @returns {Numbas.parts.Part} */ - getPart: function(path) - { + getPart: function(path) { var p = this.partDictionary[path]; if(!p) { this.error("question.no such part",{path:path}); @@ -23715,9 +23704,8 @@ Question.prototype = /** @lends Numbas.Question.prototype */ * @param {boolean} dontStore - Don't tell the storage that the advice has been shown - use when loading from storage! * @fires Numbas.Question#adviceDisplayed */ - getAdvice: function(dontStore) - { - if(!Numbas.is_instructor && this.exam && !this.exam.settings.reviewShowAdvice) { + getAdvice: function(dontStore) { + if(!Numbas.is_instructor && this.exam && this.exam.settings.revealAdvice == 'never') { return; } this.adviceDisplayed = true; @@ -23745,8 +23733,7 @@ Question.prototype = /** @lends Numbas.Question.prototype */ * @param {boolean} dontStore - Don't tell the storage that the advice has been shown - use when loading from storage! * @fires Numbas.Question#revealed */ - revealAnswer: function(dontStore) - { + revealAnswer: function(dontStore) { this.lock(); this.revealed = true; //display advice if allowed @@ -23770,13 +23757,11 @@ Question.prototype = /** @lends Numbas.Question.prototype */ * * @returns {boolean} */ - validate: function() - { + validate: function() { switch(this.partsMode) { case 'all': var success = true; - for(var i=0; i>} navigationEvents - checks to perform when doing certain navigation action * @property {Array.>} timerEvents - Events based on timing. * @property {number} duration - The time allowed for the exam, in seconds. * @property {number} duration_extension - A number of seconds to add to the duration. * @property {number} initial_duration - The duration without any extension applied. * @property {boolean} allowPause - Can the student suspend the timer with the pause button or by leaving? - * @property {boolean} showActualMark - Show the current score? - * @property {boolean} showTotalMark - Show total marks in exam? - * @property {boolean} showAnswerState - Tell student if answer is correct/wrong/partial? + * @property {string} showActualMark - When should the current score be shown? + * @property {string} showTotalMark - When should total marks in the exam be shown? + * @property {string} showAnswerState - When to tell the student if answer is correct/wrong/partial? + * @property {string} showPartFeedbackMessages - When to show part feedback messages? * @property {boolean} allowRevealAnswer - Allow 'reveal answer' button? * @property {boolean} showQuestionGroupNames - Show the names of question groups? - * @property {boolean} reviewShowScore - Show student's score in review mode? - * @property {boolean} reviewShowFeedback - Show part feedback messages in review mode? - * @property {boolean} reviewShowAdvice - Show question advice in review mode? + * @property {string} revealAdvice - When should question advice be shown? + * @property {string} revealExpectedAnswers - When should expected answers be shown? * @property {boolean} resultsprintquestions - Show questions in printed results? * @property {boolean} resultsprintadvice - Show advice in printed results? * @memberof Numbas.Exam @@ -24358,28 +24392,28 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { allowRegen: false, allowAttemptDownload: false, downloadEncryptionKey: '', + autoSubmit: true, navigateMode: 'menu', navigateReverse: false, navigateBrowse: false, allowSteps: true, showFrontPage: true, - showResultsPage: 'oncompletion', + enterReviewModeImmediately: true, navigationEvents: {}, timerEvents: {}, duration: 0, initial_duration: 0, allowPause: false, - showActualMark: false, - showTotalMark: false, - showAnswerState: false, + showActualMark: 'inreview', + showTotalMark: 'inreview', + showAnswerState: 'inreview', + showPartFeedbackMessages: 'inreview', allowRevealAnswer: false, showQuestionGroupNames: false, shuffleQuestionGroups: false, showStudentName: true, - reviewShowScore: true, - reviewShowFeedback: true, - reviewShowExpectedAnswer: true, - reviewShowAdvice: true, + revealAdvice: 'inreview', + revealExpectedAnswers: 'inreview', resultsprintquestions: true, resultsprintadvice: true, diagnosticScript: 'diagnosys', @@ -24723,6 +24757,15 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { } }, + /** Show the given info page. + * + * @param {string} page - The name of the page to show. + */ + showInfoPage: function(page) { + this.display && this.display.showInfoPage(page); + this.events.trigger('showInfoPage', page); + }, + /** * Show the question menu. * @@ -24733,8 +24776,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { return; } this.currentQuestion = undefined; - this.display && this.display.showInfoPage('menu'); - this.events.trigger('showInfoPage','menu'); + this.showInfoPage('menu'); }, /** Accept the given password to begin the exam? @@ -24770,8 +24812,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { this.display && this.display.showQuestion(); //display the current question break; case 'menu': - this.display && this.display.showInfoPage('menu'); - this.events.trigger('showInfoPage','menu'); + this.showInfoPage('menu'); break; case 'diagnostic': var question = this.diagnostic_controller.first_question(); @@ -24789,8 +24830,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { pause: function() { this.endTiming(); - this.display && this.display.showInfoPage('paused'); - this.events.trigger('showInfoPage','paused'); + this.showInfoPage('paused'); this.store && this.store.pause(); this.events.trigger('pause'); }, @@ -24808,8 +24848,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { this.display.showQuestion(); this.events.trigger('showQuestion'); } else if(this.settings.navigateMode=='menu') { - this.display.showInfoPage('menu'); - this.events.trigger('showInfoPage','menu'); + this.showInfoPage('menu'); } } this.events.trigger('resume'); @@ -25207,8 +25246,7 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { * @fires Numbas.Exam#event:end * @fires Numbas.Exam#event:showInfoPage */ - end: function(save) - { + end: function(save) { this.mode = 'review'; switch(this.settings.navigateMode) { case 'diagnostic': @@ -25240,31 +25278,21 @@ Exam.prototype = /** @lends Numbas.Exam.prototype */ { this.store && this.store.end(); } this.display && this.display.end(); + //display the results - var revealAnswers = false; - switch(this.settings.showResultsPage) { - case 'oncompletion': - revealAnswers = true; - break; - case 'review': - revealAnswers = this.entry == 'review'; - break; - default: - revealAnswers = false; - break; - } - if(Numbas.is_instructor) { - revealAnswers = true; - } + + var revealAnswers = this.settings.enterReviewModeImmediately || (this.entry == 'review' && this.store.reviewModeAllowed()) || Numbas.is_instructor; + for(var i=0;i
${R('matrix input.size control legend')} - - + +
diff --git a/tests/parts/part-tests.mjs b/tests/parts/part-tests.mjs index cce7add37..6b9e4eea6 100644 --- a/tests/parts/part-tests.mjs +++ b/tests/parts/part-tests.mjs @@ -158,7 +158,7 @@ Numbas.queueScript('part_tests',['qunit','json','jme','localisation','parts/numb var res = await mark_part(p,'1'); assert.ok(p.answered,'Part is answerd'); assert.equal(p.credit,1,'1 credit'); - assert.equal(p.markingFeedback[0].message,"Top marks!\n\nYou were awarded 1 mark.", 'Feedback message is "Top marks!" as set in script'); + assert.equal(p.markingFeedback[0].message,"Top marks!", 'Feedback message is "Top marks!" as set in script'); }); QUnit.module('Stateful scope'); @@ -500,7 +500,7 @@ Numbas.queueScript('part_tests',['qunit','json','jme','localisation','parts/numb "marks":1, "unitTests": [ {"variables":[],"name":"t/t is incorrect","answer":{"valid":true,"value":"t/t"},"notes":[{"name":"mark","expected":{"value":"nothing","messages":["Your answer is incorrect."],"warnings":[],"error":"","valid":true,"credit":0}}]}, - {"variables":[],"name":"t/T is correct","answer":{"valid":true,"value":"t/T"},"notes":[{"name":"mark","expected":{"value":"nothing","messages":["Your answer is numerically correct.\n\nYou were awarded 1 mark."],"warnings":[],"error":"","valid":true,"credit":1}}]} + {"variables":[],"name":"t/T is correct","answer":{"valid":true,"value":"t/T"},"notes":[{"name":"mark","expected":{"value":"nothing","messages":["Your answer is numerically correct."],"warnings":[],"error":"","valid":true,"credit":1}}]} ], "answer":"t/T", "caseSensitive":true, @@ -766,7 +766,7 @@ Numbas.queueScript('part_tests',['qunit','json','jme','localisation','parts/numb var g = q.getPart('p1g0'); g.storeAnswer('1'); await submit_part(p); - assert.equal(p.markingFeedback.map(f => f.message).join('\n'), "You must answer a) first.\nYou scored 0 marks for this part."); + assert.equal(p.markingFeedback.map(f => f.message).join('\n'), "You must answer a) first."); done(); } ); @@ -1171,7 +1171,8 @@ Numbas.queueScript('part_tests',['qunit','json','jme','localisation','parts/numb { "op": "add_credit", "credit": 0.5, - "message": "Your answer is correct.\n\nYou were awarded 0.5 marks.", + "message": "Your answer is correct.", + "credit_message": "You were awarded 0.5 marks.", "reason": "correct", "credit_change": "positive" }, @@ -1188,12 +1189,6 @@ Numbas.queueScript('part_tests',['qunit','json','jme','localisation','parts/numb "message": "Your answer is incorrect.", "reason": "incorrect", "credit_change": "negative" - }, - { - "op": "feedback", - "format": "string", - "message": "You scored 0.5 marks for this part.", - "reason": undefined } ] assert.deepEqual(p0.markingFeedback,expected_feedback); @@ -1436,7 +1431,7 @@ return new Promise(resolve => { p.storeAnswer('2'); p.submit(); assert.equal(p.credit,0.5,'0.5 credit for alternative answer'); - assert.equal(p.markingFeedback[0].message,'

You wrote 2.

\n\nYou were awarded 0.5 marks.'); + assert.equal(p.markingFeedback[0].message,'

You wrote 2.

'); } ); @@ -1462,7 +1457,6 @@ return new Promise(resolve => { p.storeAnswer('1'); p.submit(); assert.equal(p.credit,1,'1 credit for correct answer'); - assert.equal(p.markingFeedback[0].message,'You were awarded 1 mark.','Feedback says 1 mark awarded'); } ); @@ -1496,13 +1490,13 @@ return new Promise(resolve => { var p = q.parts[0]; p.storeAnswer('x'); p.submit(); - assert.equal(collect_feedback(p.markingFeedback),'Your answer is numerically correct.\n\nYou were awarded 1 mark.\nYou scored 1 mark for this part.'); + assert.equal(collect_feedback(p.markingFeedback),'Your answer is numerically correct.'); p.storeAnswer('y'); p.submit(); - assert.equal(collect_feedback(p.markingFeedback),'

You wrote y

\n\nYou were awarded 0.5 marks.\nYou scored 0.5 marks for this part.'); + assert.equal(collect_feedback(p.markingFeedback),'

You wrote y

'); p.storeAnswer('z'); p.submit(); - assert.equal(collect_feedback(p.markingFeedback),'Your answer is numerically correct.\n\nYou were awarded 0.5 marks.\n

You wrote z

\nYou scored 0.5 marks for this part.'); + assert.equal(collect_feedback(p.markingFeedback),'Your answer is numerically correct.\n

You wrote z

'); } ); @@ -2116,7 +2110,6 @@ next_actions: "event: post-mark", "event: post-markAdaptive", "event: calculateScore", - "event: markingComment", "event: post-submit" ], 'submitting a correct answer'); assert.equal(part.credit,1); @@ -2250,7 +2243,6 @@ pre_submit: "event: post-mark", "event: post-markAdaptive", "event: calculateScore", - "event: markingComment", "event: post-submit", "event: completed_pre_submit" ], 'once pre-submit tasks are done'); @@ -2296,7 +2288,6 @@ mark: "event: post-mark", "event: post-markAdaptive", "event: calculateScore", - "event: markingComment", "event: post-submit" ]); @@ -3051,4 +3042,72 @@ next_actions: done(); }); + + QUnit.test('Resume a completed exam without review allowed',async function(assert) { + var done = assert.async(); + var exam_def = { + name: "Exam", + question_groups: [ + { + questions: [ + { + name: "Q", + parts: [{type:'numberentry',minvalue:'1',maxvalue:'1',marks:1}] + } + ] + } + ], + feedback: { + enterreviewmodeimmediately: false, + } + }; + + const [run1,run2, run3] = await with_scorm( + async function() { + var e = Numbas.createExamFromJSON(exam_def,Numbas.store,false); + e.init(); + await e.signals.on('ready'); + e.begin(); + const q = e.questionList[0]; + const p = q.getPart('p0'); + await mark_part(p,"1"); + e.tryEnd(); + assert.notOk(e.revealed, "The exam is not in review mode."); + }, + + async function(data, results, scorm) { + scorm.SetValue('numbas.review_allowed', 'false'); + var e = Numbas.createExamFromJSON(exam_def,Numbas.store,false); + e.entry = 'review'; + e.load(); + e.end(); + await e.signals.on('ready'); + assert.notOk(e.revealed, "The exam is not in review mode."); + }, + + async function(data, results, scorm) { + scorm.SetValue('numbas.review_allowed', 'true'); + var e = Numbas.createExamFromJSON(exam_def,Numbas.store,false); + e.entry = 'review'; + e.load(); + e.end(); + await e.signals.on('ready'); + assert.ok(e.revealed, "The exam is in review mode."); + }, + + async function(data, results, scorm) { + scorm.DeleteValue('numbas.review_allowed'); + var e = Numbas.createExamFromJSON(exam_def,Numbas.store,false); + e.entry = 'review'; + e.load(); + e.end(); + await e.signals.on('ready'); + assert.ok(e.revealed, "The exam is in review mode."); + } + ); + + + done(); + }); + }); diff --git a/tests/parts/part_unit_tests.mjs b/tests/parts/part_unit_tests.mjs index a14421c78..faf3924cb 100644 --- a/tests/parts/part_unit_tests.mjs +++ b/tests/parts/part_unit_tests.mjs @@ -1,5 +1,5 @@ export const unit_test_exam = // Numbas version: exam_results_page_options -{"name": "Part unit tests", "extensions": [], "question_groups": [{"questions": [{"name": "Choose one from a list part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [[true], [false], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "Incorrect", "answer": {"valid": true, "value": [[false], [true], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose an incorrect answer."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3"], "matrix": ["1", 0, 0], "distractors": ["", "", ""]}, {"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Minimum score zero", "answer": {"valid": true, "value": [[false], [true], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose an incorrect answer.", "","1 mark was taken away.","The minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3"], "matrix": ["1", "-1", 0], "distractors": ["", "", ""]}, {"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [[true], [false], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": "map(\"Choice \"+n,n,1..3)", "matrix": "[1,0,0]"}]}, {"name": "Choose several from a list part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "m_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "One correct choice", "answer": {"valid": true, "value": [[true], [false], [false], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}, {"variables": [], "name": "Both correct choices", "answer": {"valid": true, "value": [[true], [true], [false], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "One correct, one incorrect", "answer": {"valid": true, "value": [[true], [false], [true], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose an incorrect answer.\n\n1 mark was taken away."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "All but choice 2", "answer": {"valid": true, "value": [[true], [false], [true], [true], [true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.\nYou chose an incorrect answer.\n\n1 mark was taken away.\nYou chose an incorrect answer.\n\n1 mark was taken away.\nYou chose an incorrect answer.\n\n1 mark was taken away.\nThe minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "checkbox", "displayColumns": 0, "minAnswers": 0, "maxAnswers": 0, "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3", "Choice 4", "Choice 5"], "matrix": ["1", "1", "-1", "-1", "-1"], "distractors": ["", "", "", "", ""]}, {"type": "m_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "First two choices", "answer": {"valid": true, "value": [[true], [true], [false], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 2 marks."], "warnings": [], "error": "", "valid": true, "credit": 0.6}}]}, {"variables": [], "name": "Choices 2 and 3", "answer": {"valid": true, "value": [[false], [true], [true], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 2 marks.", "You chose a correct answer.\n\nYou were awarded 3 marks."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "checkbox", "displayColumns": 0, "minAnswers": 0, "maxAnswers": "2", "warningType": "prevent", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3", "Choice 4", "Choice 5"], "matrix": ["1", "2", "3", "-1", "-1"], "distractors": ["", "", "", "", ""]}]}, {"name": "Match choices with answers part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Both correct choices", "answer": {"valid": true, "value": [[true, false], [false, true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "One right, one wrong", "answer": {"valid": true, "value": [[true, true], [false, false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose an incorrect answer.\n\n1 mark was taken away."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "Both wrong", "answer": {"valid": true, "value": [[false, true], [true, false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose an incorrect answer.\n\n1 mark was taken away.\nYou chose an incorrect answer.\n\n1 mark was taken away.\nThe minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": false, "shuffleAnswers": false, "displayType": "radiogroup", "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2"], "matrix": [["1 ", "-1"], ["-1", "1"]], "layout": {"type": "all", "expression": ""}, "answers": ["Answer 1", "Answer 2"]}, {"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "All correct answers", "answer": {"valid": true, "value": [[true, true], [true, false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "Incorrect answer", "answer": {"valid": true, "value": [[false, true], [true, true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.\nYou chose a correct answer.\n\nYou were awarded 1 mark.\nYou chose an incorrect answer.\n\n3 marks were taken away.\nThe minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": false, "shuffleAnswers": false, "displayType": "checkbox", "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2"], "matrix": [["1", "1"], ["1", "-3"]], "layout": {"type": "all", "expression": ""}, "answers": ["Answer 1", "Answer 2"]}, {"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "All correct answers", "answer": {"valid": true, "value": [[true, false, false], [true, true, false], [true, true, true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark.", "You chose a correct answer.\n\nYou were awarded 1 mark.", "The maximum score for this part is 3."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minMarks": 0, "maxMarks": "3", "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": false, "shuffleAnswers": false, "displayType": "checkbox", "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3"], "matrix": [["1", "1", "1"], ["1", "1", "1"], ["1", "1", "1"]], "layout": {"type": "uppertriangle", "expression": ""}, "answers": ["Answer 1", "Answer 2", "Answer 3"]}]}, {"name": "Match text pattern part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "patternmatch", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "\"thing!\" is correct", "answer": {"valid": true, "value": "thing!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "\"THING!\" is correct", "answer": {"valid": true, "value": "THING!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "thing!", "displayAnswer": "thing!", "matchMode": "exact"}, {"type": "patternmatch", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "\"thing!\" is correct", "answer": {"valid": true, "value": "thing!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "\"THING!\" is correct except for case", "answer": {"valid": true, "value": "THING!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "0.5", "messages": ["Your answer is correct, except for the case.\n\nYou were awarded 0.5 marks."], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}], "answer": "thing!", "displayAnswer": "thing!", "caseSensitive": true, "partialCredit": "50", "matchMode": "exact"}, {"type": "patternmatch", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "\"two words\" is correct", "answer": {"valid": true, "value": "two words", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "\"this thing!\" is incorrect", "answer": {"valid": true, "value": "this thing!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "false", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "answer": "\\w+ \\w+", "displayAnswer": "hello there", "matchMode": "regex"}]}, {"name": "Mathematical expression part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "x is correct", "answer": {"valid": true, "value": "x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "y is incorrect", "answer": {"valid": true, "value": "y"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "x+0 is correct", "answer": {"valid": true, "value": "x+0"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "x+0*y is correct", "answer": {"valid": true, "value": "x+0y"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "x", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "valuegenerators": [{"name": "x", "value": ""}]}, {"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "2x is correct", "answer": {"valid": true, "value": "2x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "x+x gets a penalty", "answer": {"valid": true, "value": "x+x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark.", "Your answer is not in the expected form: Should be number times x\n\n0.5 marks were taken away."], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}, {"variables": [], "name": "3x is wrong", "answer": {"valid": true, "value": "3x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "x+x+x is wrong and gets warning", "answer": {"valid": true, "value": "x+x+x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect.", "Your answer is not in the expected form: Should be number times x"], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "answer": "2x", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "mustmatchpattern": {"pattern": "$n*x", "partialCredit": "50", "message": "Should be number times x", "nameToCompare": ""}, "valuegenerators": [{"name": "x", "value": ""}]}, {"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "x1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "x-y<0 is correct", "answer": {"valid": true, "value": "x-y<0"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "x=y is incorrect", "answer": {"valid": true, "value": "x=y"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "y>x is correct", "answer": {"valid": true, "value": "y>x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "x1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "y=x^2+2", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "valuegenerators": [{"name": "x", "value": ""}, {"name": "y", "value": ""}]}]}, {"name": "Matrix entry part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "matrix", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [["1", "2", "3"], ["4", "5", "6"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "Wrong size", "answer": {"valid": true, "value": [["1", "2"], ["3", "4"]]}, "notes": [{"name": "wrong_size", "expected": {"value": "true", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}, {"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "correctAnswer": "matrix([1,2,3],[4,5,6])", "correctAnswerFractions": false, "numRows": "2", "numColumns": "3", "allowResize": true, "tolerance": 0, "markPerCell": false, "allowFractions": false}, {"type": "matrix", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "correct", "answer": {"valid": true, "value": [["1/3", "0"], ["0", "1/3"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "2/6", "answer": {"valid": true, "value": [["2/6", "0"], ["0", "2/6"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "correctAnswer": "id(2)/3", "correctAnswerFractions": false, "numRows": "2", "numColumns": "2", "allowResize": true, "tolerance": 0, "markPerCell": false, "allowFractions": true}, {"type": "matrix", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [["0.71", "0.29"], ["0.57", "0.14"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "correctAnswer": "matrix([5,2],[4,1])/7", "correctAnswerFractions": false, "numRows": "2", "numColumns": "2", "allowResize": false, "tolerance": 0, "markPerCell": false, "allowFractions": false, "precisionType": "dp", "precision": "2", "precisionPartialCredit": "50", "precisionMessage": "You have not given your answer to the correct precision.", "strictPrecision": true}, {"type": "matrix", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "0.5 off still correct", "answer": {"valid": true, "value": [["0.5", "0.5"], ["1.5", "1.5"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "0 incorrect", "answer": {"valid": true, "value": [["1", "1"], ["1", "0"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "A variety of errors within tolerance", "answer": {"valid": true, "value": [["1.1", "1.2"], ["0.7", "0.9"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "correctAnswer": "matrix([1,1],[1,1])", "correctAnswerFractions": false, "numRows": "2", "numColumns": "2", "allowResize": true, "tolerance": "0.5", "markPerCell": false, "allowFractions": false}, {"type": "matrix", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [["1", "2"], ["3", "4"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "One incorrect cell", "answer": {"valid": true, "value": [["1", "2"], ["3", "3"]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["One or more of the cells in your answer is incorrect, but you have been awarded marks for the rest.\n\nYou were awarded 0.75 marks."], "warnings": [], "error": "", "valid": true, "credit": 0.75}}]}], "correctAnswer": "matrix([1,2],[3,4])", "correctAnswerFractions": false, "numRows": "2", "numColumns": "2", "allowResize": true, "tolerance": 0, "markPerCell": true, "allowFractions": false}]}, {"name": "Number entry part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {"sqrt2": {"name": "sqrt2", "group": "Ungrouped variables", "definition": "sqrt(dec(2))", "description": "", "templateType": "anything"}}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": ["sqrt2"], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "1 is correct", "answer": {"valid": true, "value": "1", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "0 is incorrect", "answer": {"valid": true, "value": "0", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minValue": "1", "maxValue": "1", "correctAnswerFraction": false, "allowFractions": false, "mustBeReduced": false, "mustBeReducedPC": 0, "showFractionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}, {"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "3.14 is correct", "answer": {"valid": true, "value": "3.14", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "3.140 is incorrect", "answer": {"valid": true, "value": "3.140", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minValue": "pi", "maxValue": "pi", "correctAnswerFraction": false, "allowFractions": false, "mustBeReduced": false, "mustBeReducedPC": 0, "precisionType": "dp", "precision": "2", "precisionPartialCredit": 0, "precisionMessage": "You have not given your answer to the correct precision.", "strictPrecision": true, "showPrecisionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}, {"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "1.2 is incorrect", "answer": {"valid": true, "value": "1.2", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark.", "You have not given your answer to the correct precision.\n\n1 mark was taken away."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "1.20 is correct", "answer": {"valid": true, "value": "1.20", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minValue": "1.2", "maxValue": "1.2", "correctAnswerFraction": false, "allowFractions": false, "mustBeReduced": false, "mustBeReducedPC": 0, "precisionType": "dp", "precision": "2", "precisionPartialCredit": 0, "precisionMessage": "You have not given your answer to the correct precision.", "strictPrecision": true, "showPrecisionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}, {"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "1 234,5 is correct", "answer": {"valid": true, "value": "1 234,5", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minValue": "1234.5", "maxValue": "1234.5", "correctAnswerFraction": false, "allowFractions": false, "mustBeReduced": false, "mustBeReducedPC": 0, "showFractionHint": true, "notationStyles": ["si-fr"], "correctAnswerStyle": "si-fr"}, {"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "6/7 is correct", "answer": {"valid": true, "value": "6/7", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "12/14 gets partial credit", "answer": {"valid": true, "value": "12/14", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark.", "Your answer is not reduced to lowest terms.\n\n0.5 marks were taken away."], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}], "minValue": "6/7", "maxValue": "6/7", "correctAnswerFraction": false, "allowFractions": true, "mustBeReduced": true, "mustBeReducedPC": "50", "showFractionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}, {"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [{"name": "sqrt2", "value": "dec(\"1.41421356237309504880168872420969807857e+0\")"}], "name": "1.414213562373095", "answer": {"valid": true, "value": "1.414213562373095", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is correct.\n\nYou were awarded 1 mark."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minValue": "sqrt2", "maxValue": "sqrt2", "correctAnswerFraction": false, "allowFractions": false, "mustBeReduced": false, "mustBeReducedPC": 0, "precisionType": "dp", "precision": "15", "precisionPartialCredit": 0, "precisionMessage": "You have not given your answer to the correct precision.", "strictPrecision": true, "showPrecisionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}]}]}]}; +{"name": "Part unit tests", "extensions": [], "question_groups": [{"questions": [{"name": "Choose one from a list part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [[true], [false], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "Incorrect", "answer": {"valid": true, "value": [[false], [true], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose an incorrect answer."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3"], "matrix": ["1", 0, 0], "distractors": ["", "", ""]}, {"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Minimum score zero", "answer": {"valid": true, "value": [[false], [true], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose an incorrect answer.", "The minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3"], "matrix": ["1", "-1", 0], "distractors": ["", "", ""]}, {"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Correct", "answer": {"valid": true, "value": [[true], [false], [false]], "empty": false}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": "map(\"Choice \"+n,n,1..3)", "matrix": "[1,0,0]"}]}, {"name": "Choose several from a list part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "m_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "One correct choice", "answer": {"valid": true, "value": [[true], [false], [false], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}, {"variables": [], "name": "Both correct choices", "answer": {"valid": true, "value": [[true], [true], [false], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "One correct, one incorrect", "answer": {"valid": true, "value": [[true], [false], [true], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose an incorrect answer."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "All but choice 2", "answer": {"valid": true, "value": [[true], [false], [true], [true], [true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\nYou chose an incorrect answer.\nYou chose an incorrect answer.\nYou chose an incorrect answer.\nThe minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "checkbox", "displayColumns": 0, "minAnswers": 0, "maxAnswers": 0, "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3", "Choice 4", "Choice 5"], "matrix": ["1", "1", "-1", "-1", "-1"], "distractors": ["", "", "", "", ""]}, {"type": "m_n_2", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "First two choices", "answer": {"valid": true, "value": [[true], [true], [false], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 0.6}}]}, {"variables": [], "name": "Choices 2 and 3", "answer": {"valid": true, "value": [[false], [true], [true], [false], [false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "checkbox", "displayColumns": 0, "minAnswers": 0, "maxAnswers": "2", "warningType": "prevent", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3", "Choice 4", "Choice 5"], "matrix": ["1", "2", "3", "-1", "-1"], "distractors": ["", "", "", "", ""]}]}, {"name": "Match choices with answers part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "Both correct choices", "answer": {"valid": true, "value": [[true, false], [false, true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "One right, one wrong", "answer": {"valid": true, "value": [[true, true], [false, false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose an incorrect answer."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "Both wrong", "answer": {"valid": true, "value": [[false, true], [true, false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose an incorrect answer.\nYou chose an incorrect answer.\nThe minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": false, "shuffleAnswers": false, "displayType": "radiogroup", "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2"], "matrix": [["1 ", "-1"], ["-1", "1"]], "layout": {"type": "all", "expression": ""}, "answers": ["Answer 1", "Answer 2"]}, {"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "All correct answers", "answer": {"valid": true, "value": [[true, true], [true, false]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose a correct answer.", "You chose a correct answer."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "Incorrect answer", "answer": {"valid": true, "value": [[false, true], [true, true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.\nYou chose a correct answer.\nYou chose an incorrect answer.\nThe minimum score for this part is 0."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "minMarks": 0, "maxMarks": 0, "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": false, "shuffleAnswers": false, "displayType": "checkbox", "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2"], "matrix": [["1", "1"], ["1", "-3"]], "layout": {"type": "all", "expression": ""}, "answers": ["Answer 1", "Answer 2"]}, {"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "All correct answers", "answer": {"valid": true, "value": [[true, false, false], [true, true, false], [true, true, true]]}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["You chose a correct answer.", "You chose a correct answer.", "You chose a correct answer.", "You chose a correct answer.", "You chose a correct answer.", "You chose a correct answer.", "The maximum score for this part is 3."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "minMarks": 0, "maxMarks": "3", "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": false, "shuffleAnswers": false, "displayType": "checkbox", "warningType": "none", "showCellAnswerState": true, "choices": ["Choice 1", "Choice 2", "Choice 3"], "matrix": [["1", "1", "1"], ["1", "1", "1"], ["1", "1", "1"]], "layout": {"type": "uppertriangle", "expression": ""}, "answers": ["Answer 1", "Answer 2", "Answer 3"]}]}, {"name": "Match text pattern part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "patternmatch", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "\"thing!\" is correct", "answer": {"valid": true, "value": "thing!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "\"THING!\" is correct", "answer": {"valid": true, "value": "THING!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "thing!", "displayAnswer": "thing!", "matchMode": "exact"}, {"type": "patternmatch", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "\"thing!\" is correct", "answer": {"valid": true, "value": "thing!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "\"THING!\" is correct except for case", "answer": {"valid": true, "value": "THING!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "0.5", "messages": ["Your answer is correct, except for the case."], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}], "answer": "thing!", "displayAnswer": "thing!", "caseSensitive": true, "partialCredit": "50", "matchMode": "exact"}, {"type": "patternmatch", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "\"two words\" is correct", "answer": {"valid": true, "value": "two words", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "true", "messages": ["Your answer is correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "\"this thing!\" is incorrect", "answer": {"valid": true, "value": "this thing!", "empty": false}, "notes": [{"name": "mark", "expected": {"value": "false", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "answer": "\\w+ \\w+", "displayAnswer": "hello there", "matchMode": "regex"}]}, {"name": "Mathematical expression part", "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "extensions": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "x is correct", "answer": {"valid": true, "value": "x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "y is incorrect", "answer": {"valid": true, "value": "y"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "x+0 is correct", "answer": {"valid": true, "value": "x+0"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "x+0*y is correct", "answer": {"valid": true, "value": "x+0y"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "x", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "valuegenerators": [{"name": "x", "value": ""}]}, {"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "2x is correct", "answer": {"valid": true, "value": "2x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}, {"variables": [], "name": "x+x gets a penalty", "answer": {"valid": true, "value": "x+x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct.", "Your answer is not in the expected form: Should be number times x"], "warnings": [], "error": "", "valid": true, "credit": 0.5}}]}, {"variables": [], "name": "3x is wrong", "answer": {"valid": true, "value": "3x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect."], "warnings": [], "error": "", "valid": true, "credit": 0}}]}, {"variables": [], "name": "x+x+x is wrong and gets warning", "answer": {"valid": true, "value": "x+x+x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is incorrect.", "Your answer is not in the expected form: Should be number times x"], "warnings": [], "error": "", "valid": true, "credit": 0}}]}], "answer": "2x", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "mustmatchpattern": {"pattern": "$n*x", "partialCredit": "50", "message": "Should be number times x", "nameToCompare": ""}, "valuegenerators": [{"name": "x", "value": ""}]}, {"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [{"variables": [], "name": "xx is correct", "answer": {"valid": true, "value": "y>x"}, "notes": [{"name": "mark", "expected": {"value": "nothing", "messages": ["Your answer is numerically correct."], "warnings": [], "error": "", "valid": true, "credit": 1}}]}], "answer": "x