I am an amateur in Python programming and cognitive neuroscience, currently working on developing a task-switching paradigm for an experimental study. I have written some initial code based on a specific research paper and would greatly appreciate it if someone could review it to determine whether it aligns with the original experimental design.
Thank you very much for your kind support and assistance.
from psychopy import visual, core, event, gui
import random
import csv
from pathlib import Path
import subprocess
import platform
=== 設定視覺角對應像素大小(70 cm viewing distance, 約 4.6 度 ≈ 180 px)===
visual_angle_px = 180
=== 取得參與者資訊 ===
exp_info = {‘participant’: ‘’, ‘session’: ‘1’}
dlg = gui.DlgFromDict(dictionary=exp_info, title=‘認知彈性測驗練習’)
if not dlg.OK:
core.quit()
=== 建立桌面資料夾與檔案路徑 ===
desktop_path = Path.home() / ‘Desktop’ / ‘data_practice’
desktop_path.mkdir(parents=True, exist_ok=True)
filename = desktop_path / f"{exp_info[‘participant’]}_session{exp_info[‘session’]}.csv"
=== 畫面與刺激設定 ===
win = visual.Window([1024, 768], color=‘black’, units=‘pix’, fullscr=True)
number_stim = visual.TextStim(win, text=‘’, height=visual_angle_px, color=‘white’)
fixation = visual.TextStim(win, text=‘+’, height=80, color=‘white’)
solid_box = visual.Rect(win, width=visual_angle_px, height=visual_angle_px, lineColor=‘white’, fillColor=None, lineWidth=6)
digits = [1, 2, 3, 4, 6, 7, 8, 9]
trial_data =
def create_dashed_rect(win, width=visual_angle_px, height=visual_angle_px, segments=16, color=‘white’, lineWidth=6):
half_w, half_h = width / 2, height / 2
edges = [
((-half_w, half_h), (half_w, half_h)),
((half_w, half_h), (half_w, -half_h)),
((half_w, -half_h), (-half_w, -half_h)),
((-half_w, -half_h), (-half_w, half_h))
]
lines =
for start, end in edges:
for i in range(segments):
if i % 2 == 0:
t0 = i / segments
t1 = (i + 1) / segments
xa = start[0] + (end[0] - start[0]) * t0
ya = start[1] + (end[1] - start[1]) * t0
xb = start[0] + (end[0] - start[0]) * t1
yb = start[1] + (end[1] - start[1]) * t1
lines.append(visual.Line(win, start=(xa, ya), end=(xb, yb), lineColor=color, lineWidth=lineWidth))
return lines
def get_task_condition(number, task_type):
if task_type == “A”:
return ‘greater’ if number > 5 else ‘less’
elif task_type == “B”:
return ‘even’ if number % 2 == 0 else ‘odd’
def run_trial(number, task_type, trial_num):
fixation.draw()
win.flip()
core.wait(random.uniform(0.3, 0.5))
correct_answer = get_task_condition(number, task_type)
correct_key = 'z' if correct_answer in ['less', 'odd'] else 'm'
number_stim.text = str(number)
if task_type == "A":
solid_box.draw()
else:
for line in create_dashed_rect(win):
line.draw()
number_stim.draw()
win.flip()
core.wait(0.2)
win.flip()
clock = core.Clock()
response_key = None
rt = None
is_correct = False
while clock.getTime() < 2.0:
keys = event.getKeys(timeStamped=clock)
for key, t in keys:
if key == 'escape':
win.close()
core.quit()
if response_key is None and key in ['z', 'm']:
response_key = key
is_correct = (response_key == correct_key)
rt = round(t, 4) if is_correct else ''
core.wait(0.01)
trial_data.append({
'trial': trial_num,
'number': number,
'task_type': task_type,
'correct_key': correct_key,
'response_key': response_key if response_key else '',
'rt': rt,
'correct': is_correct
})
def show_instructions():
instruction_text = (“”"
歡迎參加本次練習!
你將看到 1–9 之間的數字(不包含 5)。
若數字出現在【實線方框】,請判斷是否【大於或小於 5】:
按 Z = 小於 5(1–4)
按 M = 大於 5(6–9)
若數字出現在【虛線方框】,請判斷是否【奇數或偶數】:
按 Z = 奇數(1, 3, 7, 9)
按 M = 偶數(2, 4, 6, 8)
請儘可能快速且正確地作答。
按任意鍵開始,按 ESC 可中途退出。
“”")
instr = visual.TextStim(win, text=instruction_text, wrapWidth=900, color=‘white’, height=28)
instr.draw()
win.flip()
event.waitKeys()
def show_countdown():
countdown = visual.TextStim(win, text=‘’, height=80, color=‘white’)
for i in [3, 2, 1]:
countdown.text = str(i)
countdown.draw()
win.flip()
core.wait(1)
show_instructions()
show_countdown()
fixation.draw()
win.flip()
core.wait(random.uniform(0.3, 0.5))
task_seq = random.choices([‘A’, ‘B’], k=20)
for i, task_type in enumerate(task_seq, start=1):
number = random.choice(digits)
run_trial(number, task_type, trial_num=i)
correct_rts = [t[‘rt’] for t in trial_data if t[‘correct’] and isinstance(t[‘rt’], float)]
average_rt = round(sum(correct_rts) / len(correct_rts), 3) if correct_rts else ‘’
total_correct = sum(1 for t in trial_data if t[‘correct’])
accuracy = round((total_correct / len(trial_data)) * 100, 2)
fieldnames = [‘trial’, ‘number’, ‘task_type’, ‘correct_key’, ‘response_key’, ‘rt’, ‘correct’]
with open(filename, mode=‘w’, newline=‘’, encoding=‘utf-8’) as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(trial_data)
writer.writerow({})
writer.writerow({‘trial’: ‘RT’, ‘rt’: average_rt})
writer.writerow({‘trial’: ‘ACC(%)’, ‘correct’: accuracy})
thanks = visual.TextStim(win, text=‘This is the end of the task.’, color=‘white’, height=32)
thanks.draw()
win.flip()
event.waitKeys()
win.close()
try:
if platform.system() == “Windows”:
subprocess.Popen(f’explorer “{desktop_path}”')
elif platform.system() == “Darwin”:
subprocess.Popen([“open”, str(desktop_path)])
elif platform.system() == “Linux”:
subprocess.Popen([“xdg-open”, str(desktop_path)])
except Exception as e:
print(“ 無法開啟資料夾:”, e)
core.quit()
reference: Hung, C. L., Tseng, J. W., Chao, H. H., Hung, T. M., & Wang, H. S. (2018). Effect of acute exercise mode on serum brain-derived neurotrophic factor (BDNF) and task switching performance. Journal of clinical medicine , 7 (10), 301.
The task including pure and mixed task conditions in three subtests. In each task, a white numeric digit (digits 1–9, excluding 5) was presented in the center of a computer screen on a black background. Pure task conditions included two subtests. For the first subtest, designated as being of
the ‘A’ type, participants had to identify whether the number surrounded by a solid-line rectangle, was smaller (1, 2, 3, 4) or larger (6, 7, 8, 9) than 5 (i.e., all tasks were of the ‘A’ type). For the second subtest, designated as being of the ‘B’ type, the participants had to identify whether the number,
surrounded by a dashed square, was odd (1, 3, 7, 9) or even (2, 4, 6, 8) (i.e., all tasks were of the ‘B’ type). For the mixed-task condition, the two previous tasks were combined with an alternative run switching
paradigm (i.e., AABBAA . . . ) [32]. The participants were instructed to use their index fingers of each hand to, as quickly and accurately as possible, press either the ‘X’ key to indicate smaller or odd, and the ‘M’ key to indicate larger or even, in the ‘A’ or ‘B’ tasks respectively. The probability of a correct
response requiring action by the right or left hand was the same. Each of the 8 digits within each task appeared with equal probability, in random order. The digits were presented for 200 ms, with a 2000 ms response-stimulus interval. If no response was made, the trial was terminated 3000 ms after the onset of stimuli. Participants completed 64 trials in each of the pure task conditions and 128 trials (64 trials × 2 blocks) in the mixed-task condition. The first trial in each block for both pure task and mixed-task conditions was discarded from the analyses. The viewing distance was approximately 70 cm and visual angles were 4.6 ◦. Measures were taken of reaction time
(RT), and response accuracy in pure, mixed, non-switching and switching trials. Global switch cost was calculated as the difference in RT between the pure and mixed blocks (i.e., the averaged first and second blocks). Local switch cost was calculated as the difference in RT between the non-switch and switch trials in the mixed blocks.