Welcome!

Sign in with your CogSci, Facebook, Google, or Twitter account.

Or register to create a new account.

We'll use your information only for signing in to this forum.

Supported by

[open] Working with arrays and opensesame loops

neonneon Posts: 53
edited October 2013 in OpenSesame

Hi Opensesame dudes,

Quick tips wanted :-) I'm in the process of creating a digit recall task - x number of individual digits presented, separated by masks, then participant asked to recall the digits in the correct order.
I'm using a variable within a loop to get the digits displayed in the correct order, then when a certain flag digit appears within the list, it triggers the form where the particpant enters the digits they recall. This has to be checked to see if the proceed to the "next level" or the task is done.
Consequently I need to record the variable as it is within the loop, for certain periods. As such I was wanting to pop the variable on to a list or array. I can access the opensesame variable within the loop, but dont seem to be able to append it to an array or list.

Any suggestion where and how I would declare the array? In an inline script I've tried to make it global but it didn't work.
in the run phase, I've tried:

digitSpan = []

digitSpan.append(self.get('currentDigit'))

Where digitSpan is the array/list I want to create, and 'currentDigit' is the variable from the loop.
As you can tell, I'm not particularly familiar with python...And also its the end of the day so I am tired and probably making no sense!

Any suggestions gratefully received.

Neon

