Millisecond Forums

How do I modify the Letter Memory Task in such a way that it operates with words rather than letters ?

https://forums.millisecond.com/Topic25951.aspx

By labdandeneau@gmail.com - 10/27/2018

We have been tinkering with the Letter Memory Task to use it for word recognition rather than letter recognition. While we have been successful in making the task recognize a full word as an answer, we still can't enter more than one word as an answer (we want the participants to answer with the last 3 words they remember seeing, just like LMT demands an answer with last 3 letters).  The task also only seem to recognize the last 3 letters of the last shown word as the right answer. However, we'd like the task to recognize the last 3 words (independently of the order in which the participants give them) as the correct answer and give feedback that is concordant with that.

A file is attached that shows our work so far.
By Dave - 10/28/2018

labdandeneau@gmail.com - Saturday, October 27, 2018
We have been tinkering with the Letter Memory Task to use it for word recognition rather than letter recognition. While we have been successful in making the task recognize a full word as an answer, we still can't enter more than one word as an answer (we want the participants to answer with the last 3 words they remember seeing, just like LMT demands an answer with last 3 letters).  The task also only seem to recognize the last 3 letters of the last shown word as the right answer. However, we'd like the task to recognize the last 3 words (independently of the order in which the participants give them) as the correct answer and give feedback that is concordant with that.

A file is attached that shows our work so far.

<trial recall_word>
/ ontrialbegin = [
values.last3 = substring(values.presentedWords, length(values.presentedWords) - 3, 3);
values.recallCount += 1;
if (values.recallCount == 1){
values.RecallStart = script.elapsedtime;
};
]
/ stimulusframes = [1=WhiteScreen, sentimental, talkative, religious, thrifty, curious, excited, systematic, serious, definite, deliberate, meticulous, mediative, quick, precise, subtle, idealistic, _, clear, exit, recalledwords, recallprompt]
/ validresponse = (sentimental, talkative, religious, thrifty, curious, excited, , systematic, serious, definite, deliberate, meticulous, mediative, quick, precise, subtle, idealistic, _, clear, exit)
/ monkeyresponse = ("sentimental", "talkative", "religious", "thrifty", "curious", "excited", "systematic", "serious", "definite", "deliberate", "meticulous", "mediative", "quick", "precise", "subtle", "idealistic", "exit")
/ ontrialend = [
if(trial.recall_word.response!="exit" && trial.recall_word.response!="clear") {
values.recalledwords=concat(values.recalledwords, trial.recall_word.response);
values.recalledwords = substring(values.recalledwords, 0, 3);
};
if(trial.recall_word.response=="clear") {
values.recalledwords="";
};
if (trial.recall_word.response == "exit"){
values.RecallEnd = script.elapsedtime;
};
]
...
</trial>

You're concatenating the responses to a value per

values.recalledwords=concat(values.recalledwords, trial.recall_word.response);

and then you're mereley extracting a substring of the 1st three letters of the entire substring per

values.recalledwords = substring(values.recalledwords, 0, 3);

Why?

In the same vein, this doesn't make sense either:

<trial recall_end>
/ ontrialbegin = [
values.recallDuration = values.RecallEnd - values.RecallStart;
values.temp_last3 = values.last3;

values.recalledwords = concat(values.recalledwords, " ");
if (contains(values.temp_last3, substring(values.recalledwords, 0, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 0, 1), "");
};
if (contains(values.temp_last3, substring(values.recalledwords, 1, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 1, 1), "");
};
if (contains(values.temp_last3, substring(values.recalledwords, 2, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 2, 1), "");
};

list.correctwords.insertitem(values.countCorrectWords, 1);


if (values.countCorrectWords != 3){
trial.recall_end.insertstimulusframe(text.errorFeedback, 1);
values.correct = 0;
} else {
trial.recall_end.insertstimulusframe(text.correctFeedback, 1);
values.correct = 1;
};
list.accuracy.insertitem(values.correct, 1);
]
/ stimulusframes = [1 = clearscreen, continue]
/ validresponse = (continue)
/ recorddata = true
/ posttrialpause = parameters.ITI
</trial>

