// Numbas version: exam_results_page_options {"metadata": {"licence": "Creative Commons Attribution 4.0 International", "description": ""}, "duration": 0, "question_groups": [{"pickingStrategy": "all-ordered", "pickQuestions": 1, "name": "Group", "questions": [{"name": "Custom marking - answer is a set", "extensions": [], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false}, "contributors": [{"name": "Christian Lawson-Perfect", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/7/"}, {"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}], "tags": ["custom marking", "demo"], "metadata": {"description": "", "licence": "Creative Commons Attribution 4.0 International"}, "statement": "", "advice": "", "rulesets": {}, "variables": {"odds": {"name": "odds", "group": "Ungrouped variables", "definition": "mod(im(qb+det),2)+mod(re(qb+det),2)", "description": "", "templateType": "anything"}, "eb": {"name": "eb", "group": "Ungrouped variables", "definition": "-f*(x0+x1)", "description": "", "templateType": "anything"}, "roots": {"name": "roots", "group": "Ungrouped variables", "definition": "if(im(det)<>0,[],if(det=0,[x0],[x0,x1]))", "description": "", "templateType": "anything"}, "x1": {"name": "x1", "group": "Ungrouped variables", "definition": "(-qb-det)/2", "description": "", "templateType": "anything"}, "x0": {"name": "x0", "group": "Ungrouped variables", "definition": "(-qb+det)/2", "description": "", "templateType": "anything"}, "f": {"name": "f", "group": "Ungrouped variables", "definition": "if(odds=0,1,4)", "description": "", "templateType": "anything"}, "ea": {"name": "ea", "group": "Ungrouped variables", "definition": "f", "description": "", "templateType": "anything"}, "det": {"name": "det", "group": "Ungrouped variables", "definition": "random(0..3)*random(1,i)", "description": "", "templateType": "anything"}, "ec": {"name": "ec", "group": "Ungrouped variables", "definition": "x0*x1*f", "description": "", "templateType": "anything"}, "qb": {"name": "qb", "group": "Ungrouped variables", "definition": "random(-3..3)", "description": "", "templateType": "anything"}}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": ["f", "ea", "odds", "det", "ec", "eb", "qb", "x0", "x1", "roots"], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "jme", "useCustomName": false, "customName": "", "marks": 2, "showCorrectAnswer": true, "showFeedbackIcon": true, "scripts": {"mark": {"script": "// evaluate the student's answer\ntry {\n var list = Numbas.jme.evaluate(this.studentAnswer,this.question.scope);\n}\ncatch(e)\n{\n this.setCredit(0,R('part.jme.answer invalid',e.message));\n return;\n}\n\n// check the answer is a list\nthis.notAList = list.type!='list';\nif(this.notAList) {\n this.setCredit(0,'Your answer is not a list of numbers.');\n return;\n}\n\nvar variables = this.question.scope.variables;\nvar unwrap = Numbas.jme.unwrapValue;\n\n// get the roots of the equation\nvar roots = unwrap(variables.roots);\n\n// unwrap the student's list to a Javascript array of numbers\nvar list = unwrap(list);\n\n// get the coefficients of the equation\nvar ea = unwrap(variables.ea);\nvar eb = unwrap(variables.eb);\nvar ec = unwrap(variables.ec);\n\n// check each root the student gave, keeping track of how many they got right\nvar got = 0;\nvar wrong = [];\nfor(var i=0;iroots.length) {\n this.setCredit(0,\"This equation does not have \"+(list.length)+\" real-valued \"+Numbas.util.pluralise(list.length,'root','roots')+\".\");\n} else if(got[1,2].');\n return false;\n}\nreturn true;", "order": "instead"}}, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "adaptiveMarkingPenalty": 0, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "prompt": "

Give the set of real-valued roots of the equation

\n

\$\\simplify[all,fractionnumbers]{{ea}x^2+{eb}x+{ec}}=0 \$

\n

Enter your answer as a list of numbers separated by commas and enclosed by square brackets, e.g. [1,2].

\n

If the equation has no roots, enter []

", "answer": "{roots}", "answerSimplification": "fractionNumbers", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "valuegenerators": []}]}, {"name": "Custom marking - differentiate student's answer", "extensions": [], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false}, "contributors": [{"name": "Christian Lawson-Perfect", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/7/"}], "variables": {"b": {"templateType": "anything", "name": "b", "group": "Ungrouped variables", "definition": "random(-10..10 except 0)", "description": ""}, "a": {"templateType": "anything", "name": "a", "group": "Ungrouped variables", "definition": "random(1..10)", "description": ""}}, "statement": "", "metadata": {"licence": "Creative Commons Attribution 4.0 International", "description": "