Comments

  • lvanderlindenlvanderlinden Posts: 292
    edited 2:39AM

    Hi Neon,

    If 'currentDigit' is a variable that is defined earlier in your experiment then your code should 'work' in the sense that it doesn't make your experiment crash.

    However, you are recreating the list item 'digitSpan', which is empty to begin with, every time the inline_script item is executed. Thus, it will never contain more than one item because every previous digitSpan will be overwritten by a new (empty) one in the next cycle. Do you see what I mean?

    To solve this, I would suggest appending an inline_script item to, for example, the beginning of your block sequence, where you define the (still empty) list like so:

    # Create the to-be-filled list:
    digitSpan = []
    # And make it global so that it can be used in future inline_script items as well:
    global digitSpan
    

    Next, you only place the following code in an inline_script item appended to your trial sequence:

    # Fill up the list:
    digitSpan.append(self.get('currentDigit'))
    

    A working example experiment can be found here (simply download and "save as" with the extension ".opensesame"):

    If this doesn't answer your question, could you please provide us with some more details about

    • what part of your experiment is not working (what's the error message?)
    • where/ how you defined the variable 'currentDigit'
    • the behaviour that you are aiming for (how are you going to use the digitSpan list afterwards?)

    Best wishes,

    Lotje

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • neonneon Posts: 53
    edited October 2013

    Hi Lotje,

    Thanks for your comprehensive reply, and sorry not to thank you earlier.
    Had been a very long day, which is why I overlooked the constant re-initialising of the variable digitSpan.

    So thats all fine but I have another question - if you think this should be started as a separate discussion, let me know and I'll create one (or you can if you have the relevant permissions!).

    Anyway, I am wanting to check the contents of text boxes with variables in a list. Is it possible to create an array of textboxes? Creating a loop and checking text box content against digits in a list should be easy, but not sure of best way to get a handle on the text boxes.

    OK - that sounds quite confusing; let me explain a bit better:

    digits are flashed up on the screen one after another. As they flash up, they are appended to a list (as I discussed in previous message). When all the digits have been been displayed, a form with 9 text boxes appears. The participant has to enter the digits in the boxes in the order they appeared. When they have done this, they click on a button, and a script checks whether they got all the digits correct.

    So for example, the digit 3 is diplayed, then the digit 1, then the digit 7. Nine blank text boxes appear, and the participant types in 3 in the first box, 1 in the second box and 7 in the last box and presses the continue button. The script then checks the list of digits displayed against the contents of the text boxes, calculates that they are all correct and the experiment continues.
    OR another scenario - the participant types in 3, then 7, then 1 in the box and presses continue. The script deduces that the participant has got it wrong and the experiment ends.

    Does this sound feasible to you? My main questions is, is it possible to have some code along the lines of (excuse my pseudo-code, I don't have much experience with Python):

    inc = 0
    partError = 0
    
    for items in list
       if textbox[inc].contents != digitSpan[ inc]
          partError = 1
       inc += 1
    

    --

    (sorry for bastardisation of c / python / perl pseudocode!)

    Does this make sense? The main part of my question is, is it possible to have a statement like

    if textbox[inc].contents != digitSpan[ inc]
    

    and if so, what would the syntax be?

    Thanks so much in advance. Loving Opensesame the more I use it!

    Neon

  • lvanderlindenlvanderlinden Posts: 292
    edited October 2013

    Hi Neon,

    I think something like the following should work. I'm not sure what you want the variables partError and inc to indicate exactly, so please let me know if you meant something else.

    Step 1: Append a form_base item showing 9 text_input boxes:

    Append a form_base item to, for example, your block_sequence (or at least a sequence that is one step higher in the hierarchy than the sequence carrying out the digit-span presentation). Click on the 'edit script' button at the top right, and add something like the following OpenSesame script:

    set rows "1;1;1;1"
    set cols "1;1;1"
    set description "A generic form plug-in"
    widget 0 0 1 1 text_input return_accepts="no" var="resp1" stub=""
    widget 1 0 1 1 text_input return_accepts="no" var="resp2" stub=""
    widget 2 0 1 1 text_input return_accepts="no" var="resp3" stub=""
    widget 0 1 1 1 text_input return_accepts="no" var="resp4" stub=""
    widget 1 1 1 1 text_input return_accepts="no" var="resp5" stub=""
    widget 2 1 1 1 text_input return_accepts="no" var="resp6" stub=""
    widget 0 2 1 1 text_input return_accepts="no" var="resp7" stub=""
    widget 1 2 1 1 text_input return_accepts="no" var="resp8" stub=""
    widget 2 2 1 1 text_input return_accepts="no" var="resp9" stub=""
    widget 1 3 1 1 button text="Next"
    
    Step 2: Append an inline_script item right after the form_base item:

    and add something like the following in its Run phase tab:

    # Create variables that will contain the digits presented in 
    # a given digit span, and give them the starting value "None".
    # The exp.set() function is explained in more detail below.
    for i in range(1,10):
        exp.set("digit%.2d" % i, "None")
    
    
    # Give the error counter (a variable that contains the number of 
    # errors made on a given trial) a starting value:
    errCount = 0
    
    # Run through a loop that has as many iterations as there 
    # were digits shown in the current trial:
    for i in range(0,len(digitSpan)):
    
        # For every iteration, determine the digit that was shown 
        # in the sketchpad:
        digit = digitSpan[i]
    
        # And determine the 'n-th' response that the participant 
        # gave, where n is the counter of the current iteration:
        # Note that Python starts counting at 0, whereas I 
        # made the response variables ("resp1", "resp2" etc.) start 
        # at 1, which is why we have to add 1 to the current 
        # iteration counter ("resp0" does not exist).
        resp = self.get("resp%s" % str(i+1))
    
        # Check whether they are the same.
        if digit != resp:
    
            # If not, add one to the variable errCount
            errCount +=1
    
        # Print everything for debugging:
        print "digit = %s, resp = %s, count = %s" % (digit, resp, errCount)
    
        # Make column headers containing "digit01", "digit02", 
        # etc., as shown on a given trial. For more info about 
        # setting variables, see the lines below.
    
        columnHeader = "digit%.2d" % (i +1)
        exp.set(columnHeader, digit)
    
    # Finally, use the experiment function exp.set() to set the 
    # variable 'errCount' so that it becomes available in the 
    # interface (e.g. the logger item or a feedback item) as well.
    # For more info, see:
    # http://osdoc.cogsci.nl/python/experiment/#experiment.set
    exp.set("errCount", errCount)
    
    # You could also make a variable simply indicating 
    # whether participants entire response
    # was correct (i.e., typed in the right digits in 
    # the right order) or incorrect:
    
    # If no errors were made:
    if errCount == 0:
        corr = "correct"
    
    # If at least one error was made:
    else:
        corr = "incorrect"
    
    # And again, set the variable for future use in the GUI:
    exp.set("corr", corr)
    
    print corr
    

    Don't forget to log the new variables by appending a logger item after the inline_script item.

    So in the end the overview area should look something like:

    image

    By the way, is there a reason for using nine separate text_input boxes, instead of just one text_input box where participants can type in all the digits they remember at once? I think the latter is more convenient, especially because participants will have to use the mouse to first click on a given box before being able to type in it.

    I hope this helps. Good luck and let us know if you have any further questions!

    Cheers,

    Lotje

    Thanked by 1NulPart

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • lvanderlindenlvanderlinden Posts: 292
    edited 2:39AM

    EDIT: I just added two lines of code to the beginning of the script above.

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • NulPartNulPart Posts: 1

    Hi there, thank you very much for your script, I'm using it for a video based digit span task.

    I'm using the text_input form, since I would like to have a single text_input box. Being rather new to OpenSesame, I'm having a bit of trouble figuring out how to modify your script so that the resulting digit sequence is recognized as a sequence of single digits (e.g. 2,7,3 instead of 273).

    Thank you for any answers pointing me in the right direction!

    Nulpart

Sign In or Register to comment.