Help with a memory task, list repetition

Windows 8
Psychopy version 3.0
Standard Standalone?: yes
What are you trying to achieve?:
I am constructing a Complex Span Memory Task in which the participants need to remember a set of letters with distractors in between each letter, it is based on Oberauer, Jones & Lewandowsky (2015) paper on the Hebb repetition effect.
For example: C, distractor, K, distractor, L, distractor, and so on. I don’t have a problem with that, but I need a list of words that is the same every third trial. For example:
Trial 1: C, distractor, K, distractor, L, distractor…
Trial 2: F, distractor, J, distractor, H, distractor…
Trial 3: M, distractor, D, distractor, R, distractor…
Trial 4: T, distractor, W, distractor, B, distractor…
Trial 5: P, distractor, S, distractor, X, distractor…
Trial 6: M, distractor, D, distractor, R, distractor…

What did you try to make it work?:
I am attaching a screenshot of what I have done in builder. I tried separating the trials into the random ones and the repetition one, my idea was to somehow make psychopy create a random list of letters (as in the other trials) but in this case keep repeating that list on every third trial.

What specifically went wrong when you tried that?:

I don’t have any error, I just can’t make that specific trial to repeat the same list, I keep getting random letters on every trial.

Thank you so much for your help!

To get a useful reply, you need to specify your randomisation/counterbalancing design. Think the level of detail that would be required to explain your procedure in the method section of a paper or thesis. In particular, specify not only what happens within a run, but also across subjects.

i.e. how are the letters sampled within and across subjects? Are there constraints within trials (e.g. no letters the same)? Across trials (e.g. each letter shown the same number of times)? How many trials? etc, etc etc.

Thank you very much for your reply!
I need each trial to have a random list of 8 consonants, which it takes from an excel file with the all the letters. I am doing it like this:


And the same with the distractors.
So, each trial has 8 random consonants to remember (all different) with distractors in between and each participant needs to complete 24 trials. I need every trial to have a different random list of consonants, except for the repeated trial which I need it to be the same within the participant.
For example, for participant 1 the repeated list will be “H, L, N, G, T, P, W, R”, for participant 2 the repeated list will be “S, F, C, M, T, L, D, X” and so on.
The letters can be shown any number of times, as long are they are not repeated within a trial.

It is hard to explain, let me know if that is clear and enough information or if I need to explain something else.

Thank you very much!

With this sort of design, it would probably be better to select your list of letters for each trial (and the constant list of letters for each subject ) using some code snippets, rather than using conditions files. There will be something like 1010 possible permutations to choose from, so collisions will be effectively non-existent, and this would be easier and more reliable to work with. Are you happy to explore that route?

Thanks for your reply.
I´ll be happy to explore any route. I am new to programming, so I am not sure if I understand. You mean writting a code in python and adding it to psychopy?

Thank you for your help!

OK, insert a “code component” from the component panel. It will have multiple tabs, so you can paste in code that will run at specific times. In the Begin experiment tab, put something like this to create a function that you can use to select random samples of letters:

from numpy.random import choice    # to draw random samples
from string import ascii_uppercase # the upper case alphabet

# function you can call to get samples from the alphabet as required:
def choose_letters():
    alphabet = list(ascii_uppercase) # a list of length 26
    # sample 8 letters without replacement:
    sample = choice(alphabet, size = 8, replace = False)
    return list(sample) # convert from a numpy array to a list

# define a constant sample of letters that will apply for this 
# subject throughout their session:
session_list = choose_letters()

Your flow panel should have the target routine next to the distractor routine, and they should be nested together within a single loop (let’s call it letters: pro-tip – you should use meaningful names for loops, rather than just have them all called trialsxx: this will make your data much easier to analyse, and your flow panel with then actually describe your design/procedure).

letters should have an nReps value of 8 and doesn’t need to be connected to a conditions file (unless there are other variables you want to access).

letters should be nested within an outer loop called, say trials, which will have an nReps of 24, and again, no conditions file.

So now you need to define a new list of 8 letters that will apply throughout the trial, so we set this to just get a new list on the first iteration of the inner loop (so it will run once for every iteration of the outer loop, or once per trial). So in the Begin routine tab, put some code like this:

# only once per trial, update the letter list:
if letters.thisN == 0:
    # On every third trial, use the constant
    # session list, otherwise get a fresh sample:
    if (trials.thisN + 1) % 3 == 0:
        trial_letters = session_list
    else:
        trial_letters = choose_letters()

# on every iteration of the inner loop, select a new
# letter, indexing by the iteration number:
current_letter = trial_letters[letters.thisN]

# record it in the data:
thisExp.addData('current_letter', current_letter)

Make sure that the code component is placed above your text stimulus component (that way, the text component can refer to the latest variables defined in the code component). Then just put this in the text field:

$current_letter

and set that field to update on every repeat.

The magic sauce here is the % modulus operator, which gives us the remainder after dividing by 3. If the remainder is 0 (after adding 1 to the trial number to account for them starting at 0), then this is a trial with the constant letters.

Hey presto, you are in business, and with easy access to an almost infinite number of possible selections, as opposed to mucking about with conditions files.

2 Likes

Hi Michael,

Thank you so so much, this is perfect. I’ve been struggling with this for a long time, and turns out it was pretty easy. I learned a lot, thank you!
I just have one more question, the distractor is a size judgement task so I’ve set that they have to press the left or right arrow, once they press it it continues to the next one. My issue is that if there is no response after 2s then I need it to continue as well, I assume this also needs a code component (probably very simple), but I tried some options and it didn’t work. Can you help me with this?

Thanks you very much!

Probably no code required: I think you could just define your keyboard component to have a fixed duration of 2 s (and all other components end within that period too), but also set it so that a keypress forces the end of the routine.

This solved the problem.

Thank you very very much for your help!

Hi again Michael,

I found something else I need to add to my task. Is it possible to show the responses on the screen?
What I have now for the recall phase is just a Text and a keyboard component,


so that the participants can type in the alphabet letter they remember, but I need that response to show on the screen for them to see and then continue with the next response, and the same for the 8 consonants. Can you help me with this?

Thank you very much!

You can put a variable name as the contents of a text field (e.g. $current_letter), set to update “every frame”

Thank you for your answer.
This didn’t work. I’ve tried some codes on other posts but none of them work for me.
In the recall phase the participants need to type the letters they saw (e.g K, F, L…), my current experiment records their answer but doesn’t show it on the screen. What I need is that once they see the question mark, they press the letter on the keyboard and then that letter is shown on the screen for 3 seconds and then continue with the next recall, and the same for the 8 letters in each trial.
From other posts I figured I need to add a code component for this, could you help me out?

I made some progress with a code I found in another post, but I still need some help.
So this is how it looks on builder.


And this is the code I used:
Begin experiment tab:

msg=' '
alphabet = ["B","C","D","F","G","H","J",
    "K","L","M","N","P","R","S","T","V","W","X","Z"]

Each frame tab:

templist=C_response.keys
if templist.count('return')==1:
 C_response.keys.pop()
 C_response.keys=''.join(C_response.keys)
 C_response.rt=C_response.rt[0]
 continueRoutine=False
elif (len(C_response.keys)-1) == alphabet:
 msg=''
 msg=msg.join(C_response.keys)
alphabet=len(C_response.keys)

This works half ways. I have two problems:

  1. The letters are only displayed in lowercase (I changed the keyboard allowed keys to uppercase but it didn’t work).
  2. The question mark appears (from the Recalltext component) and when they press the letter it appears on the screen but overlapping with the next question mark. And I need it to be like this: Question mark, Letter (3s), Question mark, Letter (3s), and so on.

Can you help me out with this 2 issues?

Thank you!

Just have a moment, so can help with the first issue:

After you have constructed the variable msg, do this:

msg = msg.upper() # force to upper case

Thank you so much for your reply.
I am not sure if I understood, I did this:

msg = msg.upper() # force to upper case
alphabet = ["B","C","D","F","G","H","J",
   "K","L","M","N","P","R","S","T","V","W","X","Z"]

And it didn’t work, am I placing it in the wrong place? I also tried in the “Each frame” tab and nothing.

Also, I haven’t been able to fix the other problem, in case you have some time to address it.

Thank you very much!

Hi!
I solved the last issues, thank you very much for all your help!

hey,
Was your experiment a 1, 2 back?
And can I borrow to use?