Creating a dict and iterating through it online

OS (e.g. Win10): Win10
PsychoPy version (e.g. 1.84.x): 3.0
**Standard Standalone? (y/n) y
**What are you trying to achieve?:

I am trying to port an existing PsychoPy experiment online and am having issues iterating through a dictionary so it runs online. Essentially I am creating a dict that adds a word and associated value (e.g., “cat” : 1) after each trial. I want Ps to recall as many words as they can (free recall) and then reference their typed responses to the dictionary that adds up the values.

**What did you try to make it work?:

#Begin Experiment
var word_rating = {}; # JS code to create a dictionary called word_rating
#End Routine
word_rating[word1] = value1; # add word and value from spreadsheet
# Typed Response Routine
Take typed responses and iterate through loop

response_list=[typed_response.text] # save typed responses to array
str1= response_list.join("")
str2=str1.split{"")

thisExp.addData("response1",str1)
thisExp.addData("response2",str2)

total = 0 

for response in str2:
    if response in word_rating.keys():
        total = total + word_rating[response]

In python the above works fine.

**What specifically went wrong when you tried that?:

The experiment returns an error that it cannot find the var word_rating.

Any help on how to fix this would be greatly appreciated.

Could you copy-paste the JS that you’re working with?

Thanks for responding Thomas!

Changing the var word_rating to just word_rating seemed to have worked.

The JS code below is what I am having trouble with. I want to reference the dictionary words and values and sum them for a total score.

var _pj;
function _pj_snippets(container) {
    function in_es6(left, right) {
        if (((right instanceof Array) || ((typeof right) === "string"))) {
            return (right.indexOf(left) > (- 1));
        } else {
            if (((right instanceof Map) || (right instanceof Set) || (right instanceof WeakMap) || (right instanceof WeakSet))) {
                return right.has(left);
            } else {
                return (left in right);
            }
        }
    }
    container["in_es6"] = in_es6;
    return container;
}
_pj = {};
_pj_snippets(_pj);
response_list = [typed_response.text]; # take typed responses
str1 = response_list.join(" "); # join them 
str2 = str1.split(","); # split them
thisExp.addData("response1", str1);
thisExp.addData("response2", str2);
total = 0; # start with 0 total and iterate
for (var response, _pj_c = 0, _pj_a = str2, _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
    response = _pj_a[_pj_c];
    if (_pj.in_es6(response, value)) {
        total = (total + word_list[response]);
    }
}
thisExp.addData("total", total);

here I get th var value not found error

Here is link to my repository: https://pavlovia.org/Jgeller112/reward_recall if that is helpful.

I suspect it’s a scoping issue. Try replacing word_rating by window.word_rating. No need to declare it with var.

Hi @jgeller112, in Builder could you try placing var word_rating = {}; in the “Before Experiment” instead of the “Begin Routine” tab of your Code Component properties window? x

You may need to first upgrade to PsychoPy latest for that to work, x

Thanks for the comments!

The newest push should have word_rating = {} in the begin experiment tab. I am also using the newest version of PsychoPy.

Everything works until it starts iterating the loop. The JS is declaring value and it’s not defined.

Sorry you seem to be running 2020.2.5, but the latest version is 2020.2.10. Thanks, x

My apologies. I pushed the latest experiment with the newest version of PsychoPy. I declared the word_rating variable in the Begin_Experiment component with the var and it works. It does not work when placed in Before_Experiment component.

My main issue is that the I am not able to loop through the dictionary and reference it to the typed responses. I get an error about the variable value not being referenced in the JS code.

for (var response, _pj_c = 0, _pj_a = str2, _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
    response = _pj_a[_pj_c];
    if (_pj.in_es6(response, value)) {
        total = (total + word_list[response])

I am having trouble converting this python code to js:

for response in str2:
    if response in word_rating.keys():
        total = total + word_rating[response]

Hi @jgeller112, is this more or less what you are aiming for?

Without touching any of your custom code, I opened the .psyexp in PsychoPy and chose “Export HTML” from the File menu before re-syncing with Pavlovia.

x

Thanks for looking into this! I ran presumably the experiment you pushed, but I am getting this error:

And this error:

OK I have replaced the auto-translated JS with something a little less convoluted hopefully, is it working as expected? x

It is almost there! However, it does not seem to be adding up the values correctly.

Does JS store the letter strings typed out differently than Python? In Python the strings are stored as one letter string which is why I wrote some code to split them up and reference them to the dict.

Why do you say it does not seem to be adding up the values correctly?

Please note your word_rating object has the key "dog " with a trailing whitespace character added in

Each word is associated with a certain value and typing them all should give me 30, but is is giving me 10. This makes me think JS is parsing the typed responses differently than Python?

Sorry could you try typing "dog " instead of “dog”?