Nowhere are you actually keeping the entire words, you're just extracting single letters and keeping those around. What you'll probably want to do is keep the words intact and use the contains() string function to check whether the response string holds the proper words.
By Dave - 10/29/2018

Dave - Monday, October 29, 2018
labdandeneau@gmail.com - Saturday, October 27, 2018
We have been tinkering with the Letter Memory Task to use it for word recognition rather than letter recognition. While we have been successful in making the task recognize a full word as an answer, we still can't enter more than one word as an answer (we want the participants to answer with the last 3 words they remember seeing, just like LMT demands an answer with last 3 letters).  The task also only seem to recognize the last 3 letters of the last shown word as the right answer. However, we'd like the task to recognize the last 3 words (independently of the order in which the participants give them) as the correct answer and give feedback that is concordant with that.

A file is attached that shows our work so far.

<trial recall_word>
/ ontrialbegin = [
values.last3 = substring(values.presentedWords, length(values.presentedWords) - 3, 3);
values.recallCount += 1;
if (values.recallCount == 1){
values.RecallStart = script.elapsedtime;
};
]
/ stimulusframes = [1=WhiteScreen, sentimental, talkative, religious, thrifty, curious, excited, systematic, serious, definite, deliberate, meticulous, mediative, quick, precise, subtle, idealistic, _, clear, exit, recalledwords, recallprompt]
/ validresponse = (sentimental, talkative, religious, thrifty, curious, excited, , systematic, serious, definite, deliberate, meticulous, mediative, quick, precise, subtle, idealistic, _, clear, exit)
/ monkeyresponse = ("sentimental", "talkative", "religious", "thrifty", "curious", "excited", "systematic", "serious", "definite", "deliberate", "meticulous", "mediative", "quick", "precise", "subtle", "idealistic", "exit")
/ ontrialend = [
if(trial.recall_word.response!="exit" && trial.recall_word.response!="clear") {
values.recalledwords=concat(values.recalledwords, trial.recall_word.response);
values.recalledwords = substring(values.recalledwords, 0, 3);
};
if(trial.recall_word.response=="clear") {
values.recalledwords="";
};
if (trial.recall_word.response == "exit"){
values.RecallEnd = script.elapsedtime;
};
]
...
</trial>

You're concatenating the responses to a value per

values.recalledwords=concat(values.recalledwords, trial.recall_word.response);

and then you're mereley extracting a substring of the 1st three letters of the entire substring per

values.recalledwords = substring(values.recalledwords, 0, 3);

Why?

In the same vein, this doesn't make sense either:

<trial recall_end>
/ ontrialbegin = [
values.recallDuration = values.RecallEnd - values.RecallStart;
values.temp_last3 = values.last3;

values.recalledwords = concat(values.recalledwords, " ");
if (contains(values.temp_last3, substring(values.recalledwords, 0, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 0, 1), "");
};
if (contains(values.temp_last3, substring(values.recalledwords, 1, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 1, 1), "");
};
if (contains(values.temp_last3, substring(values.recalledwords, 2, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 2, 1), "");
};

list.correctwords.insertitem(values.countCorrectWords, 1);


if (values.countCorrectWords != 3){
trial.recall_end.insertstimulusframe(text.errorFeedback, 1);
values.correct = 0;
} else {
trial.recall_end.insertstimulusframe(text.correctFeedback, 1);
values.correct = 1;
};
list.accuracy.insertitem(values.correct, 1);
]
/ stimulusframes = [1 = clearscreen, continue]
/ validresponse = (continue)
/ recorddata = true
/ posttrialpause = parameters.ITI
</trial>

Nowhere are you actually keeping the entire words, you're just extracting single letters and keeping those around. What you'll probably want to do is keep the words intact and use the contains() string function to check whether the response string holds the proper words.

