// Numbas version: finer_feedback_settings {"name": "Test Yourself Week 4", "metadata": {"description": "", "licence": "None specified"}, "duration": 0, "percentPass": 0, "showQuestionGroupNames": true, "shuffleQuestionGroups": false, "showstudentname": true, "question_groups": [{"name": "Warm up", "pickingStrategy": "all-ordered", "pickQuestions": 1, "questionNames": [""], "variable_overrides": [[]], "questions": [{"name": "Logical operators", "extensions": ["mas-codeassess"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Josh Cowley", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/9358/"}, {"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true}, "constants": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": "code {\n color: #333;\n background-color: #eee\n}"}, "parts": [{"type": "m_n_x", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Consider the following variable 

\n
x = 10
\n

Which of the following commands would return True and which False (and which neither). Try to answer without running the commands

", "minMarks": 0, "maxMarks": 0, "minAnswers": 0, "maxAnswers": 0, "shuffleChoices": true, "shuffleAnswers": false, "displayType": "radiogroup", "warningType": "none", "showCellAnswerState": true, "markingMethod": "sum ticked cells", "choices": ["x = 10", "x % 4", "
x == 10
", "x > 10", "x >= 10", "x > 0 and x % 2 == 0", "x > 0 or x % 2 == 0", "x != 10", "x != 0", "x % 2 == 0", "x % 2 != 0", "x <= 10"], "matrix": [[0, 0, "0.5"], [0, 0, "0.5"], ["0.5", 0, 0], [0, "0.5", 0], ["0.5", 0, 0], ["0.5", 0, 0], ["0.5", 0, 0], [0, "0.5", 0], ["0.5", 0, 0], ["0.5", 0, 0], [0, "0.5", 0], ["0.5", 0, 0]], "layout": {"type": "all", "expression": ""}, "answers": ["True", "False", "Neither"]}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always", "type": "question"}]}, {"name": "Test Yourself", "pickingStrategy": "all-ordered", "pickQuestions": 1, "questionNames": ["", "", ""], "variable_overrides": [[], [], []], "questions": [{"name": "Fix code", "extensions": ["mas-codeassess", "programming"], "custom_part_types": [{"source": {"pk": 195, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/195/edit"}, "name": "Code", "short_name": "mark-code-3", "description": "

Mark code provided by the student by running it and a series of validation and marking tests.

\n

The validation tests are used to reject an answer if the student has misunderstood the task, for example if they haven't defined a required variable or function.

\n

Marking tests check properties of the student's code. Each test awards a proportion of the available credit if it is passed.

\n

You can optionally show the student the STDOUT and/or STDERR when running their code.

\n

You can give a preamble and postamble which are run before and after the student's code, and also modify the student's code before running it.

", "help_url": "", "input_widget": "code-editor", "input_options": {"correctAnswer": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"correct_answer\"])\n,\n settings[\"correct_answer\"]\n)", "hint": {"static": false, "value": "\"Write \"+capitalise(language_synonym(settings[\"code_language\"]))+\" code\""}, "language": {"static": false, "value": "language_synonym(settings[\"code_language\"])"}, "placeholder": {"static": false, "value": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"placeholder\"])\n,\n settings[\"placeholder\"]\n)"}, "theme": {"static": true, "value": "textmate"}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\napply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)\n\ninterpreted_answer:\nstudentAnswer\n\nmain_result:\ncode_result[3]\n\nmarking_results:\ncode_result[6..(len(settings[\"tests\"])+6)]\n\nvalidation_results:\ncode_result[(len(settings[\"tests\"])+6)..len(code_result)]\n\nmain_error:\nassert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)\n\nmarking_test_feedback:\nmap(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)\n\nvalidation_test_feedback:\nmap(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)\n\ntotal_weight:\nsum(map(weight,[name,weight,code],settings[\"tests\"]))\n\npre_submit:\nif(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)\n\ncode_result:\npre_submit[\"code_result\"]\n\nmain_stdout:\nsafe(main_result[\"stdout\"])\n\ncode_language:\nsettings[\"code_language\"]\n\npreamble_result:\ncode_result[2]\n\npreamble_stderr:\npreamble_result[\"stderr\"]\n\npostamble_result:\ncode_result[4]\n\npostamble_stderr:\npostamble_result[\"stderr\"]\n\npostamble_feedback:\nassert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)\n\nmatplotlib_preamble:\nif(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)\n\nmatplotlib_postamble:\nswitch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)\n\nmatplotlib_result:\ncode_result[5]\n\nmatplotlib_feedback:\nswitch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n\n\nimages:\nflatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))\n\nshow_images:\nassert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)", "marking_notes": [{"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "apply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "studentAnswer"}, {"name": "main_result", "description": "

The result of running the student's code and the preamble, without any tests.

\n

Normally used to detect errors in the student's code.

", "definition": "code_result[3]"}, {"name": "marking_results", "description": "

The results of running the marking tests.

", "definition": "code_result[6..(len(settings[\"tests\"])+6)]"}, {"name": "validation_results", "description": "

The results of running the validation tests.

", "definition": "code_result[(len(settings[\"tests\"])+6)..len(code_result)]"}, {"name": "main_error", "description": "

Show STDOUT if allowed.

\n

Check the student's code runs on its own. Fail if there was an error, and show STDERR if allowed.

", "definition": "assert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)"}, {"name": "marking_test_feedback", "description": "

Feedback on the marking tests. For each test, if the test was passed then add the corresponding amount of credit. If there was an error, show the error.

", "definition": "map(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)"}, {"name": "validation_test_feedback", "description": "

Give feedback on the validation tests. If any of them are not passed, the student's answer is invalid.

", "definition": "map(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)"}, {"name": "total_weight", "description": "

The sum of the weights of the marking tests. Each test's weight is divided by this to produce a proportion of the available credit.

", "definition": "sum(map(weight,[name,weight,code],settings[\"tests\"]))"}, {"name": "pre_submit", "description": "

The code blocks to run.

\n

In order, they are:

\n", "definition": "if(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)"}, {"name": "code_result", "description": "

The results of the code blocks: a list with an entry corresponding to each block of code.

", "definition": "pre_submit[\"code_result\"]"}, {"name": "main_stdout", "description": "

The stdout from the student's code.

", "definition": "safe(main_result[\"stdout\"])"}, {"name": "code_language", "description": "

The language the code is written in. Either \"pyodide\" (Python) or \"webr\" (R)

", "definition": "settings[\"code_language\"]"}, {"name": "preamble_result", "description": "

The result of running the preamble block.

", "definition": "code_result[2]"}, {"name": "preamble_stderr", "description": "

The STDERR produced by the preamble block.

", "definition": "preamble_result[\"stderr\"]"}, {"name": "postamble_result", "description": "

The result of running the postamble.

", "definition": "code_result[4]"}, {"name": "postamble_stderr", "description": "

The STDERR produced by the postamble block.

", "definition": "postamble_result[\"stderr\"]"}, {"name": "postamble_feedback", "description": "

Show the STDOUT from the postamble, if there is any.

", "definition": "assert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)"}, {"name": "matplotlib_preamble", "description": "

Preamble for a hack to ensure that figures produced by matplotlib in Python are displayed.

\n

This code clears the matplotlib output, if matplotlib has been loaded.

", "definition": "if(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_postamble", "description": "

A hack to show any figures produced with matplotlib in the stdout.

", "definition": "switch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_result", "description": "

The result of running the matplotlib hack.

", "definition": "code_result[5]"}, {"name": "matplotlib_feedback", "description": "

Feedback from the matplotlib hack: if a figure is produced, it's displayed as SVG here.

", "definition": "switch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n"}, {"name": "images", "description": "

Any images produced by the code blocks.

", "definition": "flatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))"}, {"name": "show_images", "description": "

Show the images produced by the code.

", "definition": "assert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)"}], "settings": [{"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "code_language", "label": "Code language", "help_url": "", "hint": "The language that the student's code will be written in.", "input_type": "dropdown", "default_value": "pyodide", "choices": [{"value": "pyodide", "label": "Python"}, {"value": "webr", "label": "R"}]}, {"name": "correct_answer", "label": "Correct answer", "help_url": "", "hint": "A correct answer to the part.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "correct_answer_subvars", "label": "Substitute question variables into the correct answer?", "help_url": "", "hint": "If ticked, then JME expressions between curly braces will be evaluated and substituted into the correct answer.

If not ticked, then the correct answer will be displayed exactly as it is.", "input_type": "checkbox", "default_value": true}, {"name": "show_stdout", "label": "Show stdout?", "help_url": "", "hint": "If ticked, the STDOUT produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_stderr", "label": "Show stderr?", "help_url": "", "hint": "If ticked, the STDERR produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_marking_errors", "label": "Show errors produced by marking tests?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "placeholder", "label": "Placeholder", "help_url": "", "hint": "Initial text for the code editor", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "modifier", "label": "Student code modifier", "help_url": "", "hint": "JME expression to modify the student's submitted code before being passed to the marking template. The student's code is available as the string variable studentAnswer.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "preamble", "label": "Preamble", "help_url": "", "hint": "This code is run before the student's code. Define anything that the student's code or your tests need.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble", "label": "Postamble", "help_url": "", "hint": "This code is run after the student's code but before the validation and unit tests.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble_feedback_whitespace", "label": "Format postamble output as code?", "help_url": "", "hint": "If ticked, any output produced by the postamble will be formatted in monospace font, with whitespace preserved. If not ticked, it'll be presented as prose text or HTML.", "input_type": "checkbox", "default_value": false}, {"name": "tests", "label": "Marking tests", "help_url": "", "hint": "A list of tests used to mark the student's answer.
Each item is a list with three values:
\n", "input_type": "code", "default_value": "[\n [\"Test 1\", 1, \"True\"]\n]", "evaluate": true}, {"name": "validation_tests", "label": "Validation tests", "help_url": "", "hint": "

A list of tests used to validate that the student's code is acceptable.
Each item is a list with two string values:

\n", "input_type": "code", "default_value": "[\n [\"arithmetic works\", \"1+1 == 2\"]\n]", "evaluate": true}, {"name": "variables", "label": "Variables to include in code", "help_url": "", "hint": "Give a dictionary mapping variable names to their values. These variables will be available in the code that is run.", "input_type": "code", "default_value": "dict()", "evaluate": true}], "public_availability": "always", "published": true, "extensions": ["programming"]}], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Josh Cowley", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/9358/"}, {"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "

The following sections of code have an error in them. Can you help?

", "advice": "", "rulesets": {}, "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true}, "constants": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "stepsPenalty": 0, "steps": [{"type": "information", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Check the syntax for setting up a function!

"}], "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "def cube(x):\n return x**3", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "def cube(x)\nreturn x**3", "modifier": "", "preamble": "", "postamble": "", "tests": "[\n [\"Function returns correct values\", 1, \"cube(3) == 27 and cube(5) == 125\"]\n]", "validation_tests": "[\n [\"Make sure your function is called cube\", \"'cube' in locals()\"]\n]", "variables": "dict()"}}, {"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "stepsPenalty": 0, "steps": [{"type": "information", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Is x defined before we start setting its element values? Take a look at the np.zeros function in the handout and don't forget to import numpy!

"}], "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "import numpy as np\nx = np.zeros(5)\n\nfor n in range(5):\n x[n] = n**2", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "for n in range(5):\n x[n] = n**2", "modifier": "", "preamble": "", "postamble": "import numpy as np\nx_c = np.arange(5) ** 2", "tests": "[\n [\"Correct x value\", 1, \"np.array_equal(x, np.arange(5) ** 2)\"]\n]", "validation_tests": "[\n [\"Make sure x is set\", \"'x' in locals()\"]\n]", "variables": "dict()"}}, {"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "stepsPenalty": 0, "steps": [{"type": "information", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

n = 0 does not look like a logical comparison!

"}], "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "x = [-5,0,5,10]\nfor n in x:\n if n == 0:\n print(\"There's a zero here!\")", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "x = [-5,0,5,10]\nfor n in x:\n if n = 0:\n print(\"There's a zero here!\")", "modifier": "", "preamble": "", "postamble": "", "tests": "[\n [\"Code is fixed\", 1, \"n == 10\"]\n]", "validation_tests": "[\n [\"Code is missing n\", \"'n' in locals()\"]\n]", "variables": "dict()"}}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always", "type": "question"}, {"name": "Area function", "extensions": ["mas-codeassess", "postmessage-to-parent", "programming"], "custom_part_types": [{"source": {"pk": 195, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/195/edit"}, "name": "Code", "short_name": "mark-code-3", "description": "

Mark code provided by the student by running it and a series of validation and marking tests.

\n

The validation tests are used to reject an answer if the student has misunderstood the task, for example if they haven't defined a required variable or function.

\n

Marking tests check properties of the student's code. Each test awards a proportion of the available credit if it is passed.

\n

You can optionally show the student the STDOUT and/or STDERR when running their code.

\n

You can give a preamble and postamble which are run before and after the student's code, and also modify the student's code before running it.

", "help_url": "", "input_widget": "code-editor", "input_options": {"correctAnswer": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"correct_answer\"])\n,\n settings[\"correct_answer\"]\n)", "hint": {"static": false, "value": "\"Write \"+capitalise(language_synonym(settings[\"code_language\"]))+\" code\""}, "language": {"static": false, "value": "language_synonym(settings[\"code_language\"])"}, "placeholder": {"static": false, "value": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"placeholder\"])\n,\n settings[\"placeholder\"]\n)"}, "theme": {"static": true, "value": "textmate"}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\napply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)\n\ninterpreted_answer:\nstudentAnswer\n\nmain_result:\ncode_result[3]\n\nmarking_results:\ncode_result[6..(len(settings[\"tests\"])+6)]\n\nvalidation_results:\ncode_result[(len(settings[\"tests\"])+6)..len(code_result)]\n\nmain_error:\nassert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)\n\nmarking_test_feedback:\nmap(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)\n\nvalidation_test_feedback:\nmap(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)\n\ntotal_weight:\nsum(map(weight,[name,weight,code],settings[\"tests\"]))\n\npre_submit:\nif(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)\n\ncode_result:\npre_submit[\"code_result\"]\n\nmain_stdout:\nsafe(main_result[\"stdout\"])\n\ncode_language:\nsettings[\"code_language\"]\n\npreamble_result:\ncode_result[2]\n\npreamble_stderr:\npreamble_result[\"stderr\"]\n\npostamble_result:\ncode_result[4]\n\npostamble_stderr:\npostamble_result[\"stderr\"]\n\npostamble_feedback:\nassert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)\n\nmatplotlib_preamble:\nif(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)\n\nmatplotlib_postamble:\nswitch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)\n\nmatplotlib_result:\ncode_result[5]\n\nmatplotlib_feedback:\nswitch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n\n\nimages:\nflatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))\n\nshow_images:\nassert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)", "marking_notes": [{"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "apply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "studentAnswer"}, {"name": "main_result", "description": "

The result of running the student's code and the preamble, without any tests.

\n

Normally used to detect errors in the student's code.

", "definition": "code_result[3]"}, {"name": "marking_results", "description": "

The results of running the marking tests.

", "definition": "code_result[6..(len(settings[\"tests\"])+6)]"}, {"name": "validation_results", "description": "

The results of running the validation tests.

", "definition": "code_result[(len(settings[\"tests\"])+6)..len(code_result)]"}, {"name": "main_error", "description": "

Show STDOUT if allowed.

\n

Check the student's code runs on its own. Fail if there was an error, and show STDERR if allowed.

", "definition": "assert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)"}, {"name": "marking_test_feedback", "description": "

Feedback on the marking tests. For each test, if the test was passed then add the corresponding amount of credit. If there was an error, show the error.

", "definition": "map(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)"}, {"name": "validation_test_feedback", "description": "

Give feedback on the validation tests. If any of them are not passed, the student's answer is invalid.

", "definition": "map(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)"}, {"name": "total_weight", "description": "

The sum of the weights of the marking tests. Each test's weight is divided by this to produce a proportion of the available credit.

", "definition": "sum(map(weight,[name,weight,code],settings[\"tests\"]))"}, {"name": "pre_submit", "description": "

The code blocks to run.

\n

In order, they are:

\n", "definition": "if(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)"}, {"name": "code_result", "description": "

The results of the code blocks: a list with an entry corresponding to each block of code.

", "definition": "pre_submit[\"code_result\"]"}, {"name": "main_stdout", "description": "

The stdout from the student's code.

", "definition": "safe(main_result[\"stdout\"])"}, {"name": "code_language", "description": "

The language the code is written in. Either \"pyodide\" (Python) or \"webr\" (R)

", "definition": "settings[\"code_language\"]"}, {"name": "preamble_result", "description": "

The result of running the preamble block.

", "definition": "code_result[2]"}, {"name": "preamble_stderr", "description": "

The STDERR produced by the preamble block.

", "definition": "preamble_result[\"stderr\"]"}, {"name": "postamble_result", "description": "

The result of running the postamble.

", "definition": "code_result[4]"}, {"name": "postamble_stderr", "description": "

The STDERR produced by the postamble block.

", "definition": "postamble_result[\"stderr\"]"}, {"name": "postamble_feedback", "description": "

Show the STDOUT from the postamble, if there is any.

", "definition": "assert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)"}, {"name": "matplotlib_preamble", "description": "

Preamble for a hack to ensure that figures produced by matplotlib in Python are displayed.

\n

This code clears the matplotlib output, if matplotlib has been loaded.

", "definition": "if(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_postamble", "description": "

A hack to show any figures produced with matplotlib in the stdout.

", "definition": "switch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_result", "description": "

The result of running the matplotlib hack.

", "definition": "code_result[5]"}, {"name": "matplotlib_feedback", "description": "

Feedback from the matplotlib hack: if a figure is produced, it's displayed as SVG here.

", "definition": "switch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n"}, {"name": "images", "description": "

Any images produced by the code blocks.

", "definition": "flatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))"}, {"name": "show_images", "description": "

Show the images produced by the code.

", "definition": "assert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)"}], "settings": [{"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "code_language", "label": "Code language", "help_url": "", "hint": "The language that the student's code will be written in.", "input_type": "dropdown", "default_value": "pyodide", "choices": [{"value": "pyodide", "label": "Python"}, {"value": "webr", "label": "R"}]}, {"name": "correct_answer", "label": "Correct answer", "help_url": "", "hint": "A correct answer to the part.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "correct_answer_subvars", "label": "Substitute question variables into the correct answer?", "help_url": "", "hint": "If ticked, then JME expressions between curly braces will be evaluated and substituted into the correct answer.

If not ticked, then the correct answer will be displayed exactly as it is.", "input_type": "checkbox", "default_value": true}, {"name": "show_stdout", "label": "Show stdout?", "help_url": "", "hint": "If ticked, the STDOUT produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_stderr", "label": "Show stderr?", "help_url": "", "hint": "If ticked, the STDERR produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_marking_errors", "label": "Show errors produced by marking tests?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "placeholder", "label": "Placeholder", "help_url": "", "hint": "Initial text for the code editor", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "modifier", "label": "Student code modifier", "help_url": "", "hint": "JME expression to modify the student's submitted code before being passed to the marking template. The student's code is available as the string variable studentAnswer.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "preamble", "label": "Preamble", "help_url": "", "hint": "This code is run before the student's code. Define anything that the student's code or your tests need.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble", "label": "Postamble", "help_url": "", "hint": "This code is run after the student's code but before the validation and unit tests.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble_feedback_whitespace", "label": "Format postamble output as code?", "help_url": "", "hint": "If ticked, any output produced by the postamble will be formatted in monospace font, with whitespace preserved. If not ticked, it'll be presented as prose text or HTML.", "input_type": "checkbox", "default_value": false}, {"name": "tests", "label": "Marking tests", "help_url": "", "hint": "A list of tests used to mark the student's answer.
Each item is a list with three values:
\n", "input_type": "code", "default_value": "[\n [\"Test 1\", 1, \"True\"]\n]", "evaluate": true}, {"name": "validation_tests", "label": "Validation tests", "help_url": "", "hint": "

A list of tests used to validate that the student's code is acceptable.
Each item is a list with two string values:

\n", "input_type": "code", "default_value": "[\n [\"arithmetic works\", \"1+1 == 2\"]\n]", "evaluate": true}, {"name": "variables", "label": "Variables to include in code", "help_url": "", "hint": "Give a dictionary mapping variable names to their values. These variables will be available in the code that is run.", "input_type": "code", "default_value": "dict()", "evaluate": true}], "public_availability": "always", "published": true, "extensions": ["programming"]}], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Josh Cowley", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/9358/"}, {"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true, "j": false}, "constants": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Write a Python function called area that returns the area of a circle given its radius.

", "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "import numpy as np\n\n# The function can be defined as follows (I've included some help)\n\ndef area(r):\n \"\"\"\n function that returns the area of a circle with radius r\n \"\"\"\n return np.pi*r**2", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "import numpy as np\n\n# Define your function below\n", "modifier": "", "preamble": "", "postamble": "", "postamble_feedback_whitespace": false, "tests": "[\n [\"area returns correct values\", 1, \"area(3)==np.pi*3**2\"]\n]", "validation_tests": "[\n [\"Make sure that you create a function called area\", \"'area' in locals()\"]\n]", "variables": "dict()"}}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always"}, {"name": "Quadratic roots function", "extensions": ["mas-codeassess", "programming"], "custom_part_types": [{"source": {"pk": 195, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/195/edit"}, "name": "Code", "short_name": "mark-code-3", "description": "

Mark code provided by the student by running it and a series of validation and marking tests.

\n

The validation tests are used to reject an answer if the student has misunderstood the task, for example if they haven't defined a required variable or function.

\n

Marking tests check properties of the student's code. Each test awards a proportion of the available credit if it is passed.

\n

You can optionally show the student the STDOUT and/or STDERR when running their code.

\n

You can give a preamble and postamble which are run before and after the student's code, and also modify the student's code before running it.

", "help_url": "", "input_widget": "code-editor", "input_options": {"correctAnswer": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"correct_answer\"])\n,\n settings[\"correct_answer\"]\n)", "hint": {"static": false, "value": "\"Write \"+capitalise(language_synonym(settings[\"code_language\"]))+\" code\""}, "language": {"static": false, "value": "language_synonym(settings[\"code_language\"])"}, "placeholder": {"static": false, "value": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"placeholder\"])\n,\n settings[\"placeholder\"]\n)"}, "theme": {"static": true, "value": "textmate"}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\napply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)\n\ninterpreted_answer:\nstudentAnswer\n\nmain_result:\ncode_result[3]\n\nmarking_results:\ncode_result[6..(len(settings[\"tests\"])+6)]\n\nvalidation_results:\ncode_result[(len(settings[\"tests\"])+6)..len(code_result)]\n\nmain_error:\nassert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)\n\nmarking_test_feedback:\nmap(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)\n\nvalidation_test_feedback:\nmap(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)\n\ntotal_weight:\nsum(map(weight,[name,weight,code],settings[\"tests\"]))\n\npre_submit:\nif(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)\n\ncode_result:\npre_submit[\"code_result\"]\n\nmain_stdout:\nsafe(main_result[\"stdout\"])\n\ncode_language:\nsettings[\"code_language\"]\n\npreamble_result:\ncode_result[2]\n\npreamble_stderr:\npreamble_result[\"stderr\"]\n\npostamble_result:\ncode_result[4]\n\npostamble_stderr:\npostamble_result[\"stderr\"]\n\npostamble_feedback:\nassert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)\n\nmatplotlib_preamble:\nif(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)\n\nmatplotlib_postamble:\nswitch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)\n\nmatplotlib_result:\ncode_result[5]\n\nmatplotlib_feedback:\nswitch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n\n\nimages:\nflatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))\n\nshow_images:\nassert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)", "marking_notes": [{"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "apply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "studentAnswer"}, {"name": "main_result", "description": "

The result of running the student's code and the preamble, without any tests.

\n

Normally used to detect errors in the student's code.

", "definition": "code_result[3]"}, {"name": "marking_results", "description": "

The results of running the marking tests.

", "definition": "code_result[6..(len(settings[\"tests\"])+6)]"}, {"name": "validation_results", "description": "

The results of running the validation tests.

", "definition": "code_result[(len(settings[\"tests\"])+6)..len(code_result)]"}, {"name": "main_error", "description": "

Show STDOUT if allowed.

\n

Check the student's code runs on its own. Fail if there was an error, and show STDERR if allowed.

", "definition": "assert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)"}, {"name": "marking_test_feedback", "description": "

Feedback on the marking tests. For each test, if the test was passed then add the corresponding amount of credit. If there was an error, show the error.

", "definition": "map(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)"}, {"name": "validation_test_feedback", "description": "

Give feedback on the validation tests. If any of them are not passed, the student's answer is invalid.

", "definition": "map(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)"}, {"name": "total_weight", "description": "

The sum of the weights of the marking tests. Each test's weight is divided by this to produce a proportion of the available credit.

", "definition": "sum(map(weight,[name,weight,code],settings[\"tests\"]))"}, {"name": "pre_submit", "description": "

The code blocks to run.

\n

In order, they are:

\n", "definition": "if(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)"}, {"name": "code_result", "description": "

The results of the code blocks: a list with an entry corresponding to each block of code.

", "definition": "pre_submit[\"code_result\"]"}, {"name": "main_stdout", "description": "

The stdout from the student's code.

", "definition": "safe(main_result[\"stdout\"])"}, {"name": "code_language", "description": "

The language the code is written in. Either \"pyodide\" (Python) or \"webr\" (R)

", "definition": "settings[\"code_language\"]"}, {"name": "preamble_result", "description": "

The result of running the preamble block.

", "definition": "code_result[2]"}, {"name": "preamble_stderr", "description": "

The STDERR produced by the preamble block.

", "definition": "preamble_result[\"stderr\"]"}, {"name": "postamble_result", "description": "

The result of running the postamble.

", "definition": "code_result[4]"}, {"name": "postamble_stderr", "description": "

The STDERR produced by the postamble block.

", "definition": "postamble_result[\"stderr\"]"}, {"name": "postamble_feedback", "description": "

Show the STDOUT from the postamble, if there is any.

", "definition": "assert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)"}, {"name": "matplotlib_preamble", "description": "

Preamble for a hack to ensure that figures produced by matplotlib in Python are displayed.

\n

This code clears the matplotlib output, if matplotlib has been loaded.

", "definition": "if(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_postamble", "description": "

A hack to show any figures produced with matplotlib in the stdout.

", "definition": "switch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_result", "description": "

The result of running the matplotlib hack.

", "definition": "code_result[5]"}, {"name": "matplotlib_feedback", "description": "

Feedback from the matplotlib hack: if a figure is produced, it's displayed as SVG here.

", "definition": "switch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n"}, {"name": "images", "description": "

Any images produced by the code blocks.

", "definition": "flatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))"}, {"name": "show_images", "description": "

Show the images produced by the code.

", "definition": "assert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)"}], "settings": [{"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "code_language", "label": "Code language", "help_url": "", "hint": "The language that the student's code will be written in.", "input_type": "dropdown", "default_value": "pyodide", "choices": [{"value": "pyodide", "label": "Python"}, {"value": "webr", "label": "R"}]}, {"name": "correct_answer", "label": "Correct answer", "help_url": "", "hint": "A correct answer to the part.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "correct_answer_subvars", "label": "Substitute question variables into the correct answer?", "help_url": "", "hint": "If ticked, then JME expressions between curly braces will be evaluated and substituted into the correct answer.

If not ticked, then the correct answer will be displayed exactly as it is.", "input_type": "checkbox", "default_value": true}, {"name": "show_stdout", "label": "Show stdout?", "help_url": "", "hint": "If ticked, the STDOUT produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_stderr", "label": "Show stderr?", "help_url": "", "hint": "If ticked, the STDERR produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_marking_errors", "label": "Show errors produced by marking tests?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "placeholder", "label": "Placeholder", "help_url": "", "hint": "Initial text for the code editor", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "modifier", "label": "Student code modifier", "help_url": "", "hint": "JME expression to modify the student's submitted code before being passed to the marking template. The student's code is available as the string variable studentAnswer.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "preamble", "label": "Preamble", "help_url": "", "hint": "This code is run before the student's code. Define anything that the student's code or your tests need.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble", "label": "Postamble", "help_url": "", "hint": "This code is run after the student's code but before the validation and unit tests.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble_feedback_whitespace", "label": "Format postamble output as code?", "help_url": "", "hint": "If ticked, any output produced by the postamble will be formatted in monospace font, with whitespace preserved. If not ticked, it'll be presented as prose text or HTML.", "input_type": "checkbox", "default_value": false}, {"name": "tests", "label": "Marking tests", "help_url": "", "hint": "A list of tests used to mark the student's answer.
Each item is a list with three values:
\n", "input_type": "code", "default_value": "[\n [\"Test 1\", 1, \"True\"]\n]", "evaluate": true}, {"name": "validation_tests", "label": "Validation tests", "help_url": "", "hint": "

A list of tests used to validate that the student's code is acceptable.
Each item is a list with two string values:

\n", "input_type": "code", "default_value": "[\n [\"arithmetic works\", \"1+1 == 2\"]\n]", "evaluate": true}, {"name": "variables", "label": "Variables to include in code", "help_url": "", "hint": "Give a dictionary mapping variable names to their values. These variables will be available in the code that is run.", "input_type": "code", "default_value": "dict()", "evaluate": true}], "public_availability": "always", "published": true, "extensions": ["programming"]}], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Josh Cowley", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/9358/"}, {"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "", "advice": "", "rulesets": {}, "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true, "j": false}, "constants": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Write a function real_roots that applies the quadratic formula to return the real root(s) of a quadratic $ax^2+bx+c$, given coefficients $a$, $b$ and $c$.

\n", "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "import numpy as np\n\ndef real_roots(a,b,c):\n \"\"\"\n returns the real roots of a quadratic ax^2+bx+c\n \"\"\"\n\n # List to store the roots in (will remain empty if no real roots)\n roots = []\n\n # Calculate discriminant\n d = b**2 - 4*a*c\n\n if d == 0:\n roots.append(-b/(2*a))\n if d > 0:\n roots.append((-b+np.sqrt(d))/(2*a))\n roots.append((-b-np.sqrt(d))/(2*a))\n\n return roots", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": true, "show_marking_errors": false, "placeholder": "# Define your function below\n", "modifier": "", "preamble": "import numpy as np", "postamble": "", "postamble_feedback_whitespace": false, "tests": "[\n [\"Two real roots correct\", 0.5, \"real_roots(2,-11,5)==list([5.0, 0.5]) or real_roots(2,-11,5)==list([0.5,5.0])\"],\n [\"One real root correct\", 0.25, \"real_roots(-4,12,-9)==[1.5] or real_roots(-4,12,-9)==1.5\"],\n [\"No real roots correct\", 0.25, \"real_roots(1,-3,4)==[]\"]\n]", "validation_tests": "[\n [\"Make sure that you create a function called real_roots\", \"'real_roots' in locals()\"]\n]", "variables": "dict()"}}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always"}]}, {"name": "Bonus questions", "pickingStrategy": "all-ordered", "pickQuestions": 1, "questionNames": ["", ""], "variable_overrides": [[], []], "questions": [{"name": "Rock paper scissors", "extensions": ["mas-codeassess", "programming"], "custom_part_types": [{"source": {"pk": 195, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/195/edit"}, "name": "Code", "short_name": "mark-code-3", "description": "

Mark code provided by the student by running it and a series of validation and marking tests.

\n

The validation tests are used to reject an answer if the student has misunderstood the task, for example if they haven't defined a required variable or function.

\n

Marking tests check properties of the student's code. Each test awards a proportion of the available credit if it is passed.

\n

You can optionally show the student the STDOUT and/or STDERR when running their code.

\n

You can give a preamble and postamble which are run before and after the student's code, and also modify the student's code before running it.

", "help_url": "", "input_widget": "code-editor", "input_options": {"correctAnswer": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"correct_answer\"])\n,\n settings[\"correct_answer\"]\n)", "hint": {"static": false, "value": "\"Write \"+capitalise(language_synonym(settings[\"code_language\"]))+\" code\""}, "language": {"static": false, "value": "language_synonym(settings[\"code_language\"])"}, "placeholder": {"static": false, "value": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"placeholder\"])\n,\n settings[\"placeholder\"]\n)"}, "theme": {"static": true, "value": "textmate"}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\napply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)\n\ninterpreted_answer:\nstudentAnswer\n\nmain_result:\ncode_result[3]\n\nmarking_results:\ncode_result[6..(len(settings[\"tests\"])+6)]\n\nvalidation_results:\ncode_result[(len(settings[\"tests\"])+6)..len(code_result)]\n\nmain_error:\nassert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)\n\nmarking_test_feedback:\nmap(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)\n\nvalidation_test_feedback:\nmap(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)\n\ntotal_weight:\nsum(map(weight,[name,weight,code],settings[\"tests\"]))\n\npre_submit:\nif(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)\n\ncode_result:\npre_submit[\"code_result\"]\n\nmain_stdout:\nsafe(main_result[\"stdout\"])\n\ncode_language:\nsettings[\"code_language\"]\n\npreamble_result:\ncode_result[2]\n\npreamble_stderr:\npreamble_result[\"stderr\"]\n\npostamble_result:\ncode_result[4]\n\npostamble_stderr:\npostamble_result[\"stderr\"]\n\npostamble_feedback:\nassert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)\n\nmatplotlib_preamble:\nif(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)\n\nmatplotlib_postamble:\nswitch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)\n\nmatplotlib_result:\ncode_result[5]\n\nmatplotlib_feedback:\nswitch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n\n\nimages:\nflatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))\n\nshow_images:\nassert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)", "marking_notes": [{"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "apply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "studentAnswer"}, {"name": "main_result", "description": "

The result of running the student's code and the preamble, without any tests.

\n

Normally used to detect errors in the student's code.

", "definition": "code_result[3]"}, {"name": "marking_results", "description": "

The results of running the marking tests.

", "definition": "code_result[6..(len(settings[\"tests\"])+6)]"}, {"name": "validation_results", "description": "

The results of running the validation tests.

", "definition": "code_result[(len(settings[\"tests\"])+6)..len(code_result)]"}, {"name": "main_error", "description": "

Show STDOUT if allowed.

\n

Check the student's code runs on its own. Fail if there was an error, and show STDERR if allowed.

", "definition": "assert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)"}, {"name": "marking_test_feedback", "description": "

Feedback on the marking tests. For each test, if the test was passed then add the corresponding amount of credit. If there was an error, show the error.

", "definition": "map(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)"}, {"name": "validation_test_feedback", "description": "

Give feedback on the validation tests. If any of them are not passed, the student's answer is invalid.

", "definition": "map(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)"}, {"name": "total_weight", "description": "

The sum of the weights of the marking tests. Each test's weight is divided by this to produce a proportion of the available credit.

", "definition": "sum(map(weight,[name,weight,code],settings[\"tests\"]))"}, {"name": "pre_submit", "description": "

The code blocks to run.

\n

In order, they are:

\n", "definition": "if(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)"}, {"name": "code_result", "description": "

The results of the code blocks: a list with an entry corresponding to each block of code.

", "definition": "pre_submit[\"code_result\"]"}, {"name": "main_stdout", "description": "

The stdout from the student's code.

", "definition": "safe(main_result[\"stdout\"])"}, {"name": "code_language", "description": "

The language the code is written in. Either \"pyodide\" (Python) or \"webr\" (R)

", "definition": "settings[\"code_language\"]"}, {"name": "preamble_result", "description": "

The result of running the preamble block.

", "definition": "code_result[2]"}, {"name": "preamble_stderr", "description": "

The STDERR produced by the preamble block.

", "definition": "preamble_result[\"stderr\"]"}, {"name": "postamble_result", "description": "

The result of running the postamble.

", "definition": "code_result[4]"}, {"name": "postamble_stderr", "description": "

The STDERR produced by the postamble block.

", "definition": "postamble_result[\"stderr\"]"}, {"name": "postamble_feedback", "description": "

Show the STDOUT from the postamble, if there is any.

", "definition": "assert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)"}, {"name": "matplotlib_preamble", "description": "

Preamble for a hack to ensure that figures produced by matplotlib in Python are displayed.

\n

This code clears the matplotlib output, if matplotlib has been loaded.

", "definition": "if(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_postamble", "description": "

A hack to show any figures produced with matplotlib in the stdout.

", "definition": "switch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_result", "description": "

The result of running the matplotlib hack.

", "definition": "code_result[5]"}, {"name": "matplotlib_feedback", "description": "

Feedback from the matplotlib hack: if a figure is produced, it's displayed as SVG here.

", "definition": "switch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n"}, {"name": "images", "description": "

Any images produced by the code blocks.

", "definition": "flatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))"}, {"name": "show_images", "description": "

Show the images produced by the code.

", "definition": "assert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)"}], "settings": [{"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "code_language", "label": "Code language", "help_url": "", "hint": "The language that the student's code will be written in.", "input_type": "dropdown", "default_value": "pyodide", "choices": [{"value": "pyodide", "label": "Python"}, {"value": "webr", "label": "R"}]}, {"name": "correct_answer", "label": "Correct answer", "help_url": "", "hint": "A correct answer to the part.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "correct_answer_subvars", "label": "Substitute question variables into the correct answer?", "help_url": "", "hint": "If ticked, then JME expressions between curly braces will be evaluated and substituted into the correct answer.

If not ticked, then the correct answer will be displayed exactly as it is.", "input_type": "checkbox", "default_value": true}, {"name": "show_stdout", "label": "Show stdout?", "help_url": "", "hint": "If ticked, the STDOUT produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_stderr", "label": "Show stderr?", "help_url": "", "hint": "If ticked, the STDERR produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_marking_errors", "label": "Show errors produced by marking tests?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "placeholder", "label": "Placeholder", "help_url": "", "hint": "Initial text for the code editor", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "modifier", "label": "Student code modifier", "help_url": "", "hint": "JME expression to modify the student's submitted code before being passed to the marking template. The student's code is available as the string variable studentAnswer.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "preamble", "label": "Preamble", "help_url": "", "hint": "This code is run before the student's code. Define anything that the student's code or your tests need.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble", "label": "Postamble", "help_url": "", "hint": "This code is run after the student's code but before the validation and unit tests.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble_feedback_whitespace", "label": "Format postamble output as code?", "help_url": "", "hint": "If ticked, any output produced by the postamble will be formatted in monospace font, with whitespace preserved. If not ticked, it'll be presented as prose text or HTML.", "input_type": "checkbox", "default_value": false}, {"name": "tests", "label": "Marking tests", "help_url": "", "hint": "A list of tests used to mark the student's answer.
Each item is a list with three values:
\n", "input_type": "code", "default_value": "[\n [\"Test 1\", 1, \"True\"]\n]", "evaluate": true}, {"name": "validation_tests", "label": "Validation tests", "help_url": "", "hint": "

A list of tests used to validate that the student's code is acceptable.
Each item is a list with two string values:

\n", "input_type": "code", "default_value": "[\n [\"arithmetic works\", \"1+1 == 2\"]\n]", "evaluate": true}, {"name": "variables", "label": "Variables to include in code", "help_url": "", "hint": "Give a dictionary mapping variable names to their values. These variables will be available in the code that is run.", "input_type": "code", "default_value": "dict()", "evaluate": true}], "public_availability": "always", "published": true, "extensions": ["programming"]}], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Josh Cowley", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/9358/"}, {"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "tags": [], "metadata": {"description": "", "licence": "None specified"}, "statement": "

Consider the pseudocode for playing rock-paper-scissors:

\n
while game is not over:
p1 = player 1 select from [rock,paper,scissors]
p2 = player 2 select from [rock,paper,scissors]
if p1 == p2
continue playing
else
if p1 value beats p2 value
p1 wins, finish playing
else
p2 wins, finish playing
game over
", "advice": "", "rulesets": {}, "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true, "j": false}, "constants": [], "variables": {"code": {"name": "code", "group": "Ungrouped variables", "definition": "safe('game_on = True\nwhile game_on:\n\n # Players reveal\n p1 = reveal()\n p2 = reveal()\n print(\"Player 1: {}, Player 2: {}\".format(p1,p2))\n\n # Get the result\n res = result(p1,p2)\n if(res != 0):\n game_on = False\n print(\"The winner was player {}\".format(res))')", "description": "", "templateType": "anything", "can_override": false}}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": ["code"], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Take a look at the help for the NumPy function np.random.choice and use this to create a function reveal which returns a random value from 'rock', 'paper' or 'scissors'.

", "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "import numpy as np\n\ndef reveal():\n return np.random.choice([\"rock\",\"paper\",\"scissors\"])", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "import numpy as np\n\ndef reveal():\n # Complete the function\n return ", "modifier": "", "preamble": "", "postamble": "try:\n x = []\n for n in range(10000): \n x.append(reveal().lower())\n rocks = len([v for v in x if v=='rock'])\n scissors = len([v for v in x if v=='scissors'])\n papers = len([v for v in x if v=='paper'])\nexcept:\n pass", "postamble_feedback_whitespace": false, "tests": "[\n [\"Single value returns 'rock', 'paper' or 'scissors'\", 0.5, \"reveal().lower() in ['rock','paper','scissors']\"],\n [\"Your function appears to return random values\", 0.5, \"all([v > 2500 for v in [rocks,scissors,papers]])\"]\n]", "validation_tests": "[\n [\"Make sure that you create a function called reveal\", \"'reveal' in locals()\"],\n [\"Make sure that your function returns a string (or Numpy string) object\", \"isinstance(reveal(),str)\"]\n]\n", "variables": "dict()"}}, {"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Consider the following code:

\n
p1 = reveal() # sets p1 choice
p2 = reveal() # sets p2 choice
result(p1,p2)
\n

Write a function result(p1,p2) that returns an integer value

\n", "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "def result(p1,p2):\n if p1 == p2:\n return 0\n else:\n if p1 == 'rock' and p2 == 'scissors' \\\n or p1 == 'scissors' and p2 == 'paper' \\\n or p1 == 'paper' and p2 == 'rock':\n return 1\n else:\n return 2", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "def result():\n # Complete the function\n return ", "modifier": "", "preamble": "", "postamble": "", "postamble_feedback_whitespace": false, "tests": "[\n [\"result('scissors','scissors') returns 0\", 0.2, \"result('scissors','scissors')==0\"],\n [\"result('paper','scissors') returns 2\", 0.4, \"result('paper','scissors')==2\"],\n [\"result('rock','scissors') returns 1\", 0.4, \"result('rock','scissors')==1\"]\n]", "validation_tests": "[\n [\"Make sure that you create a function called result\", \"'result' in locals()\"]\n]", "variables": "dict()"}}, {"type": "information", "useCustomName": true, "customName": "c)", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

You should now be in a position to complete the function. Try this out with your functions in Spyder:

\n
{code}
"}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always"}, {"name": "Algorithm and function is_prime", "extensions": ["iframe-resize", "mas-codeassess", "programming"], "custom_part_types": [{"source": {"pk": 195, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/195/edit"}, "name": "Code", "short_name": "mark-code-3", "description": "

Mark code provided by the student by running it and a series of validation and marking tests.

\n

The validation tests are used to reject an answer if the student has misunderstood the task, for example if they haven't defined a required variable or function.

\n

Marking tests check properties of the student's code. Each test awards a proportion of the available credit if it is passed.

\n

You can optionally show the student the STDOUT and/or STDERR when running their code.

\n

You can give a preamble and postamble which are run before and after the student's code, and also modify the student's code before running it.

", "help_url": "", "input_widget": "code-editor", "input_options": {"correctAnswer": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"correct_answer\"])\n,\n settings[\"correct_answer\"]\n)", "hint": {"static": false, "value": "\"Write \"+capitalise(language_synonym(settings[\"code_language\"]))+\" code\""}, "language": {"static": false, "value": "language_synonym(settings[\"code_language\"])"}, "placeholder": {"static": false, "value": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"placeholder\"])\n,\n settings[\"placeholder\"]\n)"}, "theme": {"static": true, "value": "textmate"}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\napply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)\n\ninterpreted_answer:\nstudentAnswer\n\nmain_result:\ncode_result[3]\n\nmarking_results:\ncode_result[6..(len(settings[\"tests\"])+6)]\n\nvalidation_results:\ncode_result[(len(settings[\"tests\"])+6)..len(code_result)]\n\nmain_error:\nassert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)\n\nmarking_test_feedback:\nmap(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)\n\nvalidation_test_feedback:\nmap(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)\n\ntotal_weight:\nsum(map(weight,[name,weight,code],settings[\"tests\"]))\n\npre_submit:\nif(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)\n\ncode_result:\npre_submit[\"code_result\"]\n\nmain_stdout:\nsafe(main_result[\"stdout\"])\n\ncode_language:\nsettings[\"code_language\"]\n\npreamble_result:\ncode_result[2]\n\npreamble_stderr:\npreamble_result[\"stderr\"]\n\npostamble_result:\ncode_result[4]\n\npostamble_stderr:\npostamble_result[\"stderr\"]\n\npostamble_feedback:\nassert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)\n\nmatplotlib_preamble:\nif(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)\n\nmatplotlib_postamble:\nswitch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)\n\nmatplotlib_result:\ncode_result[5]\n\nmatplotlib_feedback:\nswitch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n\n\nimages:\nflatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))\n\nshow_images:\nassert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)", "marking_notes": [{"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "apply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "studentAnswer"}, {"name": "main_result", "description": "

The result of running the student's code and the preamble, without any tests.

\n

Normally used to detect errors in the student's code.

", "definition": "code_result[3]"}, {"name": "marking_results", "description": "

The results of running the marking tests.

", "definition": "code_result[6..(len(settings[\"tests\"])+6)]"}, {"name": "validation_results", "description": "

The results of running the validation tests.

", "definition": "code_result[(len(settings[\"tests\"])+6)..len(code_result)]"}, {"name": "main_error", "description": "

Show STDOUT if allowed.

\n

Check the student's code runs on its own. Fail if there was an error, and show STDERR if allowed.

", "definition": "assert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)"}, {"name": "marking_test_feedback", "description": "

Feedback on the marking tests. For each test, if the test was passed then add the corresponding amount of credit. If there was an error, show the error.

", "definition": "map(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)"}, {"name": "validation_test_feedback", "description": "

Give feedback on the validation tests. If any of them are not passed, the student's answer is invalid.

", "definition": "map(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)"}, {"name": "total_weight", "description": "

The sum of the weights of the marking tests. Each test's weight is divided by this to produce a proportion of the available credit.

", "definition": "sum(map(weight,[name,weight,code],settings[\"tests\"]))"}, {"name": "pre_submit", "description": "

The code blocks to run.

\n

In order, they are:

\n", "definition": "if(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)"}, {"name": "code_result", "description": "

The results of the code blocks: a list with an entry corresponding to each block of code.

", "definition": "pre_submit[\"code_result\"]"}, {"name": "main_stdout", "description": "

The stdout from the student's code.

", "definition": "safe(main_result[\"stdout\"])"}, {"name": "code_language", "description": "

The language the code is written in. Either \"pyodide\" (Python) or \"webr\" (R)

", "definition": "settings[\"code_language\"]"}, {"name": "preamble_result", "description": "

The result of running the preamble block.

", "definition": "code_result[2]"}, {"name": "preamble_stderr", "description": "

The STDERR produced by the preamble block.

", "definition": "preamble_result[\"stderr\"]"}, {"name": "postamble_result", "description": "

The result of running the postamble.

", "definition": "code_result[4]"}, {"name": "postamble_stderr", "description": "

The STDERR produced by the postamble block.

", "definition": "postamble_result[\"stderr\"]"}, {"name": "postamble_feedback", "description": "

Show the STDOUT from the postamble, if there is any.

", "definition": "assert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)"}, {"name": "matplotlib_preamble", "description": "

Preamble for a hack to ensure that figures produced by matplotlib in Python are displayed.

\n

This code clears the matplotlib output, if matplotlib has been loaded.

", "definition": "if(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_postamble", "description": "

A hack to show any figures produced with matplotlib in the stdout.

", "definition": "switch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_result", "description": "

The result of running the matplotlib hack.

", "definition": "code_result[5]"}, {"name": "matplotlib_feedback", "description": "

Feedback from the matplotlib hack: if a figure is produced, it's displayed as SVG here.

", "definition": "switch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n"}, {"name": "images", "description": "

Any images produced by the code blocks.

", "definition": "flatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))"}, {"name": "show_images", "description": "

Show the images produced by the code.

", "definition": "assert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)"}], "settings": [{"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "code_language", "label": "Code language", "help_url": "", "hint": "The language that the student's code will be written in.", "input_type": "dropdown", "default_value": "pyodide", "choices": [{"value": "pyodide", "label": "Python"}, {"value": "webr", "label": "R"}]}, {"name": "correct_answer", "label": "Correct answer", "help_url": "", "hint": "A correct answer to the part.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "correct_answer_subvars", "label": "Substitute question variables into the correct answer?", "help_url": "", "hint": "If ticked, then JME expressions between curly braces will be evaluated and substituted into the correct answer.

If not ticked, then the correct answer will be displayed exactly as it is.", "input_type": "checkbox", "default_value": true}, {"name": "show_stdout", "label": "Show stdout?", "help_url": "", "hint": "If ticked, the STDOUT produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_stderr", "label": "Show stderr?", "help_url": "", "hint": "If ticked, the STDERR produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_marking_errors", "label": "Show errors produced by marking tests?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "placeholder", "label": "Placeholder", "help_url": "", "hint": "Initial text for the code editor", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "modifier", "label": "Student code modifier", "help_url": "", "hint": "JME expression to modify the student's submitted code before being passed to the marking template. The student's code is available as the string variable studentAnswer.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "preamble", "label": "Preamble", "help_url": "", "hint": "This code is run before the student's code. Define anything that the student's code or your tests need.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble", "label": "Postamble", "help_url": "", "hint": "This code is run after the student's code but before the validation and unit tests.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble_feedback_whitespace", "label": "Format postamble output as code?", "help_url": "", "hint": "If ticked, any output produced by the postamble will be formatted in monospace font, with whitespace preserved. If not ticked, it'll be presented as prose text or HTML.", "input_type": "checkbox", "default_value": false}, {"name": "tests", "label": "Marking tests", "help_url": "", "hint": "A list of tests used to mark the student's answer.
Each item is a list with three values:
\n", "input_type": "code", "default_value": "[\n [\"Test 1\", 1, \"True\"]\n]", "evaluate": true}, {"name": "validation_tests", "label": "Validation tests", "help_url": "", "hint": "

A list of tests used to validate that the student's code is acceptable.
Each item is a list with two string values:

\n", "input_type": "code", "default_value": "[\n [\"arithmetic works\", \"1+1 == 2\"]\n]", "evaluate": true}, {"name": "variables", "label": "Variables to include in code", "help_url": "", "hint": "Give a dictionary mapping variable names to their values. These variables will be available in the code that is run.", "input_type": "code", "default_value": "dict()", "evaluate": true}], "public_availability": "always", "published": true, "extensions": ["programming"]}], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Josh Cowley", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/9358/"}, {"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "tags": [], "metadata": {"description": "", "licence": "All rights reserved"}, "statement": "

Consider the task of creating a function that answers the question 'is the integer $n$ prime?'.

\n

\n
", "advice": "", "rulesets": {}, "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true, "j": false}, "constants": [], "variables": {}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "information", "useCustomName": true, "customName": "a)", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Let's set out the task:

\n\n

The following is a pseudocode sketch of the algorithm:

\n
start with an integer number n\nif n is <= 1, then n is not prime\nif n is > 1\n  Assume n is prime unless we later find it isn't: so set n_prime = True\n  for i = each number between 2 and n-1\n     if n modulo i is 0\n        n_prime = False\n        exit the for loop (break)\n  return the value of n_prime
"}, {"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Complete the following function is_prime which takes in an integer $n$ and returns either True or False in response to the question 'is $n$ prime?'.

", "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "def is_prime(n):\n \"\"\"\n Function that asks \"is n prime?\"\n \"\"\"\n # if n > 1 check n % i between 2 and n-1\n if n > 1:\n # assume n is prime unless we find otherwise\n n_prime = True\n for i in range(2,n):\n # is n mod i = 0?\n if n % i == 0:\n n_prime = False\n break # the code will work without this, but there's no point in continuing\n # if n <= 1 then n is not prime\n else:\n n_prime = False\n\n # return True or False\n return n_prime", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "def is_prime(n):\n if n > 1: \n # Complete me to set n_prime\n else:\n # Complete me to set n_prime\n return n_prime", "modifier": "", "preamble": "", "postamble": "", "postamble_feedback_whitespace": false, "tests": "[\n [\"is_prime returns accurate values\", 1, \"is_prime(2) and is_prime(19) and is_prime(97) and not is_prime(1) and not is_prime(6)\"]\n]", "validation_tests": "[\n [\"Make sure that you create a function called is_prime\", \"'is_prime' in locals()\"]\n]", "variables": "dict()"}}, {"type": "mark-code-3", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Use your function and a for loop to create a list of the prime numbers between $1$ and $200$ (you can assume is_prime is defined correctly, so can attempt this even if you didn't complete a).

", "settings": {"show_input_hint": true, "code_language": "pyodide", "correct_answer": "# Create a list to store the primes in\nprimes = []\n\n# Loop through from 0 to 199 (2 to 199 would be fine too)\nfor i in range(0,200):\n # if prime add to the list\n if is_prime(i):\n primes.append(i)\n\nprint(primes)", "correct_answer_subvars": true, "show_stdout": true, "show_stderr": false, "show_marking_errors": false, "placeholder": "# List to store the prime numbers in\nprimes = []\n\nfor # Complete this!", "modifier": "", "preamble": "# Required function from previous part\ndef is_prime(n):\n if n > 1: \n n_prime = True \n for i in range(2,n):\n if n % i == 0:\n n_prime = False \n else:\n n_prime = False\n return n_prime", "postamble": "primes_correct = []\nfor i in range(0,200):\n if is_prime(i):\n primes_correct.append(i)", "postamble_feedback_whitespace": false, "tests": "[\n [\"Correct primes found\", 1, \"primes == primes_correct\"]\n]", "validation_tests": "[\n [\"Make sure primes is set\", \"'primes' in locals()\"]\n]", "variables": "dict()"}}, {"type": "gapfill", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

What percentage of numbers between $1$ and $10000$ are prime?

\n

[[0]]%  round your answer to the nearest 1%

", "gaps": [{"type": "numberentry", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "minValue": "12", "maxValue": "12", "correctAnswerFraction": false, "allowFractions": false, "mustBeReduced": false, "mustBeReducedPC": 0, "displayAnswer": "", "showFractionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}], "sortAnswers": false}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always"}]}], "allowPrinting": true, "navigation": {"allowregen": true, "reverse": true, "browse": true, "allowsteps": true, "showfrontpage": false, "navigatemode": "sequence", "onleave": {"action": "none", "message": ""}, "preventleave": true, "typeendtoleave": false, "startpassword": "", "autoSubmit": true, "allowAttemptDownload": false, "downloadEncryptionKey": "", "showresultspage": "oncompletion"}, "timing": {"allowPause": true, "timeout": {"action": "none", "message": ""}, "timedwarning": {"action": "none", "message": ""}}, "feedback": {"enterreviewmodeimmediately": true, "showactualmarkwhen": "always", "showtotalmarkwhen": "always", "showanswerstatewhen": "always", "showpartfeedbackmessageswhen": "always", "showexpectedanswerswhen": "inreview", "showadvicewhen": "inreview", "allowrevealanswer": true, "intro": "", "end_message": "", "results_options": {"printquestions": true, "printadvice": true}, "feedbackmessages": [], "reviewshowexpectedanswer": true, "showanswerstate": true, "reviewshowfeedback": true, "showactualmark": true, "showtotalmark": true, "reviewshowscore": true, "reviewshowadvice": true}, "diagnostic": {"knowledge_graph": {"topics": [], "learning_objectives": []}, "script": "diagnosys", "customScript": ""}, "contributors": [{"name": "Will Rushworth", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/20560/"}], "extensions": ["iframe-resize", "mas-codeassess", "postmessage-to-parent", "programming"], "custom_part_types": [{"source": {"pk": 195, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/195/edit"}, "name": "Code", "short_name": "mark-code-3", "description": "

Mark code provided by the student by running it and a series of validation and marking tests.

\n

The validation tests are used to reject an answer if the student has misunderstood the task, for example if they haven't defined a required variable or function.

\n

Marking tests check properties of the student's code. Each test awards a proportion of the available credit if it is passed.

\n

You can optionally show the student the STDOUT and/or STDERR when running their code.

\n

You can give a preamble and postamble which are run before and after the student's code, and also modify the student's code before running it.

", "help_url": "", "input_widget": "code-editor", "input_options": {"correctAnswer": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"correct_answer\"])\n,\n settings[\"correct_answer\"]\n)", "hint": {"static": false, "value": "\"Write \"+capitalise(language_synonym(settings[\"code_language\"]))+\" code\""}, "language": {"static": false, "value": "language_synonym(settings[\"code_language\"])"}, "placeholder": {"static": false, "value": "if(settings[\"correct_answer_subvars\"],\n render(settings[\"placeholder\"])\n,\n settings[\"placeholder\"]\n)"}, "theme": {"static": true, "value": "textmate"}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\napply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)\n\ninterpreted_answer:\nstudentAnswer\n\nmain_result:\ncode_result[3]\n\nmarking_results:\ncode_result[6..(len(settings[\"tests\"])+6)]\n\nvalidation_results:\ncode_result[(len(settings[\"tests\"])+6)..len(code_result)]\n\nmain_error:\nassert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)\n\nmarking_test_feedback:\nmap(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)\n\nvalidation_test_feedback:\nmap(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)\n\ntotal_weight:\nsum(map(weight,[name,weight,code],settings[\"tests\"]))\n\npre_submit:\nif(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)\n\ncode_result:\npre_submit[\"code_result\"]\n\nmain_stdout:\nsafe(main_result[\"stdout\"])\n\ncode_language:\nsettings[\"code_language\"]\n\npreamble_result:\ncode_result[2]\n\npreamble_stderr:\npreamble_result[\"stderr\"]\n\npostamble_result:\ncode_result[4]\n\npostamble_stderr:\npostamble_result[\"stderr\"]\n\npostamble_feedback:\nassert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)\n\nmatplotlib_preamble:\nif(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)\n\nmatplotlib_postamble:\nswitch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)\n\nmatplotlib_result:\ncode_result[5]\n\nmatplotlib_feedback:\nswitch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n\n\nimages:\nflatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))\n\nshow_images:\nassert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)", "marking_notes": [{"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "apply(main_error);\napply(show_images);\napply(matplotlib_feedback);\napply(postamble_feedback);\napply(validation_test_feedback);\napply(marking_test_feedback)"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "studentAnswer"}, {"name": "main_result", "description": "

The result of running the student's code and the preamble, without any tests.

\n

Normally used to detect errors in the student's code.

", "definition": "code_result[3]"}, {"name": "marking_results", "description": "

The results of running the marking tests.

", "definition": "code_result[6..(len(settings[\"tests\"])+6)]"}, {"name": "validation_results", "description": "

The results of running the validation tests.

", "definition": "code_result[(len(settings[\"tests\"])+6)..len(code_result)]"}, {"name": "main_error", "description": "

Show STDOUT if allowed.

\n

Check the student's code runs on its own. Fail if there was an error, and show STDERR if allowed.

", "definition": "assert(main_stdout=\"\" or not settings[\"show_stdout\"],\n feedback(\"Your code produced this output:
{escape_html(main_stdout)}
\")\n);\nassert(main_result[\"success\"],\n warn(\"\"\"There was an error in your code.\"\"\");\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in your code:
{escape_html(main_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in your code.\")\n )\n)"}, {"name": "marking_test_feedback", "description": "

Feedback on the marking tests. For each test, if the test was passed then add the corresponding amount of credit. If there was an error, show the error.

", "definition": "map(\n let(\n [name,weight,code], test,\n header, \"Test: {name} \",\n if(r[\"success\"],\n let(\n result, r[\"result\"],\n max_credit, weight/total_weight,\n credit, if(result isa \"number\", result, award(1,result)),\n switch(\n credit=0, negative_feedback(header+\"was not passed.\"),\n credit=1, add_credit(max_credit, header+\"was passed.\"),\n add_credit(credit*max_credit, header+\"was partially passed.\")\n )\n )\n ,\n if(settings[\"show_marking_errors\"],\n negative_feedback(\"\"\"There was an error:
{escape_html(r[\"stderr\"])}
\"\"\")\n ,\n negative_feedback(header+\"was not passed.\")\n )\n )\n ),\n [test,r],\n zip(settings[\"tests\"],marking_results)\n)"}, {"name": "validation_test_feedback", "description": "

Give feedback on the validation tests. If any of them are not passed, the student's answer is invalid.

", "definition": "map(\n let([name,code], test,\n if(r[\"success\"],\n if(r[\"result\"],\n true\n ,\n warn(\"\"\"Your code failed the test {name}.\"\"\");\n fail(\"\"\"Your code failed the test {name}.\"\"\");false\n )\n ,\n warn(\"\"\"There was an error running the test {name}.\"\"\");\n fail(\"\"\"There was an error running the test {name}:
{escape_html(r[\"stderr\"])}
\"\"\")\n )\n ),\n [test,r],\n zip(settings[\"validation_tests\"],validation_results)\n)"}, {"name": "total_weight", "description": "

The sum of the weights of the marking tests. Each test's weight is divided by this to produce a proportion of the available credit.

", "definition": "sum(map(weight,[name,weight,code],settings[\"tests\"]))"}, {"name": "pre_submit", "description": "

The code blocks to run.

\n

In order, they are:

\n", "definition": "if(studentAnswer=nothing,\n []\n,\n [run_code(code_language,\n [\n matplotlib_preamble,\n variables_as_code(language_synonym(code_language), settings[\"variables\"]),\n render(settings[\"preamble\"]),\n if(trim(settings[\"modifier\"])=\"\", studentAnswer, eval(expression(settings[\"modifier\"]))),\n render(settings[\"postamble\"]),\n matplotlib_postamble\n ]\n +map(code,[name,marks,code],settings[\"tests\"])\n +map(code,[name,code],settings[\"validation_tests\"])\n )]\n)"}, {"name": "code_result", "description": "

The results of the code blocks: a list with an entry corresponding to each block of code.

", "definition": "pre_submit[\"code_result\"]"}, {"name": "main_stdout", "description": "

The stdout from the student's code.

", "definition": "safe(main_result[\"stdout\"])"}, {"name": "code_language", "description": "

The language the code is written in. Either \"pyodide\" (Python) or \"webr\" (R)

", "definition": "settings[\"code_language\"]"}, {"name": "preamble_result", "description": "

The result of running the preamble block.

", "definition": "code_result[2]"}, {"name": "preamble_stderr", "description": "

The STDERR produced by the preamble block.

", "definition": "preamble_result[\"stderr\"]"}, {"name": "postamble_result", "description": "

The result of running the postamble.

", "definition": "code_result[4]"}, {"name": "postamble_stderr", "description": "

The STDERR produced by the postamble block.

", "definition": "postamble_result[\"stderr\"]"}, {"name": "postamble_feedback", "description": "

Show the STDOUT from the postamble, if there is any.

", "definition": "assert(postamble_result[\"stdout\"]=\"\",\n feedback(\n if(settings[\"postamble_feedback_whitespace\"],\n html(\"\"\"
{escape_html(postamble_result[\"stdout\"])}
\"\"\")\n ,\n postamble_result[\"stdout\"]\n )\n )\n);\nassert(postamble_result[\"success\"],\n if(settings[\"show_stderr\"],\n fail(\"\"\"There was an error in the marking routine postamble:
{escape_html(postamble_result[\"stderr\"])}
\"\"\")\n ,\n fail(\"There was an error in the marking routine postamble.\")\n )\n)"}, {"name": "matplotlib_preamble", "description": "

Preamble for a hack to ensure that figures produced by matplotlib in Python are displayed.

\n

This code clears the matplotlib output, if matplotlib has been loaded.

", "definition": "if(code_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n plt.clf() \n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_postamble", "description": "

A hack to show any figures produced with matplotlib in the stdout.

", "definition": "switch(\ncode_language=\"pyodide\",\n safe(\"\"\"\nimport sys\nif 'matplotlib' in sys.modules:\n import matplotlib.pyplot as plt\n fig = plt.gcf()\n if fig.get_axes():\n fig.savefig(sys.stdout, format='svg')\n\"\"\"),\n \"\"\n)"}, {"name": "matplotlib_result", "description": "

The result of running the matplotlib hack.

", "definition": "code_result[5]"}, {"name": "matplotlib_feedback", "description": "

Feedback from the matplotlib hack: if a figure is produced, it's displayed as SVG here.

", "definition": "switch(\ncode_language=\"pyodide\",\n assert(matplotlib_result[\"stdout\"]=\"\",\n feedback(matplotlib_result[\"stdout\"])\n ),\n \"\"\n)\n\n"}, {"name": "images", "description": "

Any images produced by the code blocks.

", "definition": "flatten(map(\n get(r,\"images\",[]),\n r,\n code_result\n))"}, {"name": "show_images", "description": "

Show the images produced by the code.

", "definition": "assert(len(images)=0 or not settings[\"show_stdout\"],\n feedback(\"Your code produced the following {pluralise(len(images),'image','images')}:\");\n map(\n feedback(html(x)),\n x,\n images\n )\n)"}], "settings": [{"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "code_language", "label": "Code language", "help_url": "", "hint": "The language that the student's code will be written in.", "input_type": "dropdown", "default_value": "pyodide", "choices": [{"value": "pyodide", "label": "Python"}, {"value": "webr", "label": "R"}]}, {"name": "correct_answer", "label": "Correct answer", "help_url": "", "hint": "A correct answer to the part.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "correct_answer_subvars", "label": "Substitute question variables into the correct answer?", "help_url": "", "hint": "If ticked, then JME expressions between curly braces will be evaluated and substituted into the correct answer.

If not ticked, then the correct answer will be displayed exactly as it is.", "input_type": "checkbox", "default_value": true}, {"name": "show_stdout", "label": "Show stdout?", "help_url": "", "hint": "If ticked, the STDOUT produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_stderr", "label": "Show stderr?", "help_url": "", "hint": "If ticked, the STDERR produced after running the student's code will be shown in the feedback.", "input_type": "checkbox", "default_value": true}, {"name": "show_marking_errors", "label": "Show errors produced by marking tests?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "placeholder", "label": "Placeholder", "help_url": "", "hint": "Initial text for the code editor", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "modifier", "label": "Student code modifier", "help_url": "", "hint": "JME expression to modify the student's submitted code before being passed to the marking template. The student's code is available as the string variable studentAnswer.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "preamble", "label": "Preamble", "help_url": "", "hint": "This code is run before the student's code. Define anything that the student's code or your tests need.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble", "label": "Postamble", "help_url": "", "hint": "This code is run after the student's code but before the validation and unit tests.", "input_type": "code", "default_value": "", "evaluate": false}, {"name": "postamble_feedback_whitespace", "label": "Format postamble output as code?", "help_url": "", "hint": "If ticked, any output produced by the postamble will be formatted in monospace font, with whitespace preserved. If not ticked, it'll be presented as prose text or HTML.", "input_type": "checkbox", "default_value": false}, {"name": "tests", "label": "Marking tests", "help_url": "", "hint": "A list of tests used to mark the student's answer.
Each item is a list with three values:
\n", "input_type": "code", "default_value": "[\n [\"Test 1\", 1, \"True\"]\n]", "evaluate": true}, {"name": "validation_tests", "label": "Validation tests", "help_url": "", "hint": "

A list of tests used to validate that the student's code is acceptable.
Each item is a list with two string values:

\n", "input_type": "code", "default_value": "[\n [\"arithmetic works\", \"1+1 == 2\"]\n]", "evaluate": true}, {"name": "variables", "label": "Variables to include in code", "help_url": "", "hint": "Give a dictionary mapping variable names to their values. These variables will be available in the code that is run.", "input_type": "code", "default_value": "dict()", "evaluate": true}], "public_availability": "always", "published": true, "extensions": ["programming"]}], "resources": []}