// Numbas version: exam_results_page_options {"name": "Does this graph represent a function of x?", "extensions": ["jsxgraph"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"name": "Does this graph represent a function of x?", "tags": [], "metadata": {"description": "

A random graph is drawn and students are asked whether it represents a function or not.

", "licence": "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International"}, "statement": "

Does this graph appear to represent a function of $x$?

\n

Note: A red dashed line represents an asymptote. 

\n

Note: A filled-in circle signifies the point is included in the graph, whereas a hollow circle signifies the point is not included.

", "advice": "

A function is a rule that assigns at most one output (generally a $y$ value) for each input (generally an $x$ value).

\n

\n

Graphically, the requirement that there is at most one $y$ value for each $x$ value means a curve is the graph of a function if it passes the 'vertical line test'. That is, if you draw vertical lines through the graph and each vertical line only cuts the graph at most once, the graph 'passes' the vertical line test and it represents a function. In particular the graph shown passes fails the vertical line test and so is not a function.

", "rulesets": {}, "extensions": ["jsxgraph"], "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true}, "constants": [], "variables": {"no": {"name": "no", "group": "Ungrouped variables", "definition": " random('circle', 'ellipse', 'hhyperbola', 'vhyperbola', 'hbezier', 'vbezier','failstep')", "description": "", "templateType": "anything", "can_override": false}, "funOrNo": {"name": "funOrNo", "group": "Ungrouped variables", "definition": "random(1,0)", "description": "", "templateType": "anything", "can_override": false}, "finalchoice": {"name": "finalchoice", "group": "Ungrouped variables", "definition": "if(funOrNo=1,fun,no)", "description": "", "templateType": "anything", "can_override": false}, "fun": {"name": "fun", "group": "Ungrouped variables", "definition": "random('constant', 'line', 'sine', 'expi', 'expd','log','quadratic', 'cubic', 'hstep','rechyp')", "description": "

http://jsxgraph.uni-bayreuth.de/wiki/index.php/Step_function

", "templateType": "anything", "can_override": false}}, "variablesTest": {"condition": "", "maxRuns": 100}, "ungrouped_variables": ["funOrNo", "fun", "no", "finalchoice"], "variable_groups": [], "functions": {"graph": {"parameters": [["finalchoice", "string"]], "type": "html", "language": "javascript", "definition": "// This function creates the board and sets it up, then returns an\n// HTML div tag containing the board.\n \n\n\n// First, make the JSXGraph board.\n// The function provided by the JSXGraph extension wraps the board up in \n// a div tag so that it's easier to embed in the page.\nvar div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',\n{boundingBox: [-13,13,13,-13],\n axis: true,\n showNavigation: false,\n grid: true,\n keepaspectratio:true\n});\n \n// div.board is the object created by JSXGraph, which you use to \n// manipulate elements\nvar board = div.board; \n\n// create the x-axis.\n//var xaxis = board.create('line',[[0,0],[1,0]], { strokeColor: 'black', fixed: true});\n//var xticks = board.create('ticks',[xaxis,2],{\n// drawLabels: true,\n// label: {offset: [-4, -10]},\n// minorTicks: 0\n//});\n\n// create the y-axis\n//var yaxis = board.create('line',[[0,0],[0,1]], { strokeColor: 'black', fixed: true });\n//var yticks = board.create('ticks',[yaxis,2],{\n//drawLabels: true,\n//label: {offset: [-20, 0]},\n//minorTicks: 0\n//});\n\n//create a random integer function\nfunction getRndInteger(min, max) {\n return Math.floor(Math.random() * (max - min + 1) ) + min;\n}\n\n\nif (finalchoice=='ellipse'){\nvar f1x=-Math.floor(Math.random() * 5)-1; \nvar f1y=Math.floor(Math.random() * 10) -5; \nvar f2x=Math.floor(Math.random() * 5)+1; \nvar f2y=Math.floor(Math.random() * 10) -5; \nvar px=(f1x+f2x)/2+(f2y-f1y)*(0.2+Math.random()); \nvar py=(f1y+f2y)/2+(f1x-f2x)*(0.2+Math.random());\nvar ell = board.create('ellipse',[[f1x,f1y],[f2x,f2y],[px,py]]);\n}\n\n\nif (finalchoice=='circle'){\nvar f1x=getRndInteger(-5,5); \nvar f1y=getRndInteger(-5,5); \nvar px=f1x+1+Math.random()*5; \nvar py=f1y+1+Math.random()*5;\nvar cir = board.create('ellipse',[[f1x,f1y],[f1x,f1y],[px,py]]);\n}\n\n\nif (finalchoice=='hhyperbola'){\nvar f1x=getRndInteger(-7,-2); \nvar f1y=getRndInteger(-7,7); \nvar f2x=getRndInteger(0,7); \nvar bump = Math.random()+1 \nvar f2y=f1y+bump; \nvar px=f2x+1+Math.random(); \nvar py=f2y+1+Math.random();\nvar hhyp = board.create('hyperbola',[[f1x,f1y],[f2x,f2y],[px,py]]);\n}\n\nif (finalchoice=='vhyperbola'){\nvar f1y=getRndInteger(-7,-2); \nvar f1x=getRndInteger(-7,7); \nvar f2y=getRndInteger(2,7); \nvar bump = Math.random()+1 \nvar f2x=f1x+Math.random(); \nvar px=f2x+1+Math.random(); \nvar py=f2y+1+Math.random();\nvar vhyp = board.create('hyperbola',[[f1x,f1y],[f2x,f2y],[px,py]]);\n}\n\n\nif (finalchoice=='hbezier'){\n//some reused values\nvar Ax = getRndInteger(12,15)\nvar Ay = getRndInteger(-10,10)\n //data points \nvar D1 = board.create('point',[Ax,Ay],{fixed:true,size:-1,name:''});\nvar D2 = board.create('point',[getRndInteger(-15,10), getRndInteger(-15,15)],{fixed:true,size:-1,name:''}); \nvar D3 = board.create('point',[Ax,getRndInteger(-10,10)],{fixed:true,size:-1,name:''});\n //control points\nvar C1 = board.create('point',[getRndInteger(-15,15), getRndInteger(-15,15)],{fixed:true,size:-1,name:''});\nvar C2 = board.create('point',[getRndInteger(-15,15), getRndInteger(-15,15)],{fixed:true,size:-1,name:''}); \nvar C3 = board.create('point',[getRndInteger(-15,15), getRndInteger(-15,15)],{fixed:true,size:-1,name:''});\nvar C4 = board.create('point',[getRndInteger(-15,15), getRndInteger(-15,15)],{fixed:true,size:-1,name:''}); \n\nvar p = [D1,C1,C2,D2,C3,C4,D3];\nvar hbez = board.create('curve', JXG.Math.Numerics.bezier(p)); \n}\n\nif (finalchoice=='vbezier'){\n//some reused values\nvar Ax = getRndInteger(-5,5)\nvar Ay = getRndInteger(10,15)\n//data points \nvar D1 = board.create('point',[Ax,Ay],{fixed:true,size:-1,name:''});\nvar D2 = board.create('point',[Ax,-Ay],{fixed:true,size:-1,name:''}); \n//control points \nvar C1 = board.create('point',[getRndInteger(-15,-7), getRndInteger(0,8)],{fixed:true,size:-1,name:''});\nvar C2 = board.create('point',[getRndInteger(7,15), getRndInteger(0,-8)],{fixed:true,size:-1,name:''}); \n \nvar p = [D1,C1,C2,D2];\nvar vbez = board.create('curve', JXG.Math.Numerics.bezier(p)); \n}\n\nif (finalchoice=='constant'){\n var b = getRndInteger(-10,10)\n \nvar con = board.create('functiongraph', [function(x){return b}]);\n}\n\nif (finalchoice=='line'){\n var b = getRndInteger(-10,10)\n var m = getRndInteger(-5,5)\n \nvar lin = board.create('functiongraph', [function(x){return m*x+b}]);\n}\n\nif (finalchoice=='sine'){\n var a = getRndInteger(1,5)\n var b = getRndInteger(1,5)\n var c = getRndInteger(-2,2)\n var d = getRndInteger(-6,6)\n \nvar sin = board.create('functiongraph', [function(x){return a*Math.sin(x/b+c)+d}]);\n}\n\nif (finalchoice=='expi'){\n var a = (-1)**getRndInteger(1,2)*getRndInteger(1,5)\n var b = Math.random()+1\n var c = getRndInteger(-2,2)\n var d = getRndInteger(-6,6)\n \nvar exp = board.create('functiongraph', [function(x){return a*b**(x+c)+d}]);\n}\n\n\nif (finalchoice=='expd'){\n var a = (-1)**getRndInteger(1,2)*getRndInteger(1,5)\n var b = Math.random()+1\n var c = getRndInteger(-2,2)\n var d = getRndInteger(-6,6)\n \nvar exp = board.create('functiongraph', [function(x){return a*b**(-x+c)+d}]);\n}\n\n\nif (finalchoice=='log'){\n var a = (-1)**getRndInteger(1,2)*getRndInteger(1,5)\n var b = (-1)**getRndInteger(1,2)*getRndInteger(2,6)\n var c = getRndInteger(-2,2)\n var d = getRndInteger(-6,6)\n \nvar exp = board.create('functiongraph', [function(x){return a*Math.log(x/b+c)+d}]);\n \nvar p1 = board.create('point',[-c*b,1], {name:'',size:-1});\nvar p2 = board.create('point',[-c*b,-1], {name:'',size:-1});\n \n \n var asy = board.create('line',[p1,p2],{dash:3,strokecolor:'#FF0000'});\n}\n\n\nif (finalchoice=='quadratic'){\n var r1 = getRndInteger(-8,8)\n var r2 = getRndInteger(-8,8)\n var b = getRndInteger(-5,5)\n var a = (-1)**getRndInteger(1,2) \n \nvar quad = board.create('functiongraph', [function(x){return a*(x+r1)*(x+r2)+b}]);\n}\n\nif (finalchoice=='cubic'){\n var r1 = getRndInteger(-8,8)\n var r2 = getRndInteger(-8,8)\n var r3 = getRndInteger(-8,8)\n var b = getRndInteger(-5,5)\n var a = (-1)**getRndInteger(1,2) \n \nvar cub = board.create('functiongraph', [function(x){return a*(x+r1)*(x+r2)*(x+r3)/10+b}]);\n}\n\n\nif (finalchoice=='hstep'){\n\n var b1 = getRndInteger(-10,-3) ;\n var b2 = getRndInteger(3,10) ;\n var h1 = getRndInteger(-10,10) ;\n var h2 = getRndInteger(-10,10) ;\n var h3 = getRndInteger(-10,10) ;\n\n \n var f = function(x) {\n if(x=b1 && x =b2)\n return h3;\n}\n \nvar oc1 = board.createElement('circle',[[b1,h1],[b1+0.2,h1+0.2]], {fixed:true,strokewidth:1});\nvar cc1 = board.createElement('circle',[[b1,h2],[b1+0.1,h2+0.1]], {fixed:true,strokewidth:5});\nvar oc2 = board.createElement('circle',[[b2,h2],[b2+0.2,h2+0.2]], {fixed:true,strokewidth:1});\nvar cc2 = board.createElement('circle',[[b2,h3],[b2+0.1,h3+0.1]], {fixed:true,strokewidth:5});\n \nvar hstep = board.create('functiongraph',[f]);\n}\n\nif (finalchoice=='failstep'){\n\n var b1 = getRndInteger(-10,-3) ;\n var b2 = getRndInteger(3,10) ;\n var h1 = getRndInteger(-10,10) ;\n var h2 = getRndInteger(-10,10) ;\n var h3 = getRndInteger(-10,10) ;\n\n \n var f = function(x) {\n if(x=b1 && x =b2)\n return h3;\n}\n \n var cc1 = board.createElement('circle',[[b1,h1],[b1+0.1,h1+0.1]], {fixed:true,strokewidth:5});\nvar cc2 = board.createElement('circle',[[b1,h2],[b1+0.1,h2+0.1]], {fixed:true,strokewidth:5});\nvar cc3 = board.createElement('circle',[[b2,h2],[b2+0.1,h2+0.1]], {fixed:true,strokewidth:5});\nvar cc4 = board.createElement('circle',[[b2,h3],[b2+0.1,h3+0.1]], {fixed:true,strokewidth:5});\n\n\n \n \nvar failstep = board.create('functiongraph',[f]);\n}\n\n\nif (finalchoice=='rechyp'){\n\n var k = (-1)**getRndInteger(1,2)*getRndInteger(1,4) ;\n var x0 = getRndInteger(-7,7) ;\n var y0 = getRndInteger(-7,7) ;\n\n \n var f = function(x) {\n return y0+k/(x-x0);\n}\n \nvar asyh = board.create('line',[[x0,1],[x0,2]],{dash:3,strokecolor:'#FF0000'});\nvar asyv = board.create('line',[[1,y0],[2,y0]],{dash:3,strokecolor:'#FF0000'});\n \nvar rechyp = board.create('functiongraph',[f]);\n}\n\n\n\nreturn div;"}}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "1_n_2", "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": "

{graph(finalchoice)}

", "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": ["

A function of $x$

", "

Not a function of $x$

"], "matrix": "[funOrNo,abs(1-funOrNo)]"}], "partsMode": "all", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always", "contributors": [{"name": "Ben Brawn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/605/"}]}]}], "contributors": [{"name": "Ben Brawn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/605/"}]}