From fd29e810598ddc78377ce1e8366f0b50188f8620 Mon Sep 17 00:00:00 2001
From: tiborauer <tibor.auer@gmail.com>
Date: Tue, 12 Nov 2019 15:32:16 +0000
Subject: [PATCH] FINAL

---
 README.md             |   2 +-
 three-back.psyexp     | 133 ++++++++--------
 three-back.py         | 234 +++++++++++++++-------------
 three-back_lastrun.py | 351 ------------------------------------------
 4 files changed, 194 insertions(+), 526 deletions(-)
 delete mode 100644 three-back_lastrun.py

diff --git a/README.md b/README.md
index 164e44d..3a82cec 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
-# Three-Back
+# n-Back task
 
diff --git a/three-back.psyexp b/three-back.psyexp
index b756bdf..cefca3d 100644
--- a/three-back.psyexp
+++ b/three-back.psyexp
@@ -1,18 +1,18 @@
 <?xml version="1.0" ?>
-<PsychoPy2experiment encoding="utf-8" version="3.2.4">
+<PsychoPy2experiment encoding="utf-8" version="3.2.0">
   <Settings>
     <Param name="Audio latency priority" updates="None" val="use prefs" valType="str"/>
     <Param name="Audio lib" updates="None" val="use prefs" valType="str"/>
     <Param name="Completed URL" updates="None" val="" valType="str"/>
     <Param name="Data filename" updates="None" val="u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])" valType="code"/>
     <Param name="Enable Escape" updates="None" val="True" valType="bool"/>
-    <Param name="Experiment info" updates="None" val="{'backN': '3', 'probability': '0.2', 'participant': '', 'session': '001'}" valType="code"/>
+    <Param name="Experiment info" updates="None" val="{'participant': '', 'session': '001', 'backN': '3', 'probability': '0.2'}" valType="code"/>
     <Param name="Force stereo" updates="None" val="True" valType="bool"/>
     <Param name="Full-screen window" updates="None" val="False" valType="bool"/>
     <Param name="HTML path" updates="None" val="html" valType="str"/>
     <Param name="Incomplete URL" updates="None" val="" valType="str"/>
     <Param name="JS libs" updates="None" val="packaged" valType="str"/>
-    <Param name="Monitor" updates="None" val="Monitor" valType="str"/>
+    <Param name="Monitor" updates="None" val="Alienware Laptop Monitor" valType="str"/>
     <Param name="Save csv file" updates="None" val="False" valType="bool"/>
     <Param name="Save excel file" updates="None" val="False" valType="bool"/>
     <Param name="Save log file" updates="None" val="True" valType="bool"/>
@@ -25,7 +25,7 @@
     <Param name="Use version" updates="None" val="" valType="str"/>
     <Param name="Window size (pixels)" updates="None" val="[1600, 900]" valType="code"/>
     <Param name="blendMode" updates="None" val="avg" valType="str"/>
-    <Param name="color" updates="None" val="$[-1,-1,-1]" valType="str"/>
+    <Param name="color" updates="None" val="$[1,1,1]" valType="str"/>
     <Param name="colorSpace" updates="None" val="rgb" valType="str"/>
     <Param name="expName" updates="None" val="three-back" valType="str"/>
     <Param name="exportHTML" updates="None" val="on Sync" valType="str"/>
@@ -34,44 +34,44 @@
   <Routines>
     <Routine name="Instructions">
       <TextComponent name="instructions">
-        <Param name="color" updates="constant" val="white" valType="str"/>
+        <Param name="color" updates="constant" val="black" valType="str"/>
         <Param name="colorSpace" updates="constant" val="rgb" valType="str"/>
         <Param name="disabled" updates="None" val="False" valType="bool"/>
         <Param name="durationEstim" updates="None" val="" valType="code"/>
         <Param name="flip" updates="constant" val="" valType="str"/>
         <Param name="font" updates="constant" val="Arial" valType="str"/>
         <Param name="languageStyle" updates="None" val="LTR" valType="str"/>
-        <Param name="letterHeight" updates="constant" val="2.4" valType="code"/>
+        <Param name="letterHeight" updates="constant" val="1" valType="code"/>
         <Param name="name" updates="None" val="instructions" valType="code"/>
         <Param name="opacity" updates="constant" val="1" valType="code"/>
         <Param name="ori" updates="constant" val="0" valType="code"/>
         <Param name="pos" updates="constant" val="(0, 0)" valType="code"/>
-        <Param name="saveStartStop" updates="None" val="True" valType="bool"/>
+        <Param name="saveStartStop" updates="None" val="False" valType="bool"/>
         <Param name="startEstim" updates="None" val="" valType="code"/>
         <Param name="startType" updates="None" val="time (s)" valType="str"/>
         <Param name="startVal" updates="None" val="0.0" valType="code"/>
         <Param name="stopType" updates="None" val="condition" valType="str"/>
         <Param name="stopVal" updates="constant" val="False" valType="code"/>
         <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/>
-        <Param name="text" updates="constant" val="Press SPACE to start" valType="str"/>
+        <Param name="text" updates="constant" val="$&quot;The n-back task presents stimuli sequentially and require you to decide if the current stimulus is the same as one presented n-numbers previous (or back).\n&quot;&amp;#10;+ &quot;\n&quot;&amp;#10;+ &quot;For example, the 3-back you will indicate if the current number matches the number presented 3 places previous\n&quot;&amp;#10;+ &quot;(e.g.  A H G A B G B shows that 'A' and 'G' have matches in this sequence).\n&quot;&amp;#10;+ &quot;\n&quot;&amp;#10;+ f&quot;This is an {expInfo['backN']}-back task.\n&quot;&amp;#10;+ f&quot;Press SPACE if the current stimulus is the same a {expInfo['backN']} places previous.\n&quot;&amp;#10;+ &quot;\n&quot;&amp;#10;+ &quot;Press SPACE bar when ready to start.&quot; " valType="str"/>
         <Param name="units" updates="None" val="from exp settings" valType="str"/>
-        <Param name="wrapWidth" updates="constant" val="" valType="code"/>
+        <Param name="wrapWidth" updates="constant" val="30" valType="code"/>
       </TextComponent>
-      <KeyboardComponent name="key_start">
+      <KeyboardComponent name="instructions_key">
         <Param name="allowedKeys" updates="constant" val="'space'" valType="code"/>
         <Param name="correctAns" updates="constant" val="" valType="str"/>
         <Param name="disabled" updates="None" val="False" valType="bool"/>
         <Param name="discard previous" updates="constant" val="False" valType="bool"/>
         <Param name="durationEstim" updates="None" val="" valType="code"/>
         <Param name="forceEndRoutine" updates="constant" val="True" valType="bool"/>