Contains some extremely basic code to do symbolic differentiation: it can give the derivative of terms of the form $x^n$, $sin(x)$ and $cos(x)$, and apply the chain rule.

"}, "variablesTest": {"condition": "", "maxRuns": 100}, "functions": {}, "variable_groups": [], "rulesets": {}, "ungrouped_variables": ["a", "b"], "tags": ["custom marking", "demo"], "advice": "", "preamble": {"css": "", "js": "//*************\n// differentiation\nvar jme = Numbas.jme;\nvar TNum = Numbas.jme.types.TNum;\n\nvar functionDerivatives = {\n 'cos': '-sin(x)',\n 'sin': 'cos(x)'\n};\nvar generalFunctionDerivative = jme.compile(\"f'(x)\");\nfor(var name in functionDerivatives) {\n functionDerivatives[name] = jme.compile(functionDerivatives[name]);\n}\nvar chainRule = jme.compile(\"x'*f'\")\n var opDerivatives = {\n '+': \"u'+v'\",\n '+u': \"+u'\",\n '-u': \"-u'\",\n '-': \"u'-v'\",\n '*': \"u'*v+u*v'\",\n \"/\": \"(v*u'-v'*u)/(v^2)\"\n }\n var powerRule = jme.compile(\"v*u'*u^(v-1)\");\nvar exponentialRule = jme.compile(\"ln(u)*v'*u^v\");\nfor(var name in opDerivatives) {\n opDerivatives[name] = jme.compile(opDerivatives[name]);\n}\n\nvar differentiate = jme.differentiate = function(tree,x) {\n var tok = tree.tok;\n \n switch(tok.type) {\n case 'number':\n return {tok: new TNum(0)};\n break;\n case 'name':\n return {tok: new TNum(tok.name==x ? 1 : 0)};\n case 'op':\n var l = differentiate(tree.args[0],x,1);\n if(tree.args.length>1)\n var r = differentiate(tree.args[1],x,1);\n var scope = {variables: {\"u\": tree.args[0], \"u'\": l, \"v\": tree.args[1], \"v'\": r}};\n if(tok.name=='^') {\n if(tree.args[1].tok.type=='number' || (tree.args[1].tok.type=='op' && tree.args[1].tok.name=='-u' && tree.args[1].args[0].tok.type=='number')) {\t// f(x)^n\n return jme.substituteTree(powerRule,scope);\n }\n else if(tree.args[0].tok.type=='number' || (tree.args[0].tok.type=='op' && tree.args[0].tok.name=='-u' && tree.args[0].args[0].tok.type=='number')) {\t// n^x\n return jme.substituteTree(exponentialRule,scope);\n }\n else {\n throw(new Numbas.Error('jme.differentiate.hard exponential'));\n }\n }\n return jme.substituteTree(opDerivatives[tok.name],scope);\n case 'function':\n var df = jme.substituteTree(tok.name in functionDerivatives ? functionDerivatives[tok.name] : generalFunctionDerivative,{variables:{x:tree.args[0], \"f'\": tok.name+\"'\"}});\n var dx = differentiate(tree.args[0],x);\n return jme.substituteTree(chainRule,{variables: {\"f'\": df, \"x'\": dx}});\n }\n}\n // end of differentiation code\n // ***************************\n \n question.signals.on('HTMLAttached',function() {\n var gap = question.parts[0].gaps[0];\n var omark = gap.mark;\n var add_constant_rule = new Numbas.jme.display.Rule('x+y',[]);\n });"}, "parts": [{"showFeedbackIcon": true, "extendBaseMarkingAlgorithm": true, "unitTests": [], "type": "gapfill", "showCorrectAnswer": true, "useCustomName": false, "prompt": "

This part is marked by calculating the derivative of your answer and comparing it to the original expression.

\n

$\\displaystyle{\\int \\simplify{cos({a}x) + e^(x/{b})} \\,\\mathrm{d}x = }$ [[0]]

