Anonypy
Anonypy

Reputation: 73

Number string colours and trials. Need better solution

This is an excerpt from my full script (shortened so that it is more understandable).

I'm very much stuck at the moment.

Upvotes: 0

Views: 60

Answers (3)

Jonas Lindeløv
Jonas Lindeløv

Reputation: 5683

You should have a data structure that pairs the strings with the colors, and then put in the desired combinations. So something like:

import random
trials = [{'text': '1', 'color': 'red'},
         {'text': '1', 'color': 'red'},
         {'text': '1', 'color': 'red'},
         {'text': '1', 'color': 'green'},
         {'text': '1', 'color': 'blue'},
         {'text': '2', 'color': 'green'}]  # ... etc
random.shuffle(trials)
key_mapping = {'r': 'red', 'g':'green', 'b':'blue'}  # which keys means which color

for trial in trials:
    stimu.color = trial['color']
    stimu.text = trial['text']
    stimu.draw()
    ewindow.flip()

    response = event.waitKeys(keyList=key_mapping.keys())[0]  # get first response, only allow keys which have been mapped
    trial['correct'] = key_mapping[response] == trial['color']  # True if correct, False if incorrect

Notice also how I simplified the code for setting stimulus attributes and scoring response - partly made possible by a better data structure. Although a list of dictionaries seems like overkill here, you most likely want to add more info at a later stage (trial number, subject ID, reaction time, etc.) and then it becomes useful.

Upvotes: 0

TemporalWolf
TemporalWolf

Reputation: 7952

I would probably do:

import random

# Build the question list
red =   ['1'] * 3 + ['2'] + ['3']
green = ['1'] + ['2'] * 3 + ['3']
blue =  ['1'] + ['2'] + ['3'] * 3

questions = []
questions.extend([('red', x) for x in red])
questions.extend([('green', x) for x in green])
questions.extend([('blue', x) for x in blue])

random.shuffle(questions)

for color, number in questions:
    # do whatever

This allows for you to pretty readily change the lists and it will auto-compile and shuffle them for you:

[1]*3+[2]+[3] generates [1, 1, 1, 2, 3]

Essentially: I want 3 1s, a 2 and 3 in a list.

questions.extend extends the questions list with whatever list you pass it, so I want to put them all together.

[('red', x) for x in red] is a list comprehension which says: Make a new list, but for every number in that earlier list, instead say it's ('red', x) where x is what the old list had.

Finally, random.shuffle() shuffles the list so the order is random.

NOTE: This method (['1'] * 3 + ['2'] + ['3']) of list generation is not safe for mutable objects, but because strings are immutable, we're fine.

Upvotes: 1

Prune
Prune

Reputation: 77880

I suggest a different approach: store the objects you want with all of their characteristics: display character and colour. This gives you something like:

display_candidates = [
    ('1', 'r'), ('1', 'r'), ('1', 'r'),
    ('1', 'g'), ('1', 'b'),
    ('2', 'g'), ('2', 'g'), ('2', 'g'),
    ('2', 'b'), ('2', 'r'),
    ('3', 'b'), ('3', 'b'), ('3', 'b'),
    ('3', 'r'), ('3', 'g')
]

Now, you pull out a random display object with

import random

random.shuffle(display_candidates)
for number, colour in display_candidates:

Now, use colour for setColor, much as you've done above.

You'll need to slap a loop around this to make it run the desired number of times.

Does this get you moving?

Upvotes: 0

Related Questions