base timing of a trial on total time taken in previous trials--mismatch error?

Janet Trammell janet.trammell at gmail.com
Fri Jul 1 21:00:24 UTC 2011


I do now have a perfectly good working solution that makes sense, but
the solution you just posted looks a whole lot "cleaner".  I think
this will be really useful if I ever need to do this again, and it
looks like it can be adapted to similar situations.  Many thanks for
your help!

Janet

On Jul 1, 4:11 pm, David McFarlane <mcfar... at msu.edu> wrote:
> The original poster figured out a solution using
> an array, as posted on the PST Forum
> (http://www.pstnet.com/forum/Topic5419-7-1.aspx
> ).  Since I already figured out an alternative
> solution without using an array, I am posting it
> here just to show that I could do it.
>
> First, I will restate the specifications:
>
> (1) A block of trials will last for either some
> specified time (e.g., 10 min) or for 12 trials, whichever comes first.
>
> (2) The stimulus on each trial will last for
> either some specified time (2 min), or for the
> remainder of the block duration, or until the
> subject responds, whichever comes
> first.  Unpacking this, in effect it means that
> all trials except the final one last for the
> usual trial duration or until a response
> (whichever comes first), and the final trial
> lasts for the remainder of the block duration or
> until a response (whichever comes first).
>
> I already know some functions for working
> directly with the clock times of events, so for
> this problem I find it handier to think in terms
> of the clock times for when the blocks and trials
> will end, instead of the remaining block
> duration.  So here is my solution (following good
> programming practices, such as using constants in place of "magic numbers").
>
> I would first define a global variable on the
> User tab of the Script window.  This will hold
> the clock time of when the block must end.  (I
> like to use a "g_" prefix to remind me that it's
> a global and not a local variable):
>
>      Dim  g_BlockTargetOffsetTime as Long
>
> Then I would set up a structure with some InLines something like the following:
>
> BlockInitCode
> TrialList
>      TrialProc
>          TrialInitCode
>          TrialStimSlide
>
> TrialStimSlide is the stimulus, with Duration set to [TrialDur].
>
> BlockInitCode is an InLine object that simply
> stores the target offset time of the block for
> use later (it assumes that the first event in
> TrialProc is our stimulus, and uses the much
> overlooked GetNextTargetOnsetTime method, see
> that topic in the E-Basic Help facility):
>
>      Const  BlockDur as Long = 10 * 60 * 1000
>      g_BlockTargetOffsetTime = GetNextTargetOnsetTime + BlockDur
>
> And TrialInitCode is another InLine object that
> sets the TrialDur attribute according to specifications (1) and (2) above:
>
>      Const  TrialDur as Long = 2 * 60 * 1000
>      If ((GetNextTargetOnsetTime + TrialDur) <=
> g_BlockTargetOffsetTime) Then  ' all but the final trial
>          c.SetAttrib "TrialDur", TrialDur
>      Else  ' final trial
>          c.SetAttrib "TrialDur", _
>              (g_BlockTargetOffsetTime - GetNextTargetOnsetTime)
>      End If
>
> And if you don't mind using one of the less
> common coding conveniences of E-Basic/VBA, then you could shorten that to
>
>      Const  TrialDur as Long = 2 * 60 * 1000
>      c.SetAttrib "TrialDur", _
>          Iif( ((GetNextTargetOnsetTime +
> TrialDur) <= g_BlockTargetOffsetTime ), _
>          TrialDur, (g_BlockTargetOffsetTime - GetNextTargetOnsetTime) )
>
> Pros to this solution:
> - It does not use any array, nor require the
> attending complications of computing array indexes.
>
> - It does not require any "If
> c.GetAttrib("Trial") > 1" test on each trial --
> seems wasteful to run such a test on each trial
> when we know ahead of time that it will succeed
> on all trials except the first.  Usually we can find a better way.
>
> - It works directly in terms of the target offset
> time for the block, which gets computed only
> once.  It is thus more accurate with time
> (without care, accumulated computations of block
> time remaining might not take into account delays
> in actual stimulus duration, etc.).
>
> Criticisms of this solution:
> - Some users would find it more natural to work
> in terms of the remaining block duration instead
> of the target block offset time (but, without
> much trouble, this solution could be adapted to
> compute and use remaining block duration instead).
>
> - It uses the GetNextTargetOnsetTime method -- a
> very powerful concept in E-Prime, but kept well
> hidden in the documentation (I stumbled upon it
> myself only while searching the Forum for other things).
>
> - Instead of having all the code compactly
> gathered into one InLine (plus a bit of global
> User code), it is spread across two InLines (plus
> a bit of global User code).  This may make it
> slightly harder for some to follow (I think
> Michiel Spapé has made well-put comments on this
> sort of tradeoff either on the Group or in his E-Primer).
>
> - You already have a perfectly good working
> solution that makes sense to you, so I'm a little late to the game, aren't I?
>
> -- David McFarlane, Professional Faultfinder
>
> At 6/30/2011 05:26 PM Thursday, David McFarlane wrote:
>
>
>
>
>
>
>
> >This got addressed on the PST Forum
> >(http://www.pstnet.com/forum/Topic5419-7-1.aspx
> >), but you did well to post here as well --
> >generally I respond only here on the E-Prime
> >Group, and now I can post a few more details and
> >provide code with proper indentation.
>
> >First, as you might find explained in Chapter 4
> >of the User's Guide that came with E-Prime, and
> >have instead discovered the hard way, attributes
> >propogate only downward through logging levels,
> >they do not persist as you pop back up to higher
> >levels, and as a result they do not persist as
> >you pop up a level and then back down to the
> >same level, as happens at the end of a Procedure
> >run by a List.  IOW, despite some appearance,
> >"attributes" are *not* "variables", and they
> >will not fulfill the role of
> >variables.  Variables and attributes each have their own roles.
>
> >So, as explained on the Forum, in short you need
> >to use a global variable.  As explained in
> >Chapter 4 of the User's Guide, you do that in
> >the User tab of the Script view.  Define a variable such as TRemaining, e.g.,
>
> >Dim TRemaining as Long
>
> >Then use that global variable to keep track of
> >the value from trial to trial, as in ...  well,
> >when I tried to write out the code it didn't
> >seem quite right, and I have to run off and
> >catch a bus now.  Maybe you or someone else can
> >now sort this out based on the clues given so far.
>
> >-- David McFarlane, Professional Faultfinder
>
> >At 6/30/2011 02:18 PM Thursday, you wrote:
> >>I am programming an experiment where the total time a person can take
> >>is 10 minutes (600000 ms) (to do 12 trials), with a maximum of 2
> >>minutes per trial (the trial terminates and starts the next trial
> >>after 2 minutes). I have set the program to terminate the list if the
> >>total time is over 10 minutes, however there is a problem--say a
> >>person has taken 9:45 do to 7 trials, so they have 15 seconds left.
> >>BUT...on trial 8, the duration is still set to max 2 min--so a person
> >>can theoretically have a total of 11:45, not 10:00 before it
> >>terminates. So I need to have the program know that if more than 8
> >>minutes (480000) has been used, the duration of the trial should be
> >>600000-however much time has been used so far.
>
> >>I have tried to fix this by putting an attribute in the list object
> >>called "trial" which is just the number of the trial, and another
> >>attribute called "trialtime", which will be the duration of the slide
> >>object (where the stimulus/trial is presented). in the slide object
> >>properties, I have set timelimit to be the attribute "trialtime".
> >>Lastly, after each trial, the attribute "timertrial" is calculated,
> >>which essentially calculates the length of time taken for that trial
> >>and adds it to the previous time taken, so that this attribute is
> >>constantly updated to reflect the total time taken. All of this seems
> >>to work fine, and running through the program shows that "timertrial"
> >>is indeed calculating correctly and is recording in the edata file.
> >>the problem occurs, however, when I put all this together, and try to
> >>change the duration of the next trial based on the "timertrial"
> >>attribute. Here is my code:
>
> >>Using the inline statement below, I have set the first trial duration
> >>is 120 seconds, and every other trial after that the duration is
> >>calculated based on total time taken so far
>
> >>If c.GetAttrib ("trial") = 1 then c.SetAttrib "trialtime", 120000
> >>If c.GetAttrib ("trial") > 1 then
> >>If c.getAttrib ("timertrial") >= 480000 then c.setAttrib "trialtime",
> >>600000 - c.getAttrib ("timertrial")
> >>If c.getAttrib ("timertrial") < 480000 then c.SetAttrib "trialtime",
> >>120000
> >>End If
>
> >>The problem is, the program cannot find the attribute "timertrial"--it
> >>calculates fine at the end of each trial, but when I start a new trial
> >>(within the same list), it does not have a value yet for timertrial,
> >>since that is calculated at the END of the trial. How do I get it to
> >>pull the value of "timertrial" from the previous trial and use it as
> >>an attribute in the NEXT trial? I am sure this is simple, but I can't
> >>seem to get anywhere.
>
> >>Also, Note: I have tried using this code instead:
> >>If c.GetAttrib ("Trial") > 1 then
> >>if LetterSetList.GetPrevAttrib ("timertrial") >= 480000 then
> >>c.setAttrib "trialtime", 600000 - LetterSetList.GetPrevAttrib
> >>("timertrial")
> >>if LetterSetList.GetPrevAttrib ("timertrial") < 480000 then
> >>c.setAttrib "trialtime", 120000
> >>End If
>
> >>And I keep getting type mismatch errors, which should be easy to
> >>resolve, but this one keep stumping me.  Again, I'm sure this is
> >>something simple, but for some reason I can't get it.

-- 
You received this message because you are subscribed to the Google Groups "E-Prime" group.
To post to this group, send email to e-prime at googlegroups.com.
To unsubscribe from this group, send email to e-prime+unsubscribe at googlegroups.com.
For more options, visit this group at http://groups.google.com/group/e-prime?hl=en.



More information about the Eprime mailing list