", "scripts": {}, "variableReplacementStrategy": "originalfirst", "marks": 0, "variableReplacements": [], "customName": "", "gaps": [{"showFeedbackIcon": true, "extendBaseMarkingAlgorithm": true, "checkingAccuracy": 0.001, "vsetRange": [0, 1], "type": "jme", "useCustomName": false, "valuegenerators": [{"name": "x", "value": ""}], "showPreview": true, "checkVariableNames": false, "variableReplacements": [], "customName": "", "vsetRangePoints": 5, "failureRate": 1, "customMarkingAlgorithm": "", "answer": "cos({a}x)+e^(x/{b})", "adaptiveMarkingPenalty": 0, "showCorrectAnswer": true, "checkingType": "absdiff", "scripts": {"mark": {"order": "instead", "script": "// get the student's answer\nvar integral = this.studentAnswer;\n\n// compute its derivative\nvar tree;\nvar derivative;\nvar derivative_tree;\ntry {\n tree = Numbas.jme.compile(integral);\n derivative_tree = Numbas.jme.differentiate(tree,'x');\n derivative = Numbas.jme.display.treeToJME(derivative_tree);\n derivative = Numbas.jme.display.simplifyExpression(derivative,'all',Numbas.jme.builtinScope);\n}\ncatch(e) {\n derivative = '';\n}\n\n// set the \"student's answer\" to the derivative\nthis.studentAnswer = derivative;\n\n// mark the JME part - the correct answer is the function which was to be integrated\nNumbas.parts.JMEPart.prototype.mark.apply(this);\n\n// set the student's answer back to what they typed\nthis.studentAnswer = integral;\n\nthis.markingFeedback = [];\n\n// If the derivative matches the original expression\nif(this.credit==1) { \n this.markingComment('Your answer is correct. Well done!');\n \n // check there's a constant of integration\n if(Numbas.jme.findvars(tree).length!=2) {\n this.multCredit(0.5,'You need to add a constant of integration, but otherwise this is correct.');\n }\n}\nelse {\n // Show the student what the derivative of their expression is\n var derivativeTeX = Numbas.jme.display.exprToLaTeX(derivative,[],Numbas.jme.builtinScope);\n this.markingComment('The derivative of your answer should be equal to the expression you were asked to integrate, i.e.: \\\$\\\\simplify{cos({a}x) + e^(x/{b})} \\\$ The derivative of your function is \\\$'+derivativeTeX+'\\\$');\n}"}}, "marks": 2, "variableReplacementStrategy": "originalfirst", "unitTests": []}], "customMarkingAlgorithm": "", "sortAnswers": false, "adaptiveMarkingPenalty": 0}]}, {"name": "Custom marking - error carried forward", "extensions": [], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false}, "contributors": [{"name": "Christian Lawson-Perfect", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/7/"}], "metadata": {"licence": "Creative Commons Attribution 4.0 International", "description": "", "notes": ""}, "advice": "", "variable_groups": [], "type": "question", "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": ["a", "root_b", "root_a", "b"], "parts": [{"prompt": "

\\begin{align} a &= \\var{a}, \\\\ b &= \\var{b} \\end{align}

\n

$\\sqrt{a} =$ [[0]] (give your answer to two decimal places)

\n

$\\sqrt{b} =$ [[1]] (give your answer to two decimal places)

\n

Using the answers you gave above, calculate $\\sqrt{a} + \\sqrt{b} =$ [[2]] (give your answer to two decimal places)

\n

If you enter incorrect values for either of $\\sqrt{a}$ and $\\sqrt{b}$ but do the addition correctly, you will only lose mark(s) for the initial error.