-        <Param name="name" updates="None" val="key_start" valType="code"/>
-        <Param name="saveStartStop" updates="None" val="True" valType="bool"/>
+        <Param name="name" updates="None" val="instructions_key" valType="code"/>
+        <Param name="saveStartStop" updates="None" val="False" valType="bool"/>
         <Param name="startEstim" updates="None" val="" valType="code"/>
         <Param name="startType" updates="None" val="time (s)" valType="str"/>
         <Param name="startVal" updates="None" val="0.0" valType="code"/>
         <Param name="stopType" updates="None" val="duration (s)" valType="str"/>
         <Param name="stopVal" updates="constant" val="" valType="code"/>
-        <Param name="store" updates="constant" val="last key" valType="str"/>
+        <Param name="store" updates="constant" val="nothing" valType="str"/>
         <Param name="storeCorrect" updates="constant" val="False" valType="bool"/>
         <Param name="syncScreenRefresh" updates="constant" val="False" valType="bool"/>
       </KeyboardComponent>
@@ -84,7 +84,7 @@
         <Param name="saveFrameValue" updates="constant" val="never" valType="str"/>
         <Param name="saveStartExp" updates="constant" val="False" valType="bool"/>
         <Param name="saveStartRoutine" updates="constant" val="False" valType="bool"/>
-        <Param name="saveStartStop" updates="None" val="True" valType="bool"/>
+        <Param name="saveStartStop" updates="None" val="False" valType="bool"/>
         <Param name="startEstim" updates="None" val="" valType="code"/>
         <Param name="startExpValue" updates="constant" val="np.array(['A','B','C','D','E','F','G','H'])" valType="code"/>
         <Param name="startFrameValue" updates="None" val="" valType="code"/>
@@ -96,49 +96,50 @@
         <Param name="syncScreenRefresh" updates="None" val="False" valType="bool"/>
       </VariableComponent>
     </Routine>
-    <Routine name="trial_n">
-      <CodeComponent name="trial_n_code">
-        <Param name="Begin Experiment" updates="constant" val="prevN = np.array([])" valType="extendedCode"/>
-        <Param name="Begin JS Experiment" updates="constant" val="" valType="extendedCode"/>
-        <Param name="Begin JS Routine" updates="constant" val="" valType="extendedCode"/>
-        <Param name="Begin Routine" updates="constant" val="if (currentLoop.thisN &lt; int(expInfo['backN'])) or (np.random.uniform() &gt; float(expInfo['probability'])):&amp;#10;    stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN])&amp;#10;    stimulus = np.random.choice(stimleft)&amp;#10;else:&amp;#10;    stimulus = prevN[-int(expInfo['backN'])]" valType="extendedCode"/>
-        <Param name="Code Type" updates="None" val="Py" valType="str"/>
-        <Param name="Each Frame" updates="constant" val="" valType="extendedCode"/>
-        <Param name="Each JS Frame" updates="constant" val="" valType="extendedCode"/>
-        <Param name="End Experiment" updates="constant" val="" valType="extendedCode"/>
-        <Param name="End JS Experiment" updates="constant" val="" valType="extendedCode"/>
-        <Param name="End JS Routine" updates="constant" val="" valType="extendedCode"/>
-        <Param name="End Routine" updates="constant" val="thisExp.addData('tial_n_letter.stim', stimulus)&amp;#10;prevN = np.hstack((prevN,stimulus))&amp;#10;prevN = prevN[-3:]" valType="extendedCode"/>
-        <Param name="disabled" updates="None" val="False" valType="bool"/>
-        <Param name="name" updates="None" val="trial_n_code" valType="code"/>
-      </CodeComponent>
-      <PolygonComponent name="trial_n_screen">
+    <Routine name="trial_back">
+      <TextComponent name="text">
+        <Param name="color" updates="constant" val="white" valType="str"/>
+        <Param name="colorSpace" updates="constant" val="rgb" valType="str"/>
         <Param name="disabled" updates="None" val="False" valType="bool"/>
         <Param name="durationEstim" updates="None" val="" valType="code"/>
-        <Param name="fillColor" updates="constant" val="$[-1,-1,-1]" valType="str"/>
-        <Param name="fillColorSpace" updates="constant" val="rgb" valType="str"/>
-        <Param name="interpolate" updates="constant" val="linear" valType="str"/>
-        <Param name="lineColor" updates="constant" val="$[1,1,1]" valType="str"/>
-        <Param name="lineColorSpace" updates="constant" val="rgb" valType="str"/>
-        <Param name="lineWidth" updates="constant" val="1" valType="code"/>
-        <Param name="nVertices" updates="constant" val="4" valType="int"/>
-        <Param name="name" updates="None" val="trial_n_screen" valType="code"/>
+        <Param name="flip" updates="constant" val="" valType="str"/>
+        <Param name="font" updates="constant" val="Arial" valType="str"/>
+        <Param name="languageStyle" updates="None" val="LTR" valType="str"/>
+        <Param name="letterHeight" updates="constant" val="2.5" valType="code"/>
+        <Param name="name" updates="None" val="text" valType="code"/>
         <Param name="opacity" updates="constant" val="1" valType="code"/>
         <Param name="ori" updates="constant" val="0" valType="code"/>
         <Param name="pos" updates="constant" val="(0, 0)" valType="code"/>
         <Param name="saveStartStop" updates="None" val="True" valType="bool"/>
-        <Param name="shape" updates="constant" val="rectangle" valType="str"/>
-        <Param name="size" updates="constant" val="(2, 2)" valType="code"/>
         <Param name="startEstim" updates="None" val="" valType="code"/>
         <Param name="startType" updates="None" val="time (s)" valType="str"/>
         <Param name="startVal" updates="None" val="0.0" valType="code"/>
         <Param name="stopType" updates="None" val="duration (s)" valType="str"/>
-        <Param name="stopVal" updates="constant" val="2" valType="code"/>
+        <Param name="stopVal" updates="constant" val="1.0" valType="code"/>
         <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/>
