// Numbas version: finer_feedback_settings {"name": "Demo variable number of gaps", "extensions": [], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"name": "Demo variable number of gaps", "tags": ["demo", "variable number of gaps"], "metadata": {"description": "
In this demo question, you can see either 2 or 3 gaps depending on the variable \\(m\\), and the marking algorithm doesn't penalise for the empty third gap in cases when it is not shown.
\nReason to use it: for vectors or matrices containing only numbers, one can easily use matrix entry to account for a random size of an answer. But this does not work for mathematical expressions. There we have to give each entry of the vector as a separate gap, which then becomes a problem when the size varies. This solves that problem. For this reason I've included two parts: one very simple one that just shows the phenomenon of variable number of gaps, and one which is more like why I needed it.
\nNote that to resolve the fact that when \\(m=2\\), the point for the third gap cannot be earned, I have made it so that the student only gets 0 or all points, when all shown gaps are correctly filled in.
\nNote the use of Ax[m-1] in the third gap \"correct answer\" of part b): if you use Ax[2], then it will throw an error when m=2, as then Ax won't have the correct size. So even though the marking algorithm will ignore it, the question would still not work.
\nBonus demo if you look in the variables: A way to automatically generate the correct latex code for \\(\\var{latexAx}\\), since it's a variable size. I would usually need that in the \"Advice\", i.e. solutions, rather than the question text.
", "licence": "Creative Commons Attribution 4.0 International"}, "statement": "In this demo question, you can see either 2 or 3 gaps depending on the variable \\(m\\), and the marking algorithm doesn't penalise for the empty third gap in cases when it is not shown.
\nReason to use it: for vectors or matrices containing only numbers, one can easily use matrix entry to account for a random size of an answer. But this does not work for mathematical expressions. There we have to give each entry of the vector as a separate gap, which then becomes a problem when the size varies. This solves that problem. For this reason I've included two parts: one very simple one that just shows the phenomenon of variable number of gaps, and one which is more like why I needed it.
\nNote that to resolve the fact that when \\(m=2\\), the point for the third gap cannot be earned, I have made it so that the student only gets 0 or all points, when all shown gaps are correctly filled in.
", "advice": "\n", "rulesets": {}, "extensions": [], "variables": {"A": {"name": "A", "group": "Ungrouped variables", "definition": "matrix(repeat([1,-1,1],m))", "description": "", "templateType": "anything"}, "m": {"name": "m", "group": "Ungrouped variables", "definition": "random(2..3)", "description": "", "templateType": "anything"}, "n": {"name": "n", "group": "Ungrouped variables", "definition": "3", "description": "", "templateType": "anything"}, "x": {"name": "x", "group": "Ungrouped variables", "definition": "map('x_{k}',k,1..n)", "description": "
general vector x. ['x_1','x_2','x_3'] As list because vector can only take numbers as entries.
", "templateType": "anything"}, "latexAx": {"name": "latexAx", "group": "Ungrouped variables", "definition": "latex('\\\\begin{pmatrix}'+ concatstrings(halfrawAx) +'\\\\end{'+'pmatrix}')", "description": "Ax as needed for latex string
", "templateType": "anything"}, "rawAx": {"name": "rawAx", "group": "Ungrouped variables", "definition": "map('{A[k][l]}*'+x[{l}]+symbols2(m,n)[k][l],[k,l],product(0..m-1,0..n-1))", "description": "", "templateType": "anything"}, "halfrawAx": {"name": "halfrawAx", "group": "Ungrouped variables", "definition": "map(string(simplify(expression(concatstrings(rawAx[(n*k)..(n*k+n)])),\"all\"))+symbols3(m)[k],k,0..m-1)", "description": "", "templateType": "anything"}, "Ax": {"name": "Ax", "group": "Ungrouped variables", "definition": "map(simplify(expression(concatstrings(rawAx[(n*k)..(n*k+n)])),[\"all\",\"!noleadingminus\"]),k,0..m-1)", "description": "Ax as list, can be used as expected answer.
", "templateType": "anything"}, "xalt": {"name": "xalt", "group": "Ungrouped variables", "definition": "map('x{k}',k,1..n)", "description": "alternative way of writing the variables in mathematical expression for part b
", "templateType": "anything"}, "rawAxalt": {"name": "rawAxalt", "group": "Ungrouped variables", "definition": "map('{A[k][l]}*'+xalt[{l}]+symbols2(m,n)[k][l],[k,l],product(0..m-1,0..n-1))", "description": "alternative way of writing the variables in mathematical expression for part b
", "templateType": "anything"}, "Axalt": {"name": "Axalt", "group": "Ungrouped variables", "definition": "map(simplify(expression(concatstrings(rawAxalt[(n*k)..(n*k+n)])),[\"all\",\"!noleadingminus\"]),k,0..m-1)", "description": "alternative way of writing the variables in mathematical expression for part b
", "templateType": "anything"}}, "variablesTest": {"condition": "", "maxRuns": "100"}, "ungrouped_variables": ["A", "m", "n", "x", "rawAx", "halfrawAx", "latexAx", "Ax", "xalt", "rawAxalt", "Axalt"], "variable_groups": [], "functions": {"concatstrings": {"parameters": [["input", "list"]], "type": "string", "language": "javascript", "definition": "var output = '';\nvar i;\nfor (i = 0; i < input.length; i++) {\n output += input[i];\n} \nreturn output;"}, "symbols2": {"parameters": [["m", "number"], ["n", "number"]], "type": "list", "language": "jme", "definition": "repeat(repeat('+',n-1)+[''],m-1)+[repeat('+',n-1)+['']]"}, "symbols3": {"parameters": [["m", "number"]], "type": "list", "language": "jme", "definition": "repeat('\\\\\\\\',m-1)+['']"}}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "gapfill", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "mygaps (Pick the correct number of gaps depending on the variable m):\n gaps[0..m]\n\nmystudentAnswer (Pick the correct number of gaps in student answer):\n studentAnswer[0..m]\n\nmarked_original_order (Mark the gaps in the original order, mainly to establish if every gap has a valid answer):\n map(\n mark_part(gap[\"path\"],studentAnswer),\n [gap,studentAnswer],\n zip(mygaps,mystudentAnswer)\n )\n\n\ngap_order:\n if(settings[\"sortAnswers\"],\n sort_destinations(interpreted_answers)\n ,\n list(0..len(mygaps)-1)\n )\n\ngap_feedback (Feedback on each of the gaps):\n map(\n let(result,submit_part(mygaps[gap_number][\"path\"],answer),\n feedback(translate('part.gapfill.feedback header',[\"index\":index]));\n concat_feedback(result[\"feedback\"], result[\"marks\"]/marks);\n result\n ),\n [gap_number,answer,index],\n zip(gap_order,mystudentAnswer,list(1..len(mygaps)))\n )\n\ngap_correct:\n map(result[\"credit\"]=1,result,gap_feedback)\n\n\nall_correct:\n correctif(all(gap_correct))\n\n\nmark:\n assert(all_valid, fail(translate(\"question.can not submit\")));\n apply(answers); \n apply(all_correct)\n", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "Enter the first \\(\\var{m}\\) integers, starting from \\(1\\).
\n[[0]] [[1]][[2]]
\n(Note that you can only apply the \"conditional visibility\" to the gap when it is in the form of [[ 2 ]]
rather than visible in the editor as a gap.)
The correct answer to be entered is \\(\\var{latexAx}\\). Input \\(x_1\\) as x_1
or x1
, etc. Use the same notation for all variables, don't mix it.
\\(Ax= \\left(\\begin{matrix} \\phantom{.}\\\\\\phantom{.}\\\\\\phantom{.}\\end{matrix} \\right. \\) | \n[[0]] | \n\\(\\left.\\begin{matrix} \\phantom{.}\\\\\\phantom{.}\\\\\\phantom{.}\\end{matrix} \\right) \\) | \n
[[1]] | \n
\\(Ax= \\left(\\begin{matrix} \\phantom{.}\\\\\\phantom{.}\\\\\\phantom{.}\\\\\\phantom{.}\\end{matrix} \\right. \\) | \n[[0]] | \n\\(\\left.\\begin{matrix} \\phantom{.}\\\\\\phantom{.}\\\\\\phantom{.}\\\\\\phantom{.}\\end{matrix} \\right) \\) | \n
[[1]] | \n||
[[2]] | \n
Note the use of Ax[m-1] in the third gap \"correct answer\": if you use Ax[2], then it will throw an error when m=2, as then Ax won't have the correct size. So even though the marking algorithm will ignore it, the question would still not work.
\nBonus demo if you look in the variables: A way to automatically generate the correct latex code for \\(\\var{latexAx}\\), since it's a variable size. I would usually need that in the \"Advice\", i.e. solutions, rather than the question text.
", "gaps": [{"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "alternatives": [{"type": "jme", "useCustomName": false, "customName": "", "marks": "1", "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "alternativeFeedbackMessage": "", "useAlternativeFeedback": true, "answer": "{Axalt[0]}", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "singleLetterVariables": false, "allowUnknownFunctions": true, "implicitFunctionComposition": false, "valuegenerators": []}], "answer": "{Ax[0]}", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "singleLetterVariables": false, "allowUnknownFunctions": true, "implicitFunctionComposition": false, "valuegenerators": []}, {"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "alternatives": [{"type": "jme", "useCustomName": false, "customName": "", "marks": "1", "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "alternativeFeedbackMessage": "", "useAlternativeFeedback": true, "answer": "{Axalt[1]}", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "singleLetterVariables": false, "allowUnknownFunctions": true, "implicitFunctionComposition": false, "valuegenerators": []}], "answer": "{Ax[1]}", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "singleLetterVariables": false, "allowUnknownFunctions": true, "implicitFunctionComposition": false, "valuegenerators": []}, {"type": "jme", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "alternatives": [{"type": "jme", "useCustomName": false, "customName": "", "marks": "1", "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "alternativeFeedbackMessage": "", "useAlternativeFeedback": true, "answer": "{Axalt[m-1]}", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "singleLetterVariables": false, "allowUnknownFunctions": true, "implicitFunctionComposition": false, "valuegenerators": []}], "answer": "{Ax[m-1]}", "showPreview": true, "checkingType": "absdiff", "checkingAccuracy": 0.001, "failureRate": 1, "vsetRangePoints": 5, "vsetRange": [0, 1], "checkVariableNames": false, "singleLetterVariables": false, "allowUnknownFunctions": true, "implicitFunctionComposition": false, "valuegenerators": []}], "sortAnswers": false}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always", "type": "question", "contributors": [{"name": "Julia Goedecke", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/5121/"}]}]}], "contributors": [{"name": "Julia Goedecke", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/5121/"}]}