", "type": "gapfill", "gaps": [{"correctAnswerFraction": false, "type": "numberentry", "precisionMessage": "You have not given your answer to the correct precision.", "precisionPartialCredit": 0, "showCorrectAnswer": true, "maxValue": "root_a", "strictPrecision": true, "showPrecisionHint": false, "precision": 2, "precisionType": "dp", "scripts": {}, "minValue": "root_a", "allowFractions": false, "marks": 1}, {"correctAnswerFraction": false, "type": "numberentry", "precisionMessage": "You have not given your answer to the correct precision.", "precisionPartialCredit": 0, "showCorrectAnswer": true, "maxValue": "root_b", "strictPrecision": true, "showPrecisionHint": false, "precision": 2, "precisionType": "dp", "scripts": {}, "minValue": "root_b", "allowFractions": false, "marks": 1}, {"correctAnswerFraction": false, "type": "numberentry", "precisionMessage": "You have not given your answer to the correct precision.", "precisionPartialCredit": 0, "showCorrectAnswer": true, "maxValue": "root_a+root_b", "strictPrecision": true, "showPrecisionHint": false, "precision": 2, "precisionType": "dp", "scripts": {"mark": {"order": "instead", "script": "// get the student's answers to the first two steps\nvar gap0 = this.parentPart.gaps[0];\nvar gap1 = this.parentPart.gaps[1];\n\n// if either of them was wrong, tell the student we're carrying the error forward\nif(gap0.credit<1) {\n this.markingComment('Error carried forward from $\\\\sqrt{a}$. The value you gave will be used to mark the sum.');\n}\nif(gap1.credit<1) {\n this.markingComment('Error carried forward from $\\\\sqrt{b}$. The value you gave will be used to mark the sum');\n}\n\nvar ecf = gap0.credit<1 || gap1.credit<1;\n\n// re-set the correct answer to gap 2 based on the answers to gaps 0 and 1\nvar student_a = parseFloat(gap0.studentAnswer);\nvar student_b = parseFloat(gap1.studentAnswer);\nthis.settings.minvalue = this.settings.maxvalue = Numbas.math.precround(student_a+student_b,2);\n\n// mark this gap\nNumberEntryPart.prototype.mark.apply(this);"}}, "minValue": "root_a+root_b", "allowFractions": false, "marks": 1}], "showCorrectAnswer": true, "scripts": {}, "marks": 0}], "preamble": {"css": "", "js": ""}, "rulesets": {}, "tags": ["custom marking", "demo"], "showQuestionGroupNames": false, "question_groups": [{"pickingStrategy": "all-ordered", "pickQuestions": 0, "questions": [], "name": ""}], "functions": {}, "variables": {"root_b": {"group": "Ungrouped variables", "name": "root_b", "templateType": "anything", "description": "", "definition": "precround(sqrt(b),2)"}, "a": {"group": "Ungrouped variables", "name": "a", "templateType": "anything", "description": "", "definition": "random(100..200#0.0001)"}, "b": {"group": "Ungrouped variables", "name": "b", "templateType": "anything", "description": "", "definition": "random(50..100#0.0001)"}, "root_a": {"group": "Ungrouped variables", "name": "root_a", "templateType": "anything", "description": "", "definition": "precround(sqrt(a),2)"}}, "statement": ""}, {"name": "Custom marking of a matrix entry part", "extensions": [], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false}, "contributors": [{"name": "Christian Lawson-Perfect", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/7/"}], "metadata": {"licence": "Creative Commons Attribution 4.0 International", "description": "", "notes": ""}, "advice": "", "variable_groups": [], "type": "question", "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "parts": [{"type": "matrix", "markPerCell": false, "showCorrectAnswer": true, "numColumns": "2", "correctAnswerFractions": false, "allowResize": false, "prompt": "

Write a $2 \\times 2$ matrix. The feedback will show the bottom-right value.

", "tolerance": 0, "correctAnswer": "id(2)", "scripts": {"mark": {"order": "instead", "script": "// student's answer is held in this.studentAnswer\n// it's a 2d array of the strings the student wrote\n// you have to parse each cell as a number.\n\n\n// this script doesn't really do any marking - it just looks at the bottom-right cell of the student's answer\n\nvar cell = Numbas.util.parseNumber(this.studentAnswer[1][1]);\n\nif(Numbas.util.isNumber(cell)) {\n this.markingComment(\"The bottom right cell is \"+cell);\n this.answered = true;\n this.setCredit(1);\n} else {\n this.invalidCell = true; // used by the validation script so it gives the right error message\n this.answered = false;\n this.setCredit(0,\"The bottom right cell is not a number!\");\n}"}}, "allowFractions": false, "numRows": "2", "marks": 1}], "preamble": {"css": "", "js": ""}, "rulesets": {}, "tags": ["demo"], "showQuestionGroupNames": false, "question_groups": [{"pickingStrategy": "all-ordered", "pickQuestions": 0, "questions": [], "name": ""}], "functions": {}, "variables": {}, "statement": ""}]}], "percentPass": 0, "type": "exam", "name": "Custom marking", "showQuestionGroupNames": false, "timing": {"allowPause": true, "timeout": {"action": "none", "message": ""}, "timedwarning": {"action": "none", "message": ""}}, "navigation": {"allowregen": true, "showresultspage": "oncompletion", "showfrontpage": false, "preventleave": false, "browse": true, "onleave": {"action": "none", "message": ""}, "reverse": true}, "feedback": {"feedbackmessages": [], "showactualmark": true, "showtotalmark": true, "showanswerstate": true, "intro": "", "allowrevealanswer": true, "advicethreshold": 0}, "contributors": [{"name": "Christian Lawson-Perfect", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/7/"}], "extensions": [], "custom_part_types": [], "resources": []}