FWIW, using list elements to store both the presented words as well as the reponses is probably easier than using only values.
By Dave - 10/29/2018

Dave - Monday, October 29, 2018
Dave - Monday, October 29, 2018
labdandeneau@gmail.com - Saturday, October 27, 2018
We have been tinkering with the Letter Memory Task to use it for word recognition rather than letter recognition. While we have been successful in making the task recognize a full word as an answer, we still can't enter more than one word as an answer (we want the participants to answer with the last 3 words they remember seeing, just like LMT demands an answer with last 3 letters).  The task also only seem to recognize the last 3 letters of the last shown word as the right answer. However, we'd like the task to recognize the last 3 words (independently of the order in which the participants give them) as the correct answer and give feedback that is concordant with that.

A file is attached that shows our work so far.

<trial recall_word>
/ ontrialbegin = [
values.last3 = substring(values.presentedWords, length(values.presentedWords) - 3, 3);
values.recallCount += 1;
if (values.recallCount == 1){
values.RecallStart = script.elapsedtime;
};
]
/ stimulusframes = [1=WhiteScreen, sentimental, talkative, religious, thrifty, curious, excited, systematic, serious, definite, deliberate, meticulous, mediative, quick, precise, subtle, idealistic, _, clear, exit, recalledwords, recallprompt]
/ validresponse = (sentimental, talkative, religious, thrifty, curious, excited, , systematic, serious, definite, deliberate, meticulous, mediative, quick, precise, subtle, idealistic, _, clear, exit)
/ monkeyresponse = ("sentimental", "talkative", "religious", "thrifty", "curious", "excited", "systematic", "serious", "definite", "deliberate", "meticulous", "mediative", "quick", "precise", "subtle", "idealistic", "exit")
/ ontrialend = [
if(trial.recall_word.response!="exit" && trial.recall_word.response!="clear") {
values.recalledwords=concat(values.recalledwords, trial.recall_word.response);
values.recalledwords = substring(values.recalledwords, 0, 3);
};
if(trial.recall_word.response=="clear") {
values.recalledwords="";
};
if (trial.recall_word.response == "exit"){
values.RecallEnd = script.elapsedtime;
};
]
...
</trial>

You're concatenating the responses to a value per

values.recalledwords=concat(values.recalledwords, trial.recall_word.response);

and then you're mereley extracting a substring of the 1st three letters of the entire substring per

values.recalledwords = substring(values.recalledwords, 0, 3);

Why?

In the same vein, this doesn't make sense either:

<trial recall_end>
/ ontrialbegin = [
values.recallDuration = values.RecallEnd - values.RecallStart;
values.temp_last3 = values.last3;

values.recalledwords = concat(values.recalledwords, " ");
if (contains(values.temp_last3, substring(values.recalledwords, 0, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 0, 1), "");
};
if (contains(values.temp_last3, substring(values.recalledwords, 1, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 1, 1), "");
};
if (contains(values.temp_last3, substring(values.recalledwords, 2, 1))){
values.countCorrectWords += 1;
values.temp_last3 = replaceall(values.temp_last3, substring(values.recalledwords, 2, 1), "");
};

list.correctwords.insertitem(values.countCorrectWords, 1);


if (values.countCorrectWords != 3){
trial.recall_end.insertstimulusframe(text.errorFeedback, 1);
values.correct = 0;
} else {
trial.recall_end.insertstimulusframe(text.correctFeedback, 1);
values.correct = 1;
};
list.accuracy.insertitem(values.correct, 1);
]
/ stimulusframes = [1 = clearscreen, continue]
/ validresponse = (continue)
/ recorddata = true
/ posttrialpause = parameters.ITI
</trial>

Nowhere are you actually keeping the entire words, you're just extracting single letters and keeping those around. What you'll probably want to do is keep the words intact and use the contains() string function to check whether the response string holds the proper words.

FWIW, using list elements to store both the presented words as well as the reponses is probably easier than using only values.

Here's a quick modification (only partly tested & not made to look pretty) using lists, this should give you the general idea.