diff --git a/FinalBRDs/detector_adaptivity_demos/1416.brd b/FinalBRDs/detector_adaptivity_demos/1416.brd index 0eca110..310df54 100644 --- a/FinalBRDs/detector_adaptivity_demos/1416.brd +++ b/FinalBRDs/detector_adaptivity_demos/1416.brd @@ -264,38 +264,6 @@ 69 - - state23 - 24 - - 45 - 121 - - - - state24 - 25 - - 56 - 169 - - - - state25 - 26 - - 100 - 292 - - - - state26 - 27 - - 76 - 217 - - state27 28 @@ -304,14 +272,6 @@ 102 - - state28 - 29 - - 127 - 350 - - @@ -1603,7 +1563,7 @@ 66079e13-da1e-4bd9-0090-d9a12f4eaf74 - ← Hey, try asking for a hint! You've made a lot of errors on this step. + Try asking for a hint! You've made a lot of errors on this step. Please provide your answer 'No_Value' in the highlighted element. @@ -1640,242 +1600,6 @@ 23 0 - - - - - - 33 - - SendNoteProperty - - CorrectAction - - No_Selection - - - No_Action - - - - - 7af3c7db-b968-edc9-f468-80be7d449329 - - - Nice job giving this step a try! If you'd like a hint, you can try clicking the button on the left. - - Please provide your answer 'No_Value' in the highlighted element. - - Buggy Action - Correct Action - Never Checked - - - - AnyMatcher - - - - - AnyMatcher - - - - - ExpressionMatcher - equals(help_model_try_if_low,"preferred") - boolean - - - Student - - - No-Applicable - - unnamed - -1 - - 1 - 24 - 0 - - - - - - - 35 - - SendNoteProperty - - CorrectAction - - No_Selection - - - No_Action - - - No_Value - - 7af3c7db-b968-edc9-f468-80be7d449329 - - - Please take your time to work through the problem. - - Please provide your answer 'No_Value' in the highlighted element. - - Buggy Action - Correct Action - Never Checked - - - - AnyMatcher - - - - - AnyMatcher - - - - - ExpressionMatcher - equals(help_model_try_if_low,"not acceptable/not deliberate") - boolean - - - Student - - - No-Applicable - - unnamed - -1 - - 1 - 25 - 0 - - - - - - - 73 - - SendNoteProperty - - CorrectAction - - No_Selection - - - No_Action - - - No_Value - - 16fc98f5-0840-bce6-5cdf-5324dd12edc6 - - - Please take it easy with those hints, there... - - Please provide your answer 'No_Value' in the highlighted element. - - Buggy Action - Correct Action - Never Checked - - - - AnyMatcher - - - - - AnyMatcher - - - - - ExpressionMatcher - equals(help_model_try_if_low,"not acceptable/hint abuse") - boolean - - - Student - - - No-Applicable - - unnamed - -1 - - 1 - 26 - 0 - - - - - - - 75 - - SendNoteProperty - - CorrectAction - - No_Selection - - - No_Action - - - No_Value - - 16fc98f5-0840-bce6-5cdf-5324dd12edc6 - - - Try asking for a hint! - - Please provide your answer 'No_Value' in the highlighted element. - - Buggy Action - Correct Action - Never Checked - - - - AnyMatcher - - - - - AnyMatcher - - - - - ExpressionMatcher - equals(help_model_try_if_low,"not acceptable/hint avoidance") - boolean - - - Student - - - No-Applicable - - unnamed - -1 - - 1 - 27 - 0 - @@ -1936,65 +1660,6 @@ 28 0 - - - - - - 82 - - SendNoteProperty - - CorrectAction - - No_Selection - - - No_Action - - - No_Value - - 71007e45-ed56-2e2d-0cf3-2818f8b23db1 - - - Please ask your teacher for help! - - Please provide your answer 'No_Value' in the highlighted element. - - Buggy Action - Correct Action - Never Checked - - - - AnyMatcher - - - - - AnyMatcher - - - - - ExpressionMatcher - equals(help_model_try_if_low,"ask teacher for help/try step") - boolean - - - Student - - - No-Applicable - - unnamed - -1 - - 1 - 29 - 0 - copy-answer-denominator fraction-addition diff --git a/HTML/Assets/Detectors/currentAttemptCount.js b/HTML/Assets/Detectors/Adaptivity/currentAttemptCount.js similarity index 99% rename from HTML/Assets/Detectors/currentAttemptCount.js rename to HTML/Assets/Detectors/Adaptivity/currentAttemptCount.js index b42186d..2c0d079 100644 --- a/HTML/Assets/Detectors/currentAttemptCount.js +++ b/HTML/Assets/Detectors/Adaptivity/currentAttemptCount.js @@ -2,7 +2,7 @@ var variableName = "current_attempt_count" //initializations (do not touch) var detector_output = {name: variableName, - category: "Dashboard", + category: "Adaptivity", value: 0, history: {}, skill_names: "", diff --git a/HTML/Assets/Detectors/Adaptivity/help_model_try_if_low.js b/HTML/Assets/Detectors/Adaptivity/help_model_try_if_low.js new file mode 100644 index 0000000..829e77a --- /dev/null +++ b/HTML/Assets/Detectors/Adaptivity/help_model_try_if_low.js @@ -0,0 +1,337 @@ +//detector template + +//add output variable name below +var variableName = "help_model_try_if_low" + +//initializations (do not touch) +var detector_output = {name: variableName, + category: "Adaptivity", + value: 0, + history: "", + skill_names: "", + step_id: "", + transaction_id: "", + time: "" + }; +var mailer; + +//declare any custom global variables that will be initialized +//based on "remembered" values across problem boundaries, here +// (initialize these at the bottom of this file, inside of self.onmessage) +// +// +// +// +// + + +//declare and/or initialize any other custom global variables for this detector here... +var help_variables = {"lastAction": "null", + "lastActionTime": "", + "seenAllHints": {}, + "lastHintLength": "", + "lastSenseOfWhatToDo": false + }; +// +//[optional] single out TUNABLE PARAMETERS below +var errorThreshold = 2; //currently arbitrary +var newStepThreshold = 1; //currently arbitrary +var familiarityThreshold = 0.4; +var senseOfWhatToDoThreshold = 0.6; +var hintIsHelpfulPlaceholder = true; //currently a dummy value (assumption that hint is always helpful...) + + +//non-controversial +function lastActionIsHint(e){ + if (help_variables.lastAction == "hint"){return true;} + else{return false;} +} +function lastActionIsError(e){ + if (help_variables.lastAction == "error"){return true;} + else{return false;} +} +function seenAllHintLevels(e){ + if (e.data.tutor_data.action_evaluation.toLowerCase() == "hint"){ + if (e.data.tutor_data.selection in help_variables.seenAllHints){ + return help_variables.seenAllHints[e.data.tutor_data.selection]; + } + else{return false;} + } + else{ + if (e.data.tool_data.selection in help_variables.seenAllHints){ + return help_variables.seenAllHints[e.data.tool_data.selection]; + } + else{return false;} + } +} +function isCorrect(e){ + if (e.data.tutor_data.action_evaluation.toLowerCase() == "correct"){return true;} + else{return false;} +} + +function secondsSinceLastAction(e){ + var currTime = new Date(); + diff = currTime.getTime() - help_variables.lastActionTime.getTime(); + console.log("time elapsed: ", diff/1000) + return (diff / 1000); +} + +//less controversial +function isDeliberate(e){ + var hintThreshold = (help_variables.lastHintLength/600)*60; + + if (lastActionIsError(e)){ + return (secondsSinceLastAction(e) > errorThreshold); + } + else if (lastActionIsHint(e)){ + return (secondsSinceLastAction(e) > hintThreshold); + } + else{ + return (secondsSinceLastAction(e) > newStepThreshold); + } +} + +//more controversial... +function isFamiliar(e){ + var rawSkills = e.data.tutor_data.skills; + for (var property in rawSkills) { + if (rawSkills.hasOwnProperty(property)) { + if (parseFloat(rawSkills[property].pKnown)<=familiarityThreshold){ + return false; + } + } + } + return true; +} + +function isLowSkillStep_All(e){ + var rawSkills = e.data.tutor_data.skills; + for (var property in rawSkills) { + if (rawSkills.hasOwnProperty(property)) { + if (parseFloat(rawSkills[property].pKnown)>=familiarityThreshold){ + return false; + } + } + } + return true; +} + +function isLowSkillStep_Some(e){ + var rawSkills = e.data.tutor_data.skills; + for (var property in rawSkills) { + if (rawSkills.hasOwnProperty(property)) { + if (parseFloat(rawSkills[property].pKnown)<=familiarityThreshold){ + return true; + } + } + } + return false; +} + +function hintIsHelpful(e){ + return hintIsHelpfulPlaceholder; +} +function lastActionUnclearFix(e){ + if (help_variables.lastSenseOfWhatToDo == false){return true;} + else{return false;} +} +function senseOfWhatToDo(e){ + var sel = e.data.tutor_data.selection; + var rawSkills = e.data.tutor_data.skills; + for (var property in rawSkills) { + if (rawSkills.hasOwnProperty(property)) { + if (parseFloat(rawSkills[property].pKnown)<=senseOfWhatToDoThreshold){ + return false; + } + } + } + return true; +} + +//evaluation of each step +function evaluateAction(e){ + var sel = e.data.tutor_data.selection; + var outcome = e.data.tutor_data.action_evaluation.toLowerCase(); + + if (e.data.tutor_data.action_evaluation.toLowerCase() == "hint"){ + console.log("isHint") + if (isDeliberate(e)){ + console.log("isDeliberate") + if (isLowSkillStep_Some(e) && !lastActionIsError(e)){ //possible modifications...unless wheel-spinning? ... or even closer to Ido's would be to get rid of the "unless last step was error" qualification? + return("not acceptable/asked hint on low skill step"); + } + else{ + if (!seenAllHintLevels(e) && + (!isFamiliar(e) + || (lastActionIsError(e) && lastActionUnclearFix(e)) + || (lastActionIsHint(e) && !hintIsHelpful(e))) ){ + return "preferred/ask hint"; + } + else if ( (isFamiliar(e) && !senseOfWhatToDo(e) ) + || (lastActionIsHint(e)) ){ + return "acceptable/ask hint"; + } + else{ + return "not acceptable/hint abuse"; + } + } + } + else{ + console.log("not deliberate") + return "not acceptable/hint abuse"; + } + + } + else{ + if (isLowSkillStep_Some(e) && !lastActionIsError(e)){ //possible modifications...unless wheel-spinning? ... or even closer to Ido's would be to get rid of the "unless last step was error" qualification? + return("preferred/try step on low skill step"); + } + else{ + if (isDeliberate(e)){ + if ( (isFamiliar(e) && (!(lastActionIsError(e) && lastActionUnclearFix(e))) ) + || (lastActionIsHint(e) && hintIsHelpful(e)) + ){ + console.log("____"); + return "preferred"; + } + else if (seenAllHintLevels(e) && + (!(lastActionIsError(e) && lastActionUnclearFix(e))) ){ + return "preferred"; + } + else if (isCorrect(e)){ + return "acceptable/try step"; + } + else if (seenAllHintLevels(e)){ + if (lastActionIsError(e) && lastActionUnclearFix(e)){ + return "ask teacher for help/try step"; + } + } + else{ + return "not acceptable/hint avoidance"; + } + } + else{ + return "not acceptable/not deliberate"; + } + } + } + +} + +function updateHistory(e){ + help_variables.lastActionTime = new Date(); + if (e.data.tutor_data.action_evaluation.toLowerCase() == "hint"){ + help_variables.lastAction = "hint"; + help_variables.lastHintLength = e.data.tutor_data.tutor_advice.split(' ').length; + if (help_variables.seenAllHints[e.data.tutor_data.selection] != true){ + help_variables.seenAllHints[e.data.tutor_data.selection] = (e.data.tutor_data.current_hint_number == e.data.tutor_data.total_hints_available); + } + } + if (e.data.tutor_data.action_evaluation.toLowerCase() == "incorrect"){ + help_variables.lastAction = "error"; + } + + help_variables.lastSenseOfWhatToDo = senseOfWhatToDo(e); + +} + + + +function receive_transaction( e ){ + //e is the data of the transaction from mailer from transaction assembler + + + //set conditions under which transaction should be processed + //(i.e., to update internal state and history, without + //necessarily updating external state and history) + if(e.data.actor == 'student' && e.data.tool_data.action != "UpdateVariable"){ + //do not touch + rawSkills = e.data.tutor_data.skills + var currSkills = [] + for (var property in rawSkills) { + if (rawSkills.hasOwnProperty(property)) { + currSkills.push(rawSkills[property].name + "/" + rawSkills[property].category) + } + } + detector_output.skill_names = currSkills; + detector_output.step_id = e.data.tutor_data.step_id; + + //custom processing (insert code here) + if (help_variables.lastAction!="null"){ + detector_output.value = evaluateAction(e); + } + else{ + detector_output.value = "preferred/first step"; + } + updateHistory(e); + detector_output.history = help_variables; + } + + //set conditions under which detector should update + //external state and history + if(e.data.actor == 'student' && e.data.tool_data.action != "UpdateVariable"){ + detector_output.time = new Date(); + detector_output.transaction_id = e.data.transaction_id; + mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); + } +} + + +self.onmessage = function ( e ) { + console.log(variableName, " self.onmessage:", e, e.data, (e.data?e.data.commmand:null), (e.data?e.data.transaction:null), e.ports); + switch( e.data.command ) + { + case "connectMailer": + mailer = e.ports[0]; + mailer.onmessage = receive_transaction; + break; + case "initialize": + for (initItem in e.data.initializer){ + if (e.data.initializer[initItem].name == variableName){ + detector_output.history = e.data.initializer[initItem].history; + detector_output.value = e.data.initializer[initItem].value; + } + } + + //optional: In "detectorForget", specify conditions under which a detector + //should NOT remember their most recent value and history (using the variable "detectorForget"). + //(e.g., setting the condition to "true" will mean that the detector + // will always be reset between problems... and setting the condition to "false" + // means that the detector will never be reset between problems) + // + detectorForget = true; + // + // + + if (detectorForget){ + detector_output.history = ""; + detector_output.value = 0; + } + + + //optional: If any global variables are based on remembered values across problem boundaries, + // these initializations should be written here + // + // + if (detector_output.history == "" || detector_output.history == null){ + //in the event that the detector history is empty, + //initialize variables to your desired 'default' values + // + // + } + else{ + //if the detector history is not empty, you can access it via: + // JSON.parse(detector_output.history); + //...and initialize your variables to your desired values, based on + //this history + // + // + } + + break; + default: + break; + } +} \ No newline at end of file diff --git a/HTML/Assets/Detectors/stagnation.js b/HTML/Assets/Detectors/Adaptivity/idle.js similarity index 59% rename from HTML/Assets/Detectors/stagnation.js rename to HTML/Assets/Detectors/Adaptivity/idle.js index 293d657..7398618 100644 --- a/HTML/Assets/Detectors/stagnation.js +++ b/HTML/Assets/Detectors/Adaptivity/idle.js @@ -1,9 +1,12 @@ -var variableName = "stagnation" +//detector template + +//add output variable name below +var variableName = "idle" //initializations (do not touch) var detector_output = {name: variableName, - category: "Dashboard", - value: 0, + category: "Adaptivity", + value: "0, none", history: "", skill_names: "", step_id: "", @@ -12,7 +15,6 @@ var detector_output = {name: variableName, }; var mailer; - //declare any custom global variables that will be initialized //based on "remembered" values across problem boundaries, here // (initialize these at the bottom of this file, inside of self.onmessage) @@ -22,20 +24,39 @@ var mailer; // // -//declare and/or initialize any other custom global variables for this detector here... -var timerId; var timerId2; var timerId3; -// -//[optional] single out TUNABLE PARAMETERS below -// +//declare and/or initialize any other custom global variables for this detector here +var timerId3; +var timerId4; +var timerId5; +timerId3 = setTimeout(function() { + detector_output.history = "onLoad" + detector_output.value = "1, > 20 s" + detector_output.time = new Date(); + mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); }, + 20000) +timerId4 = setTimeout(function() { + detector_output.history = "onLoad" + detector_output.value = "1, > 2 min" + detector_output.time = new Date(); + mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); }, + 120000) +timerId5 = setTimeout(function() { + detector_output.history = "onLoad" + detector_output.value = "1, > 5 min" + detector_output.time = new Date(); + mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); }, + 300000) function receive_transaction( e ){ //e is the data of the transaction from mailer from transaction assembler - //TEST CODE - //console.log("in detector1 with data:"); - //console.log(e.data); - //set conditions under which transaction should be processed //(i.e., to update internal state and history, without //necessarily updating external state and history) @@ -52,39 +73,53 @@ function receive_transaction( e ){ detector_output.step_id = e.data.tutor_data.step_id; //custom processing (insert code here) - clearTimeout(timerId) - clearTimeout(timerId2) - clearTimeout(timerId3) + clearTimeout(timerId3); + clearTimeout(timerId4); + clearTimeout(timerId5); + + detector_output.history = e.data.tool_data.tool_event_time + detector_output.value = "0, > 0 s" + detector_output.time = new Date(); + mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); } //set conditions under which detector should update //external state and history if(e.data.actor == 'student' && e.data.tool_data.action != "UpdateVariable"){ - timerId = setTimeout(function() { + + detector_output.time = new Date(); + detector_output.transaction_id = e.data.transaction_id; + + //custom processing (insert code here) + timerId3 = setTimeout(function() { detector_output.history = e.data.tool_data.tool_event_time - detector_output.value = "1s" + detector_output.value = "1, > 20 s" detector_output.time = new Date(); mailer.postMessage(detector_output); postMessage(detector_output); - console.log("output_data = ", detector_output); }, - 1000) - timerId2 = setTimeout(function() { + console.log("output_data = ", detector_output); }, + 20000) + timerId4 = setTimeout(function() { detector_output.history = e.data.tool_data.tool_event_time - detector_output.value = "4s" + detector_output.value = "1, > 2 min" detector_output.time = new Date(); mailer.postMessage(detector_output); postMessage(detector_output); console.log("output_data = ", detector_output); }, - 4000) - timerId3 = setTimeout(function() { + 120000) + timerId5 = setTimeout(function() { detector_output.history = e.data.tool_data.tool_event_time - detector_output.value = "7s" + detector_output.value = "1, > 5 min" detector_output.time = new Date(); mailer.postMessage(detector_output); postMessage(detector_output); console.log("output_data = ", detector_output); }, - 7000) + 300000) + + } } @@ -94,8 +129,8 @@ self.onmessage = function ( e ) { switch( e.data.command ) { case "connectMailer": - mailer = e.ports[0]; - mailer.onmessage = receive_transaction; + mailer = e.ports[0]; + mailer.onmessage = receive_transaction; break; case "initialize": for (initItem in e.data.initializer){ @@ -116,33 +151,21 @@ self.onmessage = function ( e ) { // if (detectorForget){ - detector_output.history = ""; - detector_output.value = 0; + detector_output.history = "onLoad"; + detector_output.value = "0, > 0 s"; } - //optional: If any global variables are based on remembered values across problem boundaries, - // these initializations should be written here - // - // - if (detector_output.history == "" || detector_output.history == null){ - //in the event that the detector history is empty, - //initialize variables to your desired 'default' values - // - // - } - else{ - //if the detector history is not empty, you can access it via: - // JSON.parse(detector_output.history); - //...and initialize your variables to your desired values, based on - //this history - // - // - } + detector_output.time = new Date(); + mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); + - break; default: break; + } -} + +} \ No newline at end of file diff --git a/HTML/Assets/Detectors/Adaptivity/tutor_ear.js b/HTML/Assets/Detectors/Adaptivity/tutor_ear.js new file mode 100644 index 0000000..2c7815c --- /dev/null +++ b/HTML/Assets/Detectors/Adaptivity/tutor_ear.js @@ -0,0 +1,214 @@ +//detector template + +//add output variable name below +var variableName = "tutor_ear" + +//initializations (do not touch) +var detector_output = {name: variableName, + category: "Adaptivity", + value: 0, + history: "", + skill_names: "", + step_id: "", + transaction_id: "", + time: "" + }; +var mailer; + + +//declare any custom global variables that will be initialized +//based on "remembered" values across problem boundaries, here +// (initialize these at the bottom of this file, inside of self.onmessage) +// +// +// +// +// + + +//declare and/or initialize any other custom global variables for this detector here... +var currentDetectorValues = {}; +var timerID; +// +// +// +// +//[optional] single out TUNABLE PARAMETERS below +// +// +// +// + + +function sendTutorMessage(updateType, messageContent){ + + //tutor update type ("hint_window_message" or "other") + detector_output.history = updateType; + + detector_output.value = messageContent; + + //mailer.postMessage(detector_output); + postMessage(detector_output); + console.log("output_data = ", detector_output); + +} + +function receive_transaction( e ){ + //e is the data of the transaction from mailer from transaction assembler + + clearTimeout(timerID); + + //set conditions under which transaction should be processed + //(i.e., to update internal state and history, without + //necessarily updating external state and history) + + if(e.data.tool_data.action == "UpdateVariable"){ + // update store of current detector values + currentDetectorValues[e.data.tool_data.selection] = e.data.tool_data.input; + } + + timerID = setTimeout(function() { + + console.log(currentDetectorValues); + + //set conditions under which detector should update + //external state and history + if(e.data.tool_data.action == "UpdateVariable"){ + detector_output.time = new Date(); + detector_output.transaction_id = e.data.transaction_id; + + //custom processing (set tutor-performed actions here) + + if(currentDetectorValues["help_model_try_if_low"]=="preferred"){ + var updateType = "hint_window_message"; + var messageContent = "Nice job giving this step a try! If you'd like a hint, you can try clicking the button on the left."; + sendTutorMessage(updateType, messageContent); + } + else if(currentDetectorValues["help_model_try_if_low"]=="not acceptable/not deliberate"){ + + if(+(currentDetectorValues["current_attempt_count"])<4){ + var updateType = "hint_window_message"; + var messageContent = "Please take your time to work through the problem."; + sendTutorMessage(updateType, messageContent); + } + else{ + var updateType = "hint_window_message"; + var messageContent = "Try asking for a hint! You've made a lot of errors on this step."; + sendTutorMessage(updateType, messageContent); + + //highlight the hint button + var updateType = "interface_action"; + var messageContent = ["hint", "highlight", "true"]; + sendTutorMessage(updateType, messageContent); + } + } + else if(currentDetectorValues["help_model_try_if_low"]=="not acceptable/hint avoidance"){ + var updateType = "hint_window_message"; + var messageContent = "Please try asking for a hint."; + sendTutorMessage(updateType, messageContent); + + //highlight the hint button + var updateType = "interface_action"; + var messageContent = ["hint", "highlight", "true"]; + sendTutorMessage(updateType, messageContent); + } + else if(currentDetectorValues["help_model_try_if_low"]=="not acceptable/hint abuse"){ + var updateType = "hint_window_message"; + var messageContent = "Hey, take it easy there with those hints..."; + sendTutorMessage(updateType, messageContent); + + } + else if(currentDetectorValues["help_model_try_if_low"]=="ask teacher for help/try step"){ + var updateType = "hint_window_message"; + var messageContent = "Please ask your teacher for help on this step!"; + sendTutorMessage(updateType, messageContent); + } + else{ + var messageContent = ""; + } + + + if(currentDetectorValues["idle"]!="0, > 0 s"){ + var updateType = "musicOn"; + //relative filepath to an audio file + var messageContent = "Assets/fractionsSong.mp3"; + sendTutorMessage(updateType, messageContent); + + var updateType = "alertOn"; + //alert message, alert delay (ms) + var messageContent = ["Hi there. Do some math. ...Please?", 15000]; + sendTutorMessage(updateType, messageContent); + } + else{ + var updateType = "musicOff"; + sendTutorMessage(updateType, null); + + //tutor update type ("hint_window_message" or "other") + var updateType = "alertOff"; + sendTutorMessage(updateType, null); + } + + } + }, 800); +} + + +self.onmessage = function ( e ) { + console.log(variableName, " self.onmessage:", e, e.data, (e.data?e.data.commmand:null), (e.data?e.data.transaction:null), e.ports); + switch( e.data.command ) + { + case "connectMailer": + mailer = e.ports[0]; + mailer.onmessage = receive_transaction; + break; + case "initialize": + for (initItem in e.data.initializer){ + if (e.data.initializer[initItem].name == variableName){ + detector_output.history = e.data.initializer[initItem].history; + detector_output.value = e.data.initializer[initItem].value; + } + } + + + //optional: In "detectorForget", specify conditions under which a detector + //should NOT remember their most recent value and history (using the variable "detectorForget"). + //(e.g., setting the condition to "true" will mean that the detector + // will always be reset between problems... and setting the condition to "false" + // means that the detector will never be reset between problems) + // + detectorForget = true; + // + // + + if (detectorForget){ + detector_output.history = {}; + detector_output.value = 0; + } + + + //optional: If any global variables are based on remembered values across problem boundaries, + // these initializations should be written here + // + // + if (detector_output.history == "" || detector_output.history == null){ + //in the event that the detector history is empty, + //initialize variables to your desired 'default' values + // + // + } + else{ + //if the detector history is not empty, you can access it via: + // JSON.parse(detector_output.history); + //...and initialize your variables to your desired values, based on + //this history + // + // + } + + break; + default: + break; + + } + +} \ No newline at end of file diff --git a/HTML/Assets/fractionsSong.mp3 b/HTML/Assets/fractionsSong.mp3 new file mode 100644 index 0000000..58d153d Binary files /dev/null and b/HTML/Assets/fractionsSong.mp3 differ diff --git a/HTML/Assets/tutor_adaptivity/transaction_mailer_users.js b/HTML/Assets/tutor_adaptivity/transaction_mailer_users.js index 2129cee..29394f0 100644 --- a/HTML/Assets/tutor_adaptivity/transaction_mailer_users.js +++ b/HTML/Assets/tutor_adaptivity/transaction_mailer_users.js @@ -6,9 +6,10 @@ TransactionMailerUsers = mailerURL: "mail-worker.js", mailer: null, mailerPort: null, - scripts: ["Detectors/currentAttemptCount.js", - "Detectors/Lumilo/idle.js", - "Detectors/help_models/help_model_try_if_low.js"], + scripts: ["Detectors/Adaptivity/currentAttemptCount.js", + "Detectors/Adaptivity/idle.js", + "Detectors/Adaptivity/help_model_try_if_low.js", + "Detectors/Adaptivity/tutor_ear.js"], active: [] }; @@ -47,24 +48,75 @@ TransactionMailerUsers.create = function(path, txDestURL, scriptsDestURL, authTo } TransactionMailerUsers.active.push(detector); console.log("TransactionMailerUsers.create(): s, active["+i+"]=", s, TransactionMailerUsers.active[i]); - + detector.onmessage = function(e) { var sel = e.data.name; var action = "UpdateVariable"; var input = e.data.value; + var timerID; + + if(sel!="tutor_ear"){ + var sai = new CTATSAI(); + sai.setSelection(sel); + sai.setAction(action); + sai.setInput(input); + CTATCommShell.commShell.processComponentAction(sai=sai, tutorComponent=false, aTrigger="tutor"); + } + else if(input != ""){ + //selection action input + var transactionID=CTATGuid.guid(); + var updateType = e.data.history; + + if(updateType=="hint_window_message"){ + var builder = new CTATTutorMessageBuilder(); + var msg = builder.createHintMessage([input], new CTATSAI(), 32, transactionID); + msg = CTATMsgType.setProperty(msg, CTATTutorMessageBuilder.TRIGGER, "DATA"); + msg = CTATMsgType.setProperty(msg, CTATTutorMessageBuilder.SUBTYPE, CTATTutorMessageBuilder.TUTOR_PERFORMED); - var sai = new CTATSAI(); - sai.setSelection(sel); - sai.setAction(action); - sai.setInput(input) - CTATCommShell.commShell.processComponentAction(sai=sai, tutorComponent=false, aTrigger="tutor") + CTAT.ToolTutor.sendToInterface(msg); + } + else if(updateType=="alertOn"){ + timerID = setTimeout(function(){ + alert(input[0]); + audio.pause(); + }, input[1]); + } + else if(updateType=="alertOff"){ + clearTimeout(timerID); + } + else if(updateType=="musicOn"){ + var audio = document.getElementById('audio'); + audio.src = input; + if(audio.paused){ + audio.play(); + } + } + else if(updateType=="musicOff"){ + var audio = document.getElementById('audio'); + //if(!audio.paused){ + audio.pause(); + //} + } + else if(updateType=="interface_action"){ + var sai = new CTATSAI(input[0], input[1], input[2]); + var builder = new CTATTutoringServiceMessageBuilder(); + var msg = builder.createInterfaceActionMessage(transactionID, sai); + msg = CTATMsgType.setProperty(msg, CTATTutorMessageBuilder.TRIGGER, "DATA"); + msg = CTATMsgType.setProperty(msg, CTATTutorMessageBuilder.SUBTYPE, CTATTutorMessageBuilder.TUTOR_PERFORMED); + + CTAT.ToolTutor.sendToInterface(msg); + } + + } + + }; } return TransactionMailerUsers; -}; +}; TransactionMailerUsers.sendTransaction = function(tx) { diff --git a/HTML/fractionAddition.html b/HTML/fractionAddition.html index f37a547..9119469 100644 --- a/HTML/fractionAddition.html +++ b/HTML/fractionAddition.html @@ -20,6 +20,7 @@ +
Your browser does not support CTAT. Please update or use another browser.