JsPsych按准确率标准循环试次陷入无限循环问题求助
JsPsych数学测验无限循环问题排查
我是JsPsych新手,正在开发一个简单的数学测验任务,需求是随机展示数学题目,用户答对10题后任务结束。目前代码实现了随机选题和循环功能,但陷入无限循环,不确定错误出在以下哪一处:
- 正确答案定义位置
- 答对次数计数逻辑
- 题目循环逻辑
附上两次尝试的代码,麻烦帮忙排查。
第一次尝试代码
<!DOCTYPE html> <html> <head> <!-- all preloads go into head --> <title>Math Quiz</title> <!-- any plugins go here--> <script src="jspsych/dist/jspsych.js"></script> <script src = "jspsych/dist/plugin-survey-text.js"></script> <link href="jspsych/dist/jspsych.css" rel="stylesheet" type="text/css" /> </head> <body> <!-- all script for tasks go into body--> <script> var jsPsych = initJsPsych(); var timeline = []; // create a randomly selected math problem prompt and define correct answer var test = { type: jsPsychSurveyText, questions: [ { prompt: function() { var MathQuest = [ '2+2', '3+7', 'How many weeks in a year?' ]; var mathProblems = jsPsych.randomization.sampleWithReplacement(MathQuest, 1)[0]; return mathProblems; }, name: 'resp', } ], post_trial_gap: 500, on_finish: function(data) { var correctResponses = { '2+2' : '4', '3+7' : '10', 'How many weeks in a year?' : '52' }; var response = data.response; if (correctResponses[data.prompt] === response) { data.correct = true; } else { data.correct = false; } } }; // end test trial // Create a loop node for the test with accuracy criteria: var correctCount = 0; // Counter for correct responses var loopNode = { timeline: [test], loop_function: function(data) { // Check if the loop should continue based on the number of correct responses if (correctCount < 10) { if (data.values()[0].correct) { correctCount++; } return true; // Continue the loop } else { return false; // End the loop } console.log("Correct Count: " + correctCount); }, }; jsPsych.run([loopNode]); </script> </body> </html>
第二次尝试代码
<!DOCTYPE html> <html> <head> <!-- all preloads go into head --> <title>Math Quiz Take 2</title> <!-- any plugins go here--> <script src="jspsych/dist/jspsych.js"></script> <script src = "jspsych/dist/plugin-survey-text.js"></script> <link href="jspsych/dist/jspsych.css" rel="stylesheet" type="text/css" /> </head> <body> <!-- all script for tasks go into body--> <script> var jsPsych = initJsPsych(); var timeline = []; var mathQuestions = [ {math: '2+2 = ?', correct: '4'}, {math: '2x3 = ?', correct: '6'}, {math: '5x7 = ?', correct: '35'} ]; var test = { type: jsPsychSurveyText, questions: [ { prompt: jsPsych.timelineVariable('math'), name: 'resp' } ], on_finish: function(data) { data.correct=jsPsych.timelineVariable('correct'); var acc = 0; var response = data.response.resp; if (response == data.correct){ acc++; } } }; var mathQuestionProcedure = { timeline: [test], timeline_variables: mathQuestions, loop_function: function(data) { if (acc < 2) { return true; //go to criteria } else { return false; //end loop } } } timeline.push(mathQuestionProcedure); jsPsych.run([mathQuestionProcedure]) </script> </body> </html>
问题排查与修正
第一次尝试的核心问题
data.prompt无法获取当前题目文本:
你在prompt里用了函数动态生成题目,但JsPsych不会把函数的返回值存储到data.prompt中,所以correctResponses[data.prompt]永远找不到匹配项,data.correct一直是false,导致correctCount永远不会增加,循环永远停不下来。console.log位置无效:
它被放在return语句之后,永远不会执行,没法调试计数情况。
修正方案:
在生成题目时,把当前题目文本主动存入数据中,然后在on_finish里用这个存储的字段判断答案:
prompt: function() { var MathQuest = ['2+2', '3+7', 'How many weeks in a year?']; var mathProblems = jsPsych.randomization.sampleWithReplacement(MathQuest, 1)[0]; // 把当前题目存入数据 jsPsych.data.addData({current_question: mathProblems}); return mathProblems; },
然后在on_finish里修改判断逻辑:
on_finish: function(data) { var correctResponses = { '2+2' : '4', '3+7' : '10', 'How many weeks in a year?' : '52' }; // 用存储的current_question匹配正确答案 var response = data.response.resp; // survey-text插件的response是对象,要取name对应的字段 data.correct = (correctResponses[data.current_question] === response); }
同时把console.log移到return之前,确保能输出计数。
第二次尝试的核心问题
acc变量作用域错误:acc定义在on_finish函数内部,每次触发on_finish都会重置为0,而且loop_function里访问的acc是全局变量,根本没被赋值过(始终是undefined),undefined < 2永远为真,循环停不下来。timelineVariable在on_finish中无法正确获取值:on_finish执行时,timeline变量的上下文已经结束,应该用data.timeline_variables.correct来获取当前题目的正确答案。
修正方案:
- 把
acc定义在全局作用域,作为累计计数器; - 修改
on_finish里的逻辑,正确判断答案并更新计数器; - 在
loop_function里根据计数器判断是否停止循环:
// 全局定义计数器 var correctCount = 0; var test = { type: jsPsychSurveyText, questions: [ { prompt: jsPsych.timelineVariable('math'), name: 'resp' } ], on_finish: function(data) { // 获取当前题目的正确答案 var correctAnswer = data.timeline_variables.correct; var userResponse = data.response.resp; // 判断是否正确,并存入数据 data.correct = (userResponse === correctAnswer); // 如果正确,更新计数器 if(data.correct){ correctCount++; } } }; var mathQuestionProcedure = { timeline: [test], timeline_variables: mathQuestions, // 随机选题,满足需求 randomize_order: true, loop_function: function(data) { // 答对2题就停止(可改成10) return correctCount < 2; } }
内容的提问来源于stack exchange,提问作者mbeasle2
相关产品推荐
相关产品推荐

