List.SetAttrib is a function that you can use in E-Prime in an InLine code to change characteristics of your stimuli during the running of the task itself.
PSTNET provides this tutorial video on using List.SetAttrib, but does not share the sample script from the video to copy the inline code. So I replicated the script by transcribing what was onscreen, and here is that E-Studio file.
PSTNET provides this tutorial video on using List.SetAttrib, but does not share the sample script from the video to copy the inline code. So I replicated the script by transcribing what was onscreen, and here is that E-Studio file.
vowel_exp_same_as_online.es2 | |
File Size: | 62 kb |
File Type: | es2 |
Here is what the structure of the Experiment looks like. In this Experiment, participants are presented with letters A, B, C, and D, and are asked to press '0' if the letter is a vowel and '1' if the letter is a consonant. Using List.SetAttrib with a few InLines, E-Prime is set up to re-run whichever trials the participant performs incorrectly. The initial run of all 4 letters is detailed in TrialList and subsequently the TrialProc, which means that TrialList has four rows for each of the 4 letters. RerunList, on the other hand, is essentially empty, and the InLine code is set up to populate the RerunList with the attributes in TrialList for only the trials in TrialList that participants got wrong.
To do this, we have 3 InLines: InitErrorCount, TrackErrors, and SetRerunList. Let's look at each of these InLines.
InitErrorCount initializes the variable called g_nErrorCount to 0, which is the initial number of errors participants have made. Here is that code:
g_nErrorCount = 0
TrackErrors is more complicated. Here is the code:
To do this, we have 3 InLines: InitErrorCount, TrackErrors, and SetRerunList. Let's look at each of these InLines.
InitErrorCount initializes the variable called g_nErrorCount to 0, which is the initial number of errors participants have made. Here is that code:
g_nErrorCount = 0
TrackErrors is more complicated. Here is the code:
If Stim.ACC = 0 Then
g_nErrorCount = g_nErrorCount + 1
If g_nErrorCount > 1 Then
RerunList.AddLevel g_nErrorCount
End If
RerunList.SetWeight g_nErrorCount, 1
RerunList.SetProc g_nErrorCount, "RerunProc"
RerunList.SetAttrib g_nErrorCount, "Stimulus", c.GetAttrib("Stimulus")
RerunList.SetAttrib g_nErrorCount, "CorrectAnswer", c.GetAttrib("CorrectAnswer")
End If
g_nErrorCount = g_nErrorCount + 1
If g_nErrorCount > 1 Then
RerunList.AddLevel g_nErrorCount
End If
RerunList.SetWeight g_nErrorCount, 1
RerunList.SetProc g_nErrorCount, "RerunProc"
RerunList.SetAttrib g_nErrorCount, "Stimulus", c.GetAttrib("Stimulus")
RerunList.SetAttrib g_nErrorCount, "CorrectAnswer", c.GetAttrib("CorrectAnswer")
End If
In plain English, this code says if the particular trial the participant is on right now is performed incorrectly then add 1 to our error counter variable g_nErrorCount, and if g_nErrorCount is greater than 1, we are going to add a row. Furthermore, if the participant makes an error on a particular trial, we are going to take all of the attributes of that trial and copy and paste them into the RerunList to be run again.
The code RerunList.AddLevel g_nErrorCount is a bit strange. A level in E-Prime means a row in a list. RerunList.AddLevel is the simple part; this just means to add a row to RerunList. But the List.AddLevel command doesn't ask for how many levels to add, but which row to add. This means that for the first error a participant makes, RerunList will get a row 1, and for the second error RerunList will get a row 2, etc. These rows are added one by one as the participant makes a new error.
Let's say the participant hits 0 on the first trial to correctly identify letter A as a vowel, but then accidentally hits 0 again, calling B a vowel. After the A trial, RerunList is still empty, and g_nErrorCount is still equal to 0. But after the B trial, g_nErroCount is now 1, and a row 1 is added to RerunList.
The next part (lines 6-9) uses List.SetAttrib to assign values to this new, empty row 1 of RerunList. Row 6 makes the weight of this row 1, meaning a letter B trial will be repeated only once. If you changed the 1 to a 10, participants would be punished by having to redo the B trial 10 times. The g_nErrorCount is used as an index, so that E-Prime knows to assign this new weight in the RerunList to row 1 (as g_nErrorCount is equal to 1 at this point).
Line 7 sets the procedure of this row 1 as RerunProc, which as you can see from the Experiment structure, is identical to TrialProc except it doesn't have any InLine to track errors. This means that any errors you make in the RerunList will not lead to any more repeated trials (though could recycle the TrialProc instead if you wanted to make sure the participants got all of the stimuli right before exiting the experiment). The g_nErrorCount is again used as an index, so that E-Prime knows to assign this new procedure in the RerunList to row 1 (as g_nErrorCount is still equal to 1 at this point).
Line 8 adds an Attribute (or column) called "Stimulus" to RerunList, and fills row 1 (as g_nErrorCount is still equal to 1 at this point) with whatever is in TrialList row 1 under its "Stimulus" Attribute. In this last part (c.GetAttrib("Stimulus")), the "c." portion means to get the current value of the "Stimulus" Attribute of the list we are currently running (which is still TrialList), which is letter B in this case.
Line 9, like Line 8, adds an Attribute (or column) called "CorrectAnswer" to RerunList, and fills row 1 (as g_nErrorCount is still equal to 1 at this point) with whatever is in in TrialList row 1 under its "CorrectAnswer" Attribute. Again, in this last part (c.GetAttrib("CorrectAnswer")), the "c." portion means to get the current value of the "CorrectAnswer" Attribute of the list we are currently running (which is still TrialList), which is 1 at this point, since 1 is the correct response for the letter B.
Because the TrackErrors InLine is embedded in the TrialProc, it is run on every trial, which makes sense, as we want to identify errors on a trial by trial basis. Once all 4 trials have been run, the SetRerunList InLine is run, which has this code:
The code RerunList.AddLevel g_nErrorCount is a bit strange. A level in E-Prime means a row in a list. RerunList.AddLevel is the simple part; this just means to add a row to RerunList. But the List.AddLevel command doesn't ask for how many levels to add, but which row to add. This means that for the first error a participant makes, RerunList will get a row 1, and for the second error RerunList will get a row 2, etc. These rows are added one by one as the participant makes a new error.
Let's say the participant hits 0 on the first trial to correctly identify letter A as a vowel, but then accidentally hits 0 again, calling B a vowel. After the A trial, RerunList is still empty, and g_nErrorCount is still equal to 0. But after the B trial, g_nErroCount is now 1, and a row 1 is added to RerunList.
The next part (lines 6-9) uses List.SetAttrib to assign values to this new, empty row 1 of RerunList. Row 6 makes the weight of this row 1, meaning a letter B trial will be repeated only once. If you changed the 1 to a 10, participants would be punished by having to redo the B trial 10 times. The g_nErrorCount is used as an index, so that E-Prime knows to assign this new weight in the RerunList to row 1 (as g_nErrorCount is equal to 1 at this point).
Line 7 sets the procedure of this row 1 as RerunProc, which as you can see from the Experiment structure, is identical to TrialProc except it doesn't have any InLine to track errors. This means that any errors you make in the RerunList will not lead to any more repeated trials (though could recycle the TrialProc instead if you wanted to make sure the participants got all of the stimuli right before exiting the experiment). The g_nErrorCount is again used as an index, so that E-Prime knows to assign this new procedure in the RerunList to row 1 (as g_nErrorCount is still equal to 1 at this point).
Line 8 adds an Attribute (or column) called "Stimulus" to RerunList, and fills row 1 (as g_nErrorCount is still equal to 1 at this point) with whatever is in TrialList row 1 under its "Stimulus" Attribute. In this last part (c.GetAttrib("Stimulus")), the "c." portion means to get the current value of the "Stimulus" Attribute of the list we are currently running (which is still TrialList), which is letter B in this case.
Line 9, like Line 8, adds an Attribute (or column) called "CorrectAnswer" to RerunList, and fills row 1 (as g_nErrorCount is still equal to 1 at this point) with whatever is in in TrialList row 1 under its "CorrectAnswer" Attribute. Again, in this last part (c.GetAttrib("CorrectAnswer")), the "c." portion means to get the current value of the "CorrectAnswer" Attribute of the list we are currently running (which is still TrialList), which is 1 at this point, since 1 is the correct response for the letter B.
Because the TrackErrors InLine is embedded in the TrialProc, it is run on every trial, which makes sense, as we want to identify errors on a trial by trial basis. Once all 4 trials have been run, the SetRerunList InLine is run, which has this code:
If g_nErrorCount > 0 Then
Set RerunList.TerminateCondition = Cycles(1)
Set RerunList.ResetCondition = Samples(g_nErrorCount)
RerunList.Reset
Else
GoTo EndOfBlock
End If
Set RerunList.TerminateCondition = Cycles(1)
Set RerunList.ResetCondition = Samples(g_nErrorCount)
RerunList.Reset
Else
GoTo EndOfBlock
End If
This code is modifying properties of RerunList only if the participant made at least one error. Remember, at this point in the Experiment, the participant has made it through TrialList and the RerunList has been created based on how many errors were made. If there were more than 0 errors, Line 2 says to let RerunList run through one cycle and then terminate, or exit, the list. Line 3 says to reset RerunList after as many samples as there are errors. If you don't run this line, E-Prime will only run 1 trial, even if the participant made more than 1 error.
If there were no errors (the Else part), the Experiment will jump to the Label EndofBlock, which as you can see from the structure, happens after RerunList, but before the Goodbye TextDisplay, effectively skipping the RerunList and the RepeatTrials TextDisplay.
Finally, despite its foreboding name, RerunList.Reset saves these changes.
Weird quirks that I cannot yet explain:
Hopefully that is at least somewhat helpful in explaining what List.SetAttrib does. At the very least, you don't have to watch that video tutorial like I did and try to painstakingly copy it verbatim.
If there were no errors (the Else part), the Experiment will jump to the Label EndofBlock, which as you can see from the structure, happens after RerunList, but before the Goodbye TextDisplay, effectively skipping the RerunList and the RepeatTrials TextDisplay.
Finally, despite its foreboding name, RerunList.Reset saves these changes.
Weird quirks that I cannot yet explain:
- I have only been able to get this script to run with an empty level (i.e., row) in RerunList that has a weight of 0. Without an empty row, it has a problem.
- RerunList needs the Attributes (i.e., columns) "Weight", "Procedure", "Stimulus", and "CorrectAnswer" before you start. They are empty.
- You need to tell E-Prime that g_nErrorCount is an integer variable with the code dim g_nErrorCount as integer. I've tried adding it to InitErrorCount, but it won't run that way. So you have to put it in the user script. To do that, go to View > Script. On the script, you should see two tabs at the bottom: "User" and "Full". On the "User" tab (which looks like an InLine, meaning it's blank and white), you need dim g_nErrorCount as integer.
Hopefully that is at least somewhat helpful in explaining what List.SetAttrib does. At the very least, you don't have to watch that video tutorial like I did and try to painstakingly copy it verbatim.