// Numbas version: finer_feedback_settings {"name": "Arbitrary components", "extensions": ["geogebra", "quantities"], "custom_part_types": [{"source": {"pk": 19, "author": {"name": "William Haynes", "pk": 2530}, "edit_page": "/part_type/19/edit"}, "name": "Engineering Accuracy with units", "short_name": "engineering-answer", "description": "
A value with units marked right if within an adjustable % error of the correct value. Marked close if within a wider margin of error.
", "help_url": "", "input_widget": "string", "input_options": {"correctAnswer": "siground(settings['correctAnswer'],4)", "hint": {"static": true, "value": ""}, "allowEmpty": {"static": true, "value": true}}, "can_be_gap": true, "can_be_step": true, "marking_script": "mark:\nswitch( \n right and good_units and right_sign, add_credit(1.0,'Correct.'),\n right and good_units and not right_sign, add_credit(settings['C2'],'Wrong sign.'),\n right and right_sign and not good_units, add_credit(settings['C2'],'Correct value, but wrong or missing units.'),\n close and good_units, add_credit(settings['C1'],'Close.'),\n close and not good_units, add_credit(settings['C3'],'Answer is close, but wrong or missing units.'),\n incorrect('Wrong answer.')\n)\n\n\ninterpreted_answer:\nqty(student_scalar, student_units)\n\n\n\ncorrect_quantity:\nsettings[\"correctAnswer\"]\n\n\n\ncorrect_units:\nunits(correct_quantity)\n\n\nallowed_notation_styles:\n[\"plain\",\"en\"]\n\nmatch_student_number:\nmatchnumber(studentAnswer,allowed_notation_styles)\n\nstudent_scalar:\nmatch_student_number[1]\n\nstudent_units:\nreplace_regex('ohms','ohm',\n replace_regex('\u00b0', ' deg',\n replace_regex('-', ' ' ,\n studentAnswer[len(match_student_number[0])..len(studentAnswer)])),\"i\")\n\ngood_units:\ntry(\ncompatible(quantity(1, student_units),correct_units),\nmsg,\nfeedback(msg);false)\n\n\nstudent_quantity:\nswitch(not good_units, \n student_scalar * correct_units, \n not right_sign,\n -quantity(student_scalar, student_units),\n quantity(student_scalar,student_units)\n)\n \n\n\npercent_error:\ntry(\nscalar(abs((correct_quantity - student_quantity)/correct_quantity))*100 \n,msg,\nif(student_quantity=correct_quantity,0,100))\n \n\nright:\npercent_error <= settings['right']\n\n\nclose:\nright_sign and percent_error <= settings['close']\n\nright_sign:\nsign(student_scalar) = sign(correct_quantity)", "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": "switch( \n right and good_units and right_sign, add_credit(1.0,'Correct.'),\n right and good_units and not right_sign, add_credit(settings['C2'],'Wrong sign.'),\n right and right_sign and not good_units, add_credit(settings['C2'],'Correct value, but wrong or missing units.'),\n close and good_units, add_credit(settings['C1'],'Close.'),\n close and not good_units, add_credit(settings['C3'],'Answer is close, but wrong or missing units.'),\n incorrect('Wrong answer.')\n)\n"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "qty(student_scalar, student_units)\n\n"}, {"name": "correct_quantity", "description": "", "definition": "settings[\"correctAnswer\"]\n\n"}, {"name": "correct_units", "description": "", "definition": "units(correct_quantity)\n"}, {"name": "allowed_notation_styles", "description": "", "definition": "[\"plain\",\"en\"]"}, {"name": "match_student_number", "description": "", "definition": "matchnumber(studentAnswer,allowed_notation_styles)"}, {"name": "student_scalar", "description": "", "definition": "match_student_number[1]"}, {"name": "student_units", "description": "Modify the unit portion of the student's answer by
\n1. replacing \"ohms\" with \"ohm\" case insensitive
\n2. replacing '-' with ' '
\n3. replacing '°' with ' deg'
\nto allow answers like 10 ft-lb and 30°
", "definition": "replace_regex('ohms','ohm',\n replace_regex('\u00b0', ' deg',\n replace_regex('-', ' ' ,\n studentAnswer[len(match_student_number[0])..len(studentAnswer)])),\"i\")"}, {"name": "good_units", "description": "", "definition": "try(\ncompatible(quantity(1, student_units),correct_units),\nmsg,\nfeedback(msg);false)\n"}, {"name": "student_quantity", "description": "This fixes the student answer for two common errors.
\nIf student_units are wrong - replace with correct units
\nIf student_scalar has the wrong sign - replace with right sign
\nIf student makes both errors, only one gets fixed.
", "definition": "switch(not good_units, \n student_scalar * correct_units, \n not right_sign,\n -quantity(student_scalar, student_units),\n quantity(student_scalar,student_units)\n)\n \n"}, {"name": "percent_error", "description": "", "definition": "try(\nscalar(abs((correct_quantity - student_quantity)/correct_quantity))*100 \n,msg,\nif(student_quantity=correct_quantity,0,100))\n "}, {"name": "right", "description": "", "definition": "percent_error <= settings['right']\n"}, {"name": "close", "description": "Only marked close if the student actually has the right sign.
", "definition": "right_sign and percent_error <= settings['close']"}, {"name": "right_sign", "description": "", "definition": "sign(student_scalar) = sign(correct_quantity) "}], "settings": [{"name": "correctAnswer", "label": "Correct Quantity.", "help_url": "", "hint": "The correct answer given as a JME quantity.", "input_type": "code", "default_value": "", "evaluate": true}, {"name": "right", "label": "% Accuracy for right.", "help_url": "", "hint": "Question will be considered correct if the scalar part of the student's answer is within this % of correct value.", "input_type": "code", "default_value": "0.2", "evaluate": true}, {"name": "close", "label": "% Accuracy for close.", "help_url": "", "hint": "Question will be considered close if the scalar part of the student's answer is within this % of correct value.", "input_type": "code", "default_value": "1.0", "evaluate": true}, {"name": "C1", "label": "Close with units.", "help_url": "", "hint": "Partial Credit for close value with appropriate units. if correct answer is 100 N and close is ±1%,Determine the oblique components of a vector.
", "licence": "Creative Commons Attribution-NonCommercial 4.0 International"}, "statement": "{applet()}
\nDetermine the scalar components of $\\var{F units}$ force $\\mathbf{F}$ in the $a$- and $b$- directions.
", "advice": "Procedure:
\nCarefully draw and label a diagram showing the parallelogram rule vector addition.
\nDetermine the values of any known angles and sides.
\nUse the law of sines or law of cosines to solve for the unknown values.
\nYou can't use SOHCAHTOA on this triangle unless it is a right triangle.
\nNote:
\nA Scalar component is equal to the magnitude of the corresponding vector component, but with a $+$ or $-$ sign to indicate its sense.
\nVector Magnitudes are always positive, but a scalar component is positive if it points towards the positive end of the axis, or negative if it points the other way.
\nThe positive end of an axis is the end with the label.
", "rulesets": {}, "extensions": ["geogebra", "quantities"], "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true}, "constants": [], "variables": {"debug": {"name": "debug", "group": "inputs", "definition": "false", "description": "", "templateType": "anything", "can_override": false}, "alpha": {"name": "alpha", "group": "inputs", "definition": "random(0..360#15)", "description": "Direction of a axis from x axis. b axis and F are measured from here
", "templateType": "anything", "can_override": false}, "units": {"name": "units", "group": "inputs", "definition": "qty(1, 'kN')", "description": "", "templateType": "anything", "can_override": false}, "beta": {"name": "beta", "group": "inputs", "definition": "random(0..360#15 except [0,90,270,360])", "description": "direction of +b axis from a axis
", "templateType": "anything", "can_override": false}, "F_a": {"name": "F_a", "group": "inputs", "definition": "EA( -F / sin(radians(beta)) sin(radians(theta - beta)))", "description": "Answer to question. Component in \"a\" direction.
", "templateType": "anything", "can_override": false}, "F_b": {"name": "F_b", "group": "inputs", "definition": "EA(F / sin(radians(beta)) sin(radians(180 - theta)))", "description": "component in \"b\" direction
", "templateType": "anything", "can_override": false}, "F": {"name": "F", "group": "inputs", "definition": "random(100..1500#50)", "description": "Magnitude of F
", "templateType": "anything", "can_override": false}, "theta": {"name": "theta", "group": "inputs", "definition": "random(0..360#15)", "description": "direction of force from a axis
", "templateType": "anything", "can_override": false}}, "variablesTest": {"condition": "//ensure that components look good on diagram\n\n2.5 > abs(F_a/F) > 0.3 and \n2.5 > abs(F_b/F) > 0.3", "maxRuns": 100}, "ungrouped_variables": [], "variable_groups": [{"name": "inputs", "variables": ["alpha", "beta", "theta", "debug", "units", "F", "F_a", "F_b"]}], "functions": {"applet": {"parameters": [], "type": "ggbapplet", "language": "javascript", "definition": "// Create the worksheet. \n// This function returns an object with a container `element` and a `promise` resolving to a GeoGebra applet.\nvar params = {\n material_id: 'rgfr3kj8'\n}\n\nvar result = Numbas.extensions.geogebra.createGeogebraApplet(params);\n\n// Once the applet has loaded, run some commands to manipulate the worksheet.\nresult.promise.then(function(d) {\n var app = d.app;\n question.applet = d;\n \n function setGGBAngle(gname, nname=gname) {\n // Sets angle in GGB to a Numbas Variable given in degrees.\n var v = Numbas.jme.unwrapValue(question.scope.getVariable(nname));\n app.setValue(gname,v * Math.PI / 180);\n } \n\n setGGBAngle(\"ang_a\", \"alpha\");\n setGGBAngle(\"ang_b\", \"beta\");\n setGGBAngle(\"theta\", \"theta\");\n //\n app.setGridVisible(true);\n app.setVisible(\"\u03b8\",false);\n app.setVisible(\"\u03b1\",false);\n app.setVisible(\"debug\",false);\n app.setVisible(\"show\",false);\n app.setValue(\"debug\",false);\n app.setValue(\"show\",false);\n app.setValue(\"mag_F\", Numbas.jme.unwrapValue(question.scope.getVariable(\"F\")));\n \n \n});\n\n// This function returns the result of `createGeogebraApplet` as an object \n// with the JME data type 'ggbapplet', which can be substituted into the question's content.\nreturn new Numbas.jme.types.ggbapplet(result);"}, "EA": {"parameters": [["N", "number"]], "type": "anything", "language": "jme", "definition": "round(n*100)/100"}}, "preamble": {"js": "question.signals.on('adviceDisplayed',function() {\n try{\n var app = question.applet.app;\n \n app.setVisible('show',false);\n app.setValue('show',true);\n app.setLabelVisible('show',false);\n \n }\n catch(err){} \n})\n\n\n", "css": ""}, "parts": [{"type": "gapfill", "useCustomName": true, "customName": "Components", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "$F_a$ = [[0]] {F_a units} $\\qquad F_b$ = [[1]] {F_b units}
", "gaps": [{"type": "engineering-answer", "useCustomName": true, "customName": "$F_a$", "marks": "10", "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "settings": {"correctAnswer": "F_a units", "right": "0.2", "close": "1.0", "C1": "75", "C2": "50", "C3": "25"}}, {"type": "engineering-answer", "useCustomName": true, "customName": "$F_b$", "marks": "10", "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "settings": {"correctAnswer": "F_b units", "right": "0.2", "close": "1.0", "C1": "75", "C2": "50", "C3": "25"}}], "sortAnswers": false}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always", "type": "question", "contributors": [{"name": "William Haynes", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/2530/"}]}]}], "contributors": [{"name": "William Haynes", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/2530/"}]}