-        <Param name="units" updates="None" val="norm" valType="str"/>
-      </PolygonComponent>
-      <TextComponent name="tial_n_letter">
-        <Param name="color" updates="constant" val="white" valType="str"/>
+        <Param name="text" updates="set every repeat" val="$[t['stimulus'] for t in loop_n.trialList]" valType="str"/>
+        <Param name="units" updates="None" val="from exp settings" valType="str"/>
+        <Param name="wrapWidth" updates="constant" val="" valType="code"/>
+      </TextComponent>
+    </Routine>
+    <Routine name="trial">
+      <CodeComponent name="trial_code">
+        <Param name="Begin Experiment" updates="constant" val="prevN = np.array([])" valType="extendedCode"/>
+        <Param name="Begin JS Experiment" updates="constant" val="" valType="extendedCode"/>
+        <Param name="Begin JS Routine" updates="constant" val="" valType="extendedCode"/>
+        <Param name="Begin Routine" updates="constant" val="if (currentLoop.thisN &lt; int(expInfo['backN'])) or (np.random.uniform() &gt; float(expInfo['probability'])):&amp;#10;    stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN])&amp;#10;    stimulus = np.random.choice(stimleft)&amp;#10;    correctResponse = None&amp;#10;else:&amp;#10;    stimulus = prevN[-int(expInfo['backN'])]&amp;#10;    correctResponse = 'space'" valType="extendedCode"/>
+        <Param name="Code Type" updates="None" val="Py" valType="str"/>
+        <Param name="Each Frame" updates="constant" val="" valType="extendedCode"/>
+        <Param name="Each JS Frame" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End Experiment" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End JS Experiment" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End JS Routine" updates="constant" val="" valType="extendedCode"/>
+        <Param name="End Routine" updates="constant" val="thisExp.addData('tial_stimulus.stim', stimulus)&amp;#10;prevN = np.hstack((prevN,stimulus))&amp;#10;prevN = prevN[-3:]" valType="extendedCode"/>
+        <Param name="disabled" updates="None" val="False" valType="bool"/>
+        <Param name="name" updates="None" val="trial_code" valType="code"/>
+      </CodeComponent>
+      <TextComponent name="trial_stimulus">
+        <Param name="color" updates="constant" val="black" valType="str"/>
         <Param name="colorSpace" updates="constant" val="rgb" valType="str"/>
         <Param name="disabled" updates="None" val="False" valType="bool"/>
         <Param name="durationEstim" updates="None" val="" valType="code"/>
@@ -146,7 +147,7 @@
         <Param name="font" updates="constant" val="Arial" valType="str"/>
         <Param name="languageStyle" updates="None" val="LTR" valType="str"/>
         <Param name="letterHeight" updates="constant" val="2.5" valType="code"/>
-        <Param name="name" updates="None" val="tial_n_letter" valType="code"/>
+        <Param name="name" updates="None" val="trial_stimulus" valType="code"/>
         <Param name="opacity" updates="constant" val="1" valType="code"/>
         <Param name="ori" updates="constant" val="0" valType="code"/>
         <Param name="pos" updates="constant" val="(0, 0)" valType="code"/>
@@ -161,37 +162,29 @@
         <Param name="units" updates="None" val="from exp settings" valType="str"/>
         <Param name="wrapWidth" updates="constant" val="" valType="code"/>
       </TextComponent>
-    </Routine>
-    <Routine name="trial_back">
-      <TextComponent name="text">
-        <Param name="color" updates="constant" val="white" valType="str"/>
-        <Param name="colorSpace" updates="constant" val="rgb" valType="str"/>
+      <KeyboardComponent name="trial_resp">
+        <Param name="allowedKeys" updates="constant" val="'space'" valType="code"/>
+        <Param name="correctAns" updates="constant" val="$correctResponse" valType="str"/>
         <Param name="disabled" updates="None" val="False" valType="bool"/>
+        <Param name="discard previous" updates="constant" val="True" valType="bool"/>
         <Param name="durationEstim" updates="None" val="" valType="code"/>
-        <Param name="flip" updates="constant" val="" valType="str"/>
-        <Param name="font" updates="constant" val="Arial" valType="str"/>
-        <Param name="languageStyle" updates="None" val="LTR" valType="str"/>
-        <Param name="letterHeight" updates="constant" val="2.5" valType="code"/>
-        <Param name="name" updates="None" val="text" valType="code"/>
-        <Param name="opacity" updates="constant" val="1" valType="code"/>
-        <Param name="ori" updates="constant" val="0" valType="code"/>
-        <Param name="pos" updates="constant" val="(0, 0)" valType="code"/>
+        <Param name="forceEndRoutine" updates="constant" val="False" valType="bool"/>
+        <Param name="name" updates="None" val="trial_resp" valType="code"/>
         <Param name="saveStartStop" updates="None" val="True" valType="bool"/>
         <Param name="startEstim" updates="None" val="" valType="code"/>
         <Param name="startType" updates="None" val="time (s)" valType="str"/>
         <Param name="startVal" updates="None" val="0.0" valType="code"/>
         <Param name="stopType" updates="None" val="duration (s)" valType="str"/>
-        <Param name="stopVal" updates="constant" val="1.0" valType="code"/>
-        <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/>
-        <Param name="text" updates="set every repeat" val="$[t['stimulus'] for t in loop_n.trialList]" valType="str"/>
-        <Param name="units" updates="None" val="from exp settings" valType="str"/>
-        <Param name="wrapWidth" updates="constant" val="" valType="code"/>
-      </TextComponent>
+        <Param name="stopVal" updates="constant" val="2" valType="code"/>
+        <Param name="store" updates="constant" val="first key" valType="str"/>
+        <Param name="storeCorrect" updates="constant" val="True" valType="bool"/>
+        <Param name="syncScreenRefresh" updates="constant" val="True" valType="bool"/>
+      </KeyboardComponent>
     </Routine>
   </Routines>
   <Flow>
     <Routine name="Instructions"/>
-    <LoopInitiator loopType="TrialHandler" name="loop_n">
+    <LoopInitiator loopType="TrialHandler" name="loop">
       <Param name="Selected rows" updates="None" val="" valType="str"/>
       <Param name="conditions" updates="None" val="None" valType="str"/>
       <Param name="conditionsFile" updates="None" val="" valType="str"/>
@@ -199,10 +192,10 @@
       <Param name="isTrials" updates="None" val="True" valType="bool"/>
       <Param name="loopType" updates="None" val="sequential" valType="str"/>
       <Param name="nReps" updates="None" val="20" valType="code"/>
-      <Param name="name" updates="None" val="loop_n" valType="code"/>
+      <Param name="name" updates="None" val="loop" valType="code"/>
       <Param name="random seed" updates="None" val="" valType="code"/>
     </LoopInitiator>
-    <Routine name="trial_n"/>
-    <LoopTerminator name="loop_n"/>
+    <Routine name="trial"/>
+    <LoopTerminator name="loop"/>
   </Flow>
 </PsychoPy2experiment>
diff --git a/three-back.py b/three-back.py
index 91b4b78..ee5549b 100644
--- a/three-back.py
+++ b/three-back.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 """
-This experiment was created using PsychoPy3 Experiment Builder (v3.2.4),
-    on november 12, 2019, at 02:43
+This experiment was created using PsychoPy3 Experiment Builder (v3.2.0),
+    on November 12, 2019, at 15:31
 If you publish work using this script the most relevant publication is:
 
     Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) 
@@ -33,9 +33,9 @@ _thisDir = os.path.dirname(os.path.abspath(__file__))
 os.chdir(_thisDir)
 
 # Store info about the experiment session
-psychopyVersion = '3.2.4'
+psychopyVersion = '3.2.0'
 expName = 'three-back'  # from the Builder filename that created this script
-expInfo = {'backN': '3', 'probability': '0.2', 'participant': '', 'session': '001'}
+expInfo = {'participant': '', 'session': '001', 'backN': '3', 'probability': '0.2'}
 dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
 if dlg.OK == False:
     core.quit()  # user pressed cancel
@@ -65,7 +65,7 @@ frameTolerance = 0.001  # how close to onset before 'same' frame
 win = visual.Window(
     size=[1600, 900], fullscr=False, screen=0, 
     winType='pyglet', allowGUI=True, allowStencil=False,
-    monitor='Monitor', color=[-1,-1,-1], colorSpace='rgb',
+    monitor='Alienware Laptop Monitor', color=[1,1,1], colorSpace='rgb',
     blendMode='avg', useFBO=True, 
     units='deg')
 # store frame rate of monitor if we can measure it
@@ -81,34 +81,36 @@ defaultKeyboard = keyboard.Keyboard()
 # Initialize components for Routine "Instructions"
 InstructionsClock = core.Clock()
 instructions = visual.TextStim(win=win, name='instructions',
-    text='Press SPACE to start',
+    text="The n-back task presents stimuli sequentially and require you to decide if the current stimulus is the same as one presented n-numbers previous (or back).\n"
++ "\n"
++ "For example, the 3-back you will indicate if the current number matches the number presented 3 places previous\n"
++ "(e.g.  A H G A B G B shows that 'A' and 'G' have matches in this sequence).\n"
++ "\n"
++ f"This is an {expInfo['backN']}-back task.\n"
++ f"Press SPACE if the current stimulus is the same a {expInfo['backN']} places previous.\n"
++ "\n"
++ "Press SPACE bar when ready to start." ,
     font='Arial',
-    pos=(0, 0), height=2.4, wrapWidth=None, ori=0, 
-    color='white', colorSpace='rgb', opacity=1, 
+    pos=(0, 0), height=1, wrapWidth=30, ori=0, 
+    color='black', colorSpace='rgb', opacity=1, 
     languageStyle='LTR',
     depth=0.0);
-key_start = keyboard.Keyboard()
+instructions_key = keyboard.Keyboard()
 # Set experiment start values for variable component stimuli
 stimuli = np.array(['A','B','C','D','E','F','G','H'])
 stimuliContainer = []
 
-# Initialize components for Routine "trial_n"
-trial_nClock = core.Clock()
+# Initialize components for Routine "trial"
+trialClock = core.Clock()
 prevN = np.array([])
-trial_n_screen = visual.Rect(
-    win=win, name='trial_n_screen',units='norm', 
-    width=(2, 2)[0], height=(2, 2)[1],
-    ori=0, pos=(0, 0),
-    lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
-    fillColor=[-1,-1,-1], fillColorSpace='rgb',
-    opacity=1, depth=-1.0, interpolate=True)
-tial_n_letter = visual.TextStim(win=win, name='tial_n_letter',
+trial_stimulus = visual.TextStim(win=win, name='trial_stimulus',
     text='default text',
     font='Arial',
     pos=(0, 0), height=2.5, wrapWidth=None, ori=0, 
-    color='white', colorSpace='rgb', opacity=1, 
+    color='black', colorSpace='rgb', opacity=1, 
     languageStyle='LTR',
-    depth=-2.0);
+    depth=-1.0);
+trial_resp = keyboard.Keyboard()
 
 # Create some handy timers
 globalClock = core.Clock()  # to track the time since experiment started
@@ -116,10 +118,10 @@ routineTimer = core.CountdownTimer()  # to track time remaining of each (non-sli
 
 # ------Prepare to start Routine "Instructions"-------
 # update component parameters for each repeat
-key_start.keys = []
-key_start.rt = []
+instructions_key.keys = []
+instructions_key.rt = []
 # keep track of which components have finished
-InstructionsComponents = [instructions, key_start]
+InstructionsComponents = [instructions, instructions_key]
 for thisComponent in InstructionsComponents:
     thisComponent.tStart = None
     thisComponent.tStop = None
@@ -159,26 +161,23 @@ while continueRoutine:
             win.timeOnFlip(instructions, 'tStopRefresh')  # time at next scr refresh
             instructions.setAutoDraw(False)
     
-    # *key_start* updates
-    if key_start.status == NOT_STARTED and t >= 0.0-frameTolerance:
+    # *instructions_key* updates
+    if instructions_key.status == NOT_STARTED and t >= 0.0-frameTolerance:
         # keep track of start time/frame for later
-        key_start.frameNStart = frameN  # exact frame index
-        key_start.tStart = t  # local t and not account for scr refresh
-        key_start.tStartRefresh = tThisFlipGlobal  # on global time
-        win.timeOnFlip(key_start, 'tStartRefresh')  # time at next scr refresh
-        key_start.status = STARTED
+        instructions_key.frameNStart = frameN  # exact frame index
+        instructions_key.tStart = t  # local t and not account for scr refresh
+        instructions_key.tStartRefresh = tThisFlipGlobal  # on global time
+        win.timeOnFlip(instructions_key, 'tStartRefresh')  # time at next scr refresh
+        instructions_key.status = STARTED
         # keyboard checking is just starting
-        key_start.clock.reset()  # now t=0
-    if key_start.status == STARTED:
-        theseKeys = key_start.getKeys(keyList=['space'], waitRelease=False)
+    if instructions_key.status == STARTED:
+        theseKeys = instructions_key.getKeys(keyList=['space'], waitRelease=False)
         if len(theseKeys):
             theseKeys = theseKeys[0]  # at least one key was pressed
             
             # check for quit:
             if "escape" == theseKeys:
                 endExpNow = True
-            key_start.keys = theseKeys.name  # just the last key pressed
-            key_start.rt = theseKeys.rt
             # a response ends the routine
             continueRoutine = False
     
@@ -203,51 +202,44 @@ while continueRoutine:
 for thisComponent in InstructionsComponents:
     if hasattr(thisComponent, "setAutoDraw"):
         thisComponent.setAutoDraw(False)
-thisExp.addData('instructions.started', instructions.tStartRefresh)
-thisExp.addData('instructions.stopped', instructions.tStopRefresh)
-# check responses
-if key_start.keys in ['', [], None]:  # No response was made
-    key_start.keys = None
-thisExp.addData('key_start.keys',key_start.keys)
-if key_start.keys != None:  # we had a response
-    thisExp.addData('key_start.rt', key_start.rt)
-thisExp.addData('key_start.started', key_start.tStart)
-thisExp.addData('key_start.stopped', key_start.tStop)
-thisExp.nextEntry()
 # the Routine "Instructions" was not non-slip safe, so reset the non-slip timer
 routineTimer.reset()
 
 # set up handler to look after randomisation of conditions etc
-loop_n = data.TrialHandler(nReps=20, method='sequential', 
+loop = data.TrialHandler(nReps=20, method='sequential', 
     extraInfo=expInfo, originPath=-1,
     trialList=[None],
-    seed=None, name='loop_n')
-thisExp.addLoop(loop_n)  # add the loop to the experiment
-thisLoop_n = loop_n.trialList[0]  # so we can initialise stimuli with some values
-# abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb)
-if thisLoop_n != None:
-    for paramName in thisLoop_n:
-        exec('{} = thisLoop_n[paramName]'.format(paramName))
+    seed=None, name='loop')
+thisExp.addLoop(loop)  # add the loop to the experiment
+thisLoop = loop.trialList[0]  # so we can initialise stimuli with some values
+# abbreviate parameter names if possible (e.g. rgb = thisLoop.rgb)
+if thisLoop != None:
+    for paramName in thisLoop:
+        exec('{} = thisLoop[paramName]'.format(paramName))
 
-for thisLoop_n in loop_n:
-    currentLoop = loop_n
-    # abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb)
-    if thisLoop_n != None:
-        for paramName in thisLoop_n:
-            exec('{} = thisLoop_n[paramName]'.format(paramName))
+for thisLoop in loop:
+    currentLoop = loop
+    # abbreviate parameter names if possible (e.g. rgb = thisLoop.rgb)
+    if thisLoop != None:
+        for paramName in thisLoop:
+            exec('{} = thisLoop[paramName]'.format(paramName))
     
-    # ------Prepare to start Routine "trial_n"-------
+    # ------Prepare to start Routine "trial"-------
     routineTimer.add(2.000000)
     # update component parameters for each repeat
     if (currentLoop.thisN < int(expInfo['backN'])) or (np.random.uniform() > float(expInfo['probability'])):
         stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN])
         stimulus = np.random.choice(stimleft)
+        correctResponse = None
     else:
         stimulus = prevN[-int(expInfo['backN'])]
-    tial_n_letter.setText(stimulus)
+        correctResponse = 'space'
+    trial_stimulus.setText(stimulus)
+    trial_resp.keys = []
+    trial_resp.rt = []
     # keep track of which components have finished
-    trial_nComponents = [trial_n_screen, tial_n_letter]
-    for thisComponent in trial_nComponents:
+    trialComponents = [trial_stimulus, trial_resp]
+    for thisComponent in trialComponents:
         thisComponent.tStart = None
         thisComponent.tStop = None
         thisComponent.tStartRefresh = None
@@ -257,52 +249,73 @@ for thisLoop_n in loop_n:
     # reset timers
     t = 0
     _timeToFirstFrame = win.getFutureFlipTime(clock="now")
-    trial_nClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
+    trialClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
     frameN = -1
     continueRoutine = True
     
-    # -------Run Routine "trial_n"-------
+    # -------Run Routine "trial"-------
     while continueRoutine and routineTimer.getTime() > 0:
         # get current time
-        t = trial_nClock.getTime()
-        tThisFlip = win.getFutureFlipTime(clock=trial_nClock)
+        t = trialClock.getTime()
+        tThisFlip = win.getFutureFlipTime(clock=trialClock)
         tThisFlipGlobal = win.getFutureFlipTime(clock=None)
         frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
         # update/draw components on each frame
         
-        # *trial_n_screen* updates
-        if trial_n_screen.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
+        # *trial_stimulus* updates
+        if trial_stimulus.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
             # keep track of start time/frame for later
-            trial_n_screen.frameNStart = frameN  # exact frame index
-            trial_n_screen.tStart = t  # local t and not account for scr refresh
-            trial_n_screen.tStartRefresh = tThisFlipGlobal  # on global time
-            win.timeOnFlip(trial_n_screen, 'tStartRefresh')  # time at next scr refresh
-            trial_n_screen.setAutoDraw(True)
-        if trial_n_screen.status == STARTED:
+            trial_stimulus.frameNStart = frameN  # exact frame index
+            trial_stimulus.tStart = t  # local t and not account for scr refresh
+            trial_stimulus.tStartRefresh = tThisFlipGlobal  # on global time
+            win.timeOnFlip(trial_stimulus, 'tStartRefresh')  # time at next scr refresh
+            trial_stimulus.setAutoDraw(True)
+        if trial_stimulus.status == STARTED:
             # is it time to stop? (based on global clock, using actual start)
-            if tThisFlipGlobal > trial_n_screen.tStartRefresh + 2-frameTolerance:
+            if tThisFlipGlobal > trial_stimulus.tStartRefresh + 0.03-frameTolerance:
                 # keep track of stop time/frame for later
-                trial_n_screen.tStop = t  # not accounting for scr refresh
-                trial_n_screen.frameNStop = frameN  # exact frame index
-                win.timeOnFlip(trial_n_screen, 'tStopRefresh')  # time at next scr refresh
-                trial_n_screen.setAutoDraw(False)
+                trial_stimulus.tStop = t  # not accounting for scr refresh
+                trial_stimulus.frameNStop = frameN  # exact frame index
+                win.timeOnFlip(trial_stimulus, 'tStopRefresh')  # time at next scr refresh
+                trial_stimulus.setAutoDraw(False)
         
-        # *tial_n_letter* updates
-        if tial_n_letter.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
+        # *trial_resp* updates
+        waitOnFlip = False
+        if trial_resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
             # keep track of start time/frame for later
-            tial_n_letter.frameNStart = frameN  # exact frame index
-            tial_n_letter.tStart = t  # local t and not account for scr refresh
-            tial_n_letter.tStartRefresh = tThisFlipGlobal  # on global time
-            win.timeOnFlip(tial_n_letter, 'tStartRefresh')  # time at next scr refresh
-            tial_n_letter.setAutoDraw(True)
-        if tial_n_letter.status == STARTED:
+            trial_resp.frameNStart = frameN  # exact frame index
+            trial_resp.tStart = t  # local t and not account for scr refresh
+            trial_resp.tStartRefresh = tThisFlipGlobal  # on global time
+            win.timeOnFlip(trial_resp, 'tStartRefresh')  # time at next scr refresh
+            trial_resp.status = STARTED
+            # keyboard checking is just starting
+            waitOnFlip = True
+            win.callOnFlip(trial_resp.clock.reset)  # t=0 on next screen flip
+            win.callOnFlip(trial_resp.clearEvents, eventType='keyboard')  # clear events on next screen flip
+        if trial_resp.status == STARTED:
             # is it time to stop? (based on global clock, using actual start)
-            if tThisFlipGlobal > tial_n_letter.tStartRefresh + 0.03-frameTolerance:
+            if tThisFlipGlobal > trial_resp.tStartRefresh + 2-frameTolerance:
                 # keep track of stop time/frame for later
-                tial_n_letter.tStop = t  # not accounting for scr refresh
-                tial_n_letter.frameNStop = frameN  # exact frame index
-                win.timeOnFlip(tial_n_letter, 'tStopRefresh')  # time at next scr refresh
-                tial_n_letter.setAutoDraw(False)
+                trial_resp.tStop = t  # not accounting for scr refresh
+                trial_resp.frameNStop = frameN  # exact frame index
+                win.timeOnFlip(trial_resp, 'tStopRefresh')  # time at next scr refresh
+                trial_resp.status = FINISHED
+        if trial_resp.status == STARTED and not waitOnFlip:
+            theseKeys = trial_resp.getKeys(keyList=['space'], waitRelease=False)
+            if len(theseKeys):
+                theseKeys = theseKeys[0]  # at least one key was pressed
+                
+                # check for quit:
+                if "escape" == theseKeys:
+                    endExpNow = True
+                if trial_resp.keys == []:  # then this was the first keypress
+                    trial_resp.keys = theseKeys.name  # just the first key pressed
+                    trial_resp.rt = theseKeys.rt
+                    # was this 'correct'?
+                    if (trial_resp.keys == str(correctResponse)) or (trial_resp.keys == correctResponse):
+                        trial_resp.corr = 1
+                    else:
+                        trial_resp.corr = 0
         
         # check for quit (typically the Esc key)
         if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
@@ -312,7 +325,7 @@ for thisLoop_n in loop_n:
         if not continueRoutine:  # a component has requested a forced-end of Routine
             break
         continueRoutine = False  # will revert to True if at least one component still running
-        for thisComponent in trial_nComponents:
+        for thisComponent in trialComponents:
             if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                 continueRoutine = True
                 break  # at least one component has not yet finished
@@ -321,20 +334,33 @@ for thisLoop_n in loop_n:
         if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
             win.flip()
     
-    # -------Ending Routine "trial_n"-------
-    for thisComponent in trial_nComponents:
+    # -------Ending Routine "trial"-------
+    for thisComponent in trialComponents:
         if hasattr(thisComponent, "setAutoDraw"):
             thisComponent.setAutoDraw(False)
-    thisExp.addData('tial_n_letter.stim', stimulus)
+    thisExp.addData('tial_stimulus.stim', stimulus)
     prevN = np.hstack((prevN,stimulus))
     prevN = prevN[-3:]
-    loop_n.addData('trial_n_screen.started', trial_n_screen.tStartRefresh)
-    loop_n.addData('trial_n_screen.stopped', trial_n_screen.tStopRefresh)
-    loop_n.addData('tial_n_letter.started', tial_n_letter.tStartRefresh)
-    loop_n.addData('tial_n_letter.stopped', tial_n_letter.tStopRefresh)
+    loop.addData('trial_stimulus.started', trial_stimulus.tStartRefresh)
+    loop.addData('trial_stimulus.stopped', trial_stimulus.tStopRefresh)
+    # check responses
+    if trial_resp.keys in ['', [], None]:  # No response was made
+        trial_resp.keys = None
+        # was no response the correct answer?!
+        if str(correctResponse).lower() == 'none':
+           trial_resp.corr = 1;  # correct non-response
+        else:
+           trial_resp.corr = 0;  # failed to respond (incorrectly)
+    # store data for loop (TrialHandler)
+    loop.addData('trial_resp.keys',trial_resp.keys)
+    loop.addData('trial_resp.corr', trial_resp.corr)
+    if trial_resp.keys != None:  # we had a response
+        loop.addData('trial_resp.rt', trial_resp.rt)
+    loop.addData('trial_resp.started', trial_resp.tStartRefresh)
+    loop.addData('trial_resp.stopped', trial_resp.tStopRefresh)
     thisExp.nextEntry()
     
-# completed 20 repeats of 'loop_n'
+# completed 20 repeats of 'loop'
 
 
 # Flip one final time so any remaining win.callOnFlip() 
diff --git a/three-back_lastrun.py b/three-back_lastrun.py
deleted file mode 100644
index 4a69b10..0000000
--- a/three-back_lastrun.py
+++ /dev/null
@@ -1,351 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-This experiment was created using PsychoPy3 Experiment Builder (v3.2.4),
-    on november 12, 2019, at 02:41
-If you publish work using this script the most relevant publication is:
-
-    Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) 
-        PsychoPy2: Experiments in behavior made easy Behav Res 51: 195. 
-        https://doi.org/10.3758/s13428-018-01193-y
-
-"""
-
-from __future__ import absolute_import, division
-
-from psychopy import locale_setup
-from psychopy import prefs
-from psychopy import sound, gui, visual, core, data, event, logging, clock
-from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
-                                STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
-
-import numpy as np  # whole numpy lib is available, prepend 'np.'
-from numpy import (sin, cos, tan, log, log10, pi, average,
-                   sqrt, std, deg2rad, rad2deg, linspace, asarray)
-from numpy.random import random, randint, normal, shuffle
-import os  # handy system and path functions
-import sys  # to get file system encoding
-
-from psychopy.hardware import keyboard
-
-# Ensure that relative paths start from the same directory as this script
-_thisDir = os.path.dirname(os.path.abspath(__file__))
-os.chdir(_thisDir)
-
-# Store info about the experiment session
-psychopyVersion = '3.2.4'
-expName = 'three-back'  # from the Builder filename that created this script
-expInfo = {'backN': '3', 'probability': '0.2', 'participant': '', 'session': '001'}
-dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
-if dlg.OK == False:
-    core.quit()  # user pressed cancel
-expInfo['date'] = data.getDateStr()  # add a simple timestamp
-expInfo['expName'] = expName
-expInfo['psychopyVersion'] = psychopyVersion
-
-# Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
-filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
-
-# An ExperimentHandler isn't essential but helps with data saving
-thisExp = data.ExperimentHandler(name=expName, version='',
-    extraInfo=expInfo, runtimeInfo=None,
-    originPath='D:\\Projects\\three-back\\three-back_lastrun.py',
-    savePickle=True, saveWideText=True,
-    dataFileName=filename)
-# save a log file for detail verbose info
-logFile = logging.LogFile(filename+'.log', level=logging.EXP)
-logging.console.setLevel(logging.WARNING)  # this outputs to the screen, not a file
-
-endExpNow = False  # flag for 'escape' or other condition => quit the exp
-frameTolerance = 0.001  # how close to onset before 'same' frame
-
-# Start Code - component code to be run before the window creation
-
-# Setup the Window
-win = visual.Window(
-    size=[1600, 900], fullscr=False, screen=0, 
-    winType='pyglet', allowGUI=True, allowStencil=False,
-    monitor='Monitor', color=[-1,-1,-1], colorSpace='rgb',
-    blendMode='avg', useFBO=True, 
-    units='deg')
-# store frame rate of monitor if we can measure it
-expInfo['frameRate'] = win.getActualFrameRate()
-if expInfo['frameRate'] != None:
-    frameDur = 1.0 / round(expInfo['frameRate'])
-else:
-    frameDur = 1.0 / 60.0  # could not measure, so guess
-
-# create a default keyboard (e.g. to check for escape)
-defaultKeyboard = keyboard.Keyboard()
-
-# Initialize components for Routine "Instructions"
-InstructionsClock = core.Clock()
-instructions = visual.TextStim(win=win, name='instructions',
-    text='Press SPACE to start',
-    font='Arial',
-    pos=(0, 0), height=2.4, wrapWidth=None, ori=0, 
-    color='white', colorSpace='rgb', opacity=1, 
-    languageStyle='LTR',
-    depth=0.0);
-key_start = keyboard.Keyboard()
-# Set experiment start values for variable component stimuli
-stimuli = np.array(['A','B','C','D','E','F','G','H'])
-stimuliContainer = []
-
-# Initialize components for Routine "trial_n"
-trial_nClock = core.Clock()
-prevN = np.array([])
-trial_n_screen = visual.Rect(
-    win=win, name='trial_n_screen',units='norm', 
-    width=(2, 2)[0], height=(2, 2)[1],
-    ori=0, pos=(0, 0),
-    lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
-    fillColor=[-1,-1,-1], fillColorSpace='rgb',
-    opacity=1, depth=-1.0, interpolate=True)
-tial_n_letter = visual.TextStim(win=win, name='tial_n_letter',
-    text='default text',
-    font='Arial',
-    pos=(0, 0), height=2.5, wrapWidth=None, ori=0, 
-    color='white', colorSpace='rgb', opacity=1, 
-    languageStyle='LTR',
-    depth=-2.0);
-
-# Create some handy timers
-globalClock = core.Clock()  # to track the time since experiment started
-routineTimer = core.CountdownTimer()  # to track time remaining of each (non-slip) routine 
-
-# ------Prepare to start Routine "Instructions"-------
-# update component parameters for each repeat
-key_start.keys = []
-key_start.rt = []
-# keep track of which components have finished
-InstructionsComponents = [instructions, key_start]
-for thisComponent in InstructionsComponents:
-    thisComponent.tStart = None
-    thisComponent.tStop = None
-    thisComponent.tStartRefresh = None
-    thisComponent.tStopRefresh = None
-    if hasattr(thisComponent, 'status'):
-        thisComponent.status = NOT_STARTED
-# reset timers
-t = 0
-_timeToFirstFrame = win.getFutureFlipTime(clock="now")
-InstructionsClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
-frameN = -1
-continueRoutine = True
-
-# -------Run Routine "Instructions"-------
-while continueRoutine:
-    # get current time
-    t = InstructionsClock.getTime()
-    tThisFlip = win.getFutureFlipTime(clock=InstructionsClock)
-    tThisFlipGlobal = win.getFutureFlipTime(clock=None)
-    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
-    # update/draw components on each frame
-    
-    # *instructions* updates
-    if instructions.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
-        # keep track of start time/frame for later
-        instructions.frameNStart = frameN  # exact frame index
-        instructions.tStart = t  # local t and not account for scr refresh
-        instructions.tStartRefresh = tThisFlipGlobal  # on global time
-        win.timeOnFlip(instructions, 'tStartRefresh')  # time at next scr refresh
-        instructions.setAutoDraw(True)
-    if instructions.status == STARTED:
-        if bool(False):
-            # keep track of stop time/frame for later
-            instructions.tStop = t  # not accounting for scr refresh
-            instructions.frameNStop = frameN  # exact frame index
-            win.timeOnFlip(instructions, 'tStopRefresh')  # time at next scr refresh
-            instructions.setAutoDraw(False)
-    
-    # *key_start* updates
-    if key_start.status == NOT_STARTED and t >= 0.0-frameTolerance:
-        # keep track of start time/frame for later
-        key_start.frameNStart = frameN  # exact frame index
-        key_start.tStart = t  # local t and not account for scr refresh
-        key_start.tStartRefresh = tThisFlipGlobal  # on global time
-        win.timeOnFlip(key_start, 'tStartRefresh')  # time at next scr refresh
-        key_start.status = STARTED
-        # keyboard checking is just starting
-        key_start.clock.reset()  # now t=0
-    if key_start.status == STARTED:
-        theseKeys = key_start.getKeys(keyList=['space'], waitRelease=False)
-        if len(theseKeys):
-            theseKeys = theseKeys[0]  # at least one key was pressed
-            
-            # check for quit:
-            if "escape" == theseKeys:
-                endExpNow = True
-            key_start.keys = theseKeys.name  # just the last key pressed
-            key_start.rt = theseKeys.rt
-            # a response ends the routine
-            continueRoutine = False
-    
-    # check for quit (typically the Esc key)
-    if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
-        core.quit()
-    
-    # check if all components have finished
-    if not continueRoutine:  # a component has requested a forced-end of Routine
-        break
-    continueRoutine = False  # will revert to True if at least one component still running
-    for thisComponent in InstructionsComponents:
-        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
-            continueRoutine = True
-            break  # at least one component has not yet finished
-    
-    # refresh the screen
-    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
-        win.flip()
-
-# -------Ending Routine "Instructions"-------
-for thisComponent in InstructionsComponents:
-    if hasattr(thisComponent, "setAutoDraw"):
-        thisComponent.setAutoDraw(False)
-thisExp.addData('instructions.started', instructions.tStartRefresh)
-thisExp.addData('instructions.stopped', instructions.tStopRefresh)
-# check responses
-if key_start.keys in ['', [], None]:  # No response was made
-    key_start.keys = None
-thisExp.addData('key_start.keys',key_start.keys)
-if key_start.keys != None:  # we had a response
-    thisExp.addData('key_start.rt', key_start.rt)
-thisExp.addData('key_start.started', key_start.tStart)
-thisExp.addData('key_start.stopped', key_start.tStop)
-thisExp.nextEntry()
-# the Routine "Instructions" was not non-slip safe, so reset the non-slip timer
-routineTimer.reset()
-
-# set up handler to look after randomisation of conditions etc
-loop_n = data.TrialHandler(nReps=20, method='sequential', 
-    extraInfo=expInfo, originPath=-1,
-    trialList=[None],
-    seed=None, name='loop_n')
-thisExp.addLoop(loop_n)  # add the loop to the experiment
-thisLoop_n = loop_n.trialList[0]  # so we can initialise stimuli with some values
-# abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb)
-if thisLoop_n != None:
-    for paramName in thisLoop_n:
-        exec('{} = thisLoop_n[paramName]'.format(paramName))
-
-for thisLoop_n in loop_n:
-    currentLoop = loop_n
-    # abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb)
-    if thisLoop_n != None:
-        for paramName in thisLoop_n:
-            exec('{} = thisLoop_n[paramName]'.format(paramName))
-    
-    # ------Prepare to start Routine "trial_n"-------
-    routineTimer.add(2.000000)
-    # update component parameters for each repeat
-    if (currentLoop.thisN < int(expInfo['backN'])) or (np.random.uniform() > float(expInfo['probability'])):
-        stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN])
-        stimulus = np.random.choice(stimleft)
-    else:
-        stimulus = prevN[-int(expInfo['backN'])]
-    tial_n_letter.setText(stimulus)
-    # keep track of which components have finished
-    trial_nComponents = [trial_n_screen, tial_n_letter]
-    for thisComponent in trial_nComponents:
-        thisComponent.tStart = None
-        thisComponent.tStop = None
-        thisComponent.tStartRefresh = None
-        thisComponent.tStopRefresh = None
-        if hasattr(thisComponent, 'status'):
-            thisComponent.status = NOT_STARTED
-    # reset timers
-    t = 0
-    _timeToFirstFrame = win.getFutureFlipTime(clock="now")
-    trial_nClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
-    frameN = -1
-    continueRoutine = True
-    
-    # -------Run Routine "trial_n"-------
-    while continueRoutine and routineTimer.getTime() > 0:
-        # get current time
-        t = trial_nClock.getTime()
-        tThisFlip = win.getFutureFlipTime(clock=trial_nClock)
-        tThisFlipGlobal = win.getFutureFlipTime(clock=None)
-        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
-        # update/draw components on each frame
-        
-        # *trial_n_screen* updates
-        if trial_n_screen.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
-            # keep track of start time/frame for later
-            trial_n_screen.frameNStart = frameN  # exact frame index
-            trial_n_screen.tStart = t  # local t and not account for scr refresh
-            trial_n_screen.tStartRefresh = tThisFlipGlobal  # on global time
-            win.timeOnFlip(trial_n_screen, 'tStartRefresh')  # time at next scr refresh
-            trial_n_screen.setAutoDraw(True)
-        if trial_n_screen.status == STARTED:
-            # is it time to stop? (based on global clock, using actual start)
-            if tThisFlipGlobal > trial_n_screen.tStartRefresh + 2-frameTolerance:
-                # keep track of stop time/frame for later
-                trial_n_screen.tStop = t  # not accounting for scr refresh
-                trial_n_screen.frameNStop = frameN  # exact frame index
-                win.timeOnFlip(trial_n_screen, 'tStopRefresh')  # time at next scr refresh
-                trial_n_screen.setAutoDraw(False)
-        
-        # *tial_n_letter* updates
-        if tial_n_letter.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
-            # keep track of start time/frame for later
-            tial_n_letter.frameNStart = frameN  # exact frame index
-            tial_n_letter.tStart = t  # local t and not account for scr refresh
-            tial_n_letter.tStartRefresh = tThisFlipGlobal  # on global time
-            win.timeOnFlip(tial_n_letter, 'tStartRefresh')  # time at next scr refresh
-            tial_n_letter.setAutoDraw(True)
-        if tial_n_letter.status == STARTED:
-            # is it time to stop? (based on global clock, using actual start)
-            if tThisFlipGlobal > tial_n_letter.tStartRefresh + 0.03-frameTolerance:
-                # keep track of stop time/frame for later
-                tial_n_letter.tStop = t  # not accounting for scr refresh
-                tial_n_letter.frameNStop = frameN  # exact frame index
-                win.timeOnFlip(tial_n_letter, 'tStopRefresh')  # time at next scr refresh
-                tial_n_letter.setAutoDraw(False)
-        
-        # check for quit (typically the Esc key)
-        if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
-            core.quit()
-        
-        # check if all components have finished
-        if not continueRoutine:  # a component has requested a forced-end of Routine
-            break
-        continueRoutine = False  # will revert to True if at least one component still running
-        for thisComponent in trial_nComponents:
-            if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
-                continueRoutine = True
-                break  # at least one component has not yet finished
-        
-        # refresh the screen
-        if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
-            win.flip()
-    
-    # -------Ending Routine "trial_n"-------
-    for thisComponent in trial_nComponents:
-        if hasattr(thisComponent, "setAutoDraw"):
-            thisComponent.setAutoDraw(False)
-    thisExp.addData('tial_n_letter.stim', stimulus)
-    prevN = np.hstack((prevN,stimulus))
-    prevN = prevN[-3:]
-    loop_n.addData('trial_n_screen.started', trial_n_screen.tStartRefresh)
-    loop_n.addData('trial_n_screen.stopped', trial_n_screen.tStopRefresh)
-    loop_n.addData('tial_n_letter.started', tial_n_letter.tStartRefresh)
-    loop_n.addData('tial_n_letter.stopped', tial_n_letter.tStopRefresh)
-    thisExp.nextEntry()
-    
-# completed 20 repeats of 'loop_n'
-
-
-# Flip one final time so any remaining win.callOnFlip() 
-# and win.timeOnFlip() tasks get executed before quitting
-win.flip()
-
-# these shouldn't be strictly necessary (should auto-save)
-thisExp.saveAsWideText(filename+'.csv')
-thisExp.saveAsPickle(filename)
-logging.flush()
-# make sure everything is closed down
-thisExp.abort()  # or data files will save again on exit
-win.close()
-core.quit()
-- 